Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions compiler/src/dotty/tools/dotc/reporting/Reporter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,14 @@ abstract class Reporter extends interfaces.ReporterResult {
unreportedWarnings = unreportedWarnings.updated(key, count + n)

/** Issue the diagnostic, ignoring `-Wconf` and `@nowarn` configurations,
* but still honouring `-nowarn`, `-Werror`, and conditional warnings. */
def issueUnconfigured(dia: Diagnostic)(using Context): Unit = dia match
* but still honouring `-nowarn`, `-Werror`, and conditional warnings.
*
* Avoid forcing elaboration of the message, but if already `forced`,
* then do issue the diagnostic with usual `isHidden` check.
*/
def issueUnconfigured(dia: Diagnostic, forced: Boolean = false)(using Context): Unit = dia match
case w: Warning if ctx.settings.silentWarnings.value =>
case w: ConditionalWarning if w.isSummarizedConditional =>
case w: ConditionalWarning if !forced && w.isSummarizedConditional =>
val key = w.enablingOption.name
addUnreported(key, 1)
case _ =>
Expand Down Expand Up @@ -204,10 +208,11 @@ abstract class Reporter extends interfaces.ReporterResult {
dia match
case w: Warning => WConf.parsed.action(dia) match
case Error => issueUnconfigured(w.toError)
case Warning => issueUnconfigured(toErrorIfFatal(w))
case Warning => issueUnconfigured(toErrorIfFatal(w), forced = true)
case Verbose => issueUnconfigured(toErrorIfFatal(w.setVerbose()))
case Info => issueUnconfigured(w.toInfo)
case Silent =>
case Default => issueUnconfigured(w)
case _ => issueUnconfigured(dia)

// `ctx.run` can be null in test, also in the repl when parsing the first line. The parser runs early, the Run is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@ class StoreReporter(outer: Reporter | Null = Reporter.NoReporter, fromTyperState
// so that then only when the messages are unbuffered (when the reporter if flushed)
// do they go through -Wconf, and possibly then buffered on the Run as a suspended message
override def report(dia: Diagnostic)(using Context): Unit =
if fromTyperState then issueUnconfigured(dia)
if fromTyperState then issueUnconfigured(dia, forced = false)
else super.report(dia)
}
9 changes: 5 additions & 4 deletions compiler/src/dotty/tools/dotc/reporting/WConf.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,13 @@ enum MessageFilter:
case Origin(pattern: Regex)

enum Action:
case Error, Warning, Verbose, Info, Silent
case Error, Warning, Verbose, Info, Silent, Default

final case class WConf(confs: List[(List[MessageFilter], Action)]):
def action(message: Diagnostic): Action = confs.collectFirst {
case (filters, action) if filters.forall(_.matches(message)) => action
}.getOrElse(Action.Warning)
def action(message: Diagnostic): Action =
confs.collectFirst:
case (filters, action) if filters.forall(_.matches(message)) => action
.getOrElse(Action.Default)

object WConf:
import Action.*
Expand Down
10 changes: 4 additions & 6 deletions compiler/src/dotty/tools/dotc/transform/Recheck.scala
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,6 @@ abstract class Recheck extends Phase, SymTransformer:
def toAvoid(tp: NamedType) =
tp.symbol.is(Case) && tp.symbol.owner.isContainedIn(ctx.owner)

val rawType = recheck(tree.expr)
val ownType = avoidMap(rawType)

// The pattern matching translation, which runs before this phase
// sometimes instantiates return types with singleton type alternatives
// but the returned expression is widened. We compensate by widening the expected
Expand All @@ -366,7 +363,10 @@ abstract class Recheck extends Phase, SymTransformer:
case tp: AndOrType => tp.derivedAndOrType(widened(tp.tp1), widened(tp.tp2))
case tp @ AnnotatedType(tp1, ann) => tp.derivedAnnotatedType(widened(tp1), ann)
case _ => tp
checkConforms(ownType, widened(tree.from.symbol.returnProto), tree)
val expected = widened(tree.from.symbol.returnProto)
val rawType = recheck(tree.expr, expected)
val ownType = avoidMap(rawType)
checkConforms(ownType, expected, tree)
defn.NothingType
end recheckReturn

Expand Down Expand Up @@ -575,5 +575,3 @@ class TestRecheck extends Recheck:
def phaseName: String = "recheck"
override def isEnabled(using Context) = ctx.settings.YrecheckTest.value
def newRechecker()(using Context): Rechecker = Rechecker(ctx)


Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class ScalaSettingsTests:
val feat = new Diagnostic.FeatureWarning(msg, util.NoSourcePosition)
assertEquals(Action.Error, sut.action(feat))
val warn = new Diagnostic.Warning(msg, util.NoSourcePosition)
assertEquals(Action.Warning, sut.action(warn))
assertEquals(Action.Default, sut.action(warn))
val nowr = new Diagnostic.Warning("This is a problem.".toMessage, util.NoSourcePosition)
assertEquals(Action.Silent, sut.action(nowr))

Expand Down Expand Up @@ -136,7 +136,7 @@ class ScalaSettingsTests:
)
)
)
assertEquals(result, Right(reporting.Action.Warning))
assertEquals(Right(reporting.Action.Default), result)

@Test def `WConf src filter silences warnings from a matching path for real file`: Unit =
val result = Using.resource(Files.createTempFile("myfile", ".scala").nn) { file =>
Expand Down Expand Up @@ -165,8 +165,8 @@ class ScalaSettingsTests:
)
)
)
}(Files.deleteIfExists(_))
assertEquals(result, Right(reporting.Action.Warning))
}(using Files.deleteIfExists(_))
assertEquals(Right(reporting.Action.Default), result)

@Test def `WConf src filter reports an error on an invalid regex`: Unit =
val result = wconfSrcFilterTest(
Expand Down
11 changes: 11 additions & 0 deletions tests/neg-custom-args/captures/i25320a.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i25320a.scala:6:9 ----------------------------------------
6 | case Box(y) => y // error
| ^^^^^^^^^^^
| Found: A^{y, any}
| Required: A
|
| Note that capability `y` cannot flow into capture set {}.
|
| where: any is a root capability in the type of value x7
|
| longer explanation available when compiling with `-explain`
6 changes: 6 additions & 0 deletions tests/neg-custom-args/captures/i25320a.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import language.experimental.captureChecking
sealed trait AbstractBox[A]
case class Box[A](x: A) extends AbstractBox[A]
def leak[A](x: Box[A^]): A =
x match
case Box(y) => y // error
9 changes: 9 additions & 0 deletions tests/neg-custom-args/captures/i25320b.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i25320b.scala:6:16 ---------------------------------------
6 | case Box(y) => Box(y) // error
| ^^^^^^^^^
| Found: Box[Foo]^'s1
| Required: Box[Foo^{y}]^'s2
|
| Note that capability `y` cannot flow into capture set {}.
|
| longer explanation available when compiling with `-explain`
8 changes: 8 additions & 0 deletions tests/neg-custom-args/captures/i25320b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import language.experimental.captureChecking
case class Foo()
case class Box[A](x: A)
def fooLeak(x: Box[Foo^]): Box[Foo] = {
x match {
case Box(y) => Box(y) // error
}
}
9 changes: 9 additions & 0 deletions tests/neg-custom-args/captures/match-return-avoid.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/match-return-avoid.scala:8:11 ----------------------------
8 | case y => Box(y) // error
| ^^^^^^^^^
| Found: Box[Foo]^'s1
| Required: Box[Foo^{y}]^'s2
|
| Note that capability `y` cannot flow into capture set {}.
|
| longer explanation available when compiling with `-explain`
8 changes: 8 additions & 0 deletions tests/neg-custom-args/captures/match-return-avoid.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import language.experimental.captureChecking

case class Foo()
case class Box[A](x: A)

def f(x: Foo^): Box[Foo^{}] =
x match
case y => Box(y) // error
6 changes: 6 additions & 0 deletions tests/neg/i25548.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//> using options -Wconf:any:error,cat=deprecation:warning -Werror

class Location @deprecated("", "") (value: String)
object Location {
def apply(value: String): Location = new Location(value) // nopos-error
}
4 changes: 4 additions & 0 deletions tests/warn/i25548.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- Deprecation Warning: tests/warn/i25548.scala:5:43 -------------------------------------------------------------------
5 | def apply(value: String): Location = new Location(value) // warn
| ^^^^^^^^
| constructor Location in class Location is deprecated
6 changes: 6 additions & 0 deletions tests/warn/i25548.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//> using options -Wconf:cat=deprecation:warning

class Location @deprecated("", "") (value: String)
object Location {
def apply(value: String): Location = new Location(value) // warn
}
11 changes: 11 additions & 0 deletions tests/warn/i25548b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//> using options -Wconf:cat=deprecation&msg=bruh:warning

class Location @deprecated("No loke", since="1.0") (value: String)
object Location {
def apply(value: String): Location = new Location(value) // nopos-warn summarized 1 deprecation warning
}

class Brocation @deprecated("bruh!", since="1.0") (value: String)
object Brocation {
def apply(value: String): Brocation = new Brocation(value) // warn reported deprecated since 1.0: bruh!
}
Loading