Skip to content

Commit 9e880b2

Browse files
KacperFKorbanWojciechMazur
authored andcommitted
Check if a fatal warning issued in typer is silenced, before converting it into an error
closes lampepfl#17741 closes lampepfl#17735 [Cherry-picked ad45c3e]
1 parent 917072b commit 9e880b2

File tree

7 files changed

+123
-35
lines changed

7 files changed

+123
-35
lines changed

compiler/src/dotty/tools/dotc/reporting/Reporter.scala

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -149,14 +149,10 @@ abstract class Reporter extends interfaces.ReporterResult {
149149
val key = w.enablingOption.name
150150
addUnreported(key, 1)
151151
case _ =>
152-
// conditional warnings that are not enabled are not fatal
153-
val d = dia match
154-
case w: Warning if ctx.settings.XfatalWarnings.value => w.toError
155-
case _ => dia
156-
if !isHidden(d) then // avoid isHidden test for summarized warnings so that message is not forced
157-
markReported(d)
158-
withMode(Mode.Printing)(doReport(d))
159-
d match {
152+
if !isHidden(dia) then // avoid isHidden test for summarized warnings so that message is not forced
153+
markReported(dia)
154+
withMode(Mode.Printing)(doReport(dia))
155+
dia match {
160156
case _: Warning => _warningCount += 1
161157
case e: Error =>
162158
errors = e :: errors
@@ -169,13 +165,19 @@ abstract class Reporter extends interfaces.ReporterResult {
169165
end issueUnconfigured
170166

171167
def issueIfNotSuppressed(dia: Diagnostic)(using Context): Unit =
168+
def toErrorIfFatal(dia: Diagnostic) = dia match
169+
case w: Warning if ctx.settings.silentWarnings.value => dia
170+
case w: ConditionalWarning if w.isSummarizedConditional => dia
171+
case w: Warning if ctx.settings.XfatalWarnings.value => w.toError
172+
case _ => dia
173+
172174
def go() =
173175
import Action._
174176
dia match
175-
case w: Warning => WConf.parsed.action(w) match
177+
case w: Warning => WConf.parsed.action(dia) match
176178
case Error => issueUnconfigured(w.toError)
177-
case Warning => issueUnconfigured(w)
178-
case Verbose => issueUnconfigured(w.setVerbose())
179+
case Warning => issueUnconfigured(toErrorIfFatal(w))
180+
case Verbose => issueUnconfigured(toErrorIfFatal(w.setVerbose()))
179181
case Info => issueUnconfigured(w.toInfo)
180182
case Silent =>
181183
case _ => issueUnconfigured(dia)

tests/neg/refutable-pattern-binding-messages.check

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
-- Error: tests/neg/refutable-pattern-binding-messages.scala:5:14 ------------------------------------------------------
2+
5 | val Positive(p) = 5 // error: refutable extractor
3+
| ^^^^^^^^^^^^^^^
4+
| pattern binding uses refutable extractor `Test.Positive`
5+
|
6+
| If this usage is intentional, this can be communicated by adding `: @unchecked` after the expression,
7+
| which may result in a MatchError at runtime.
8+
| This patch can be rewritten automatically under -rewrite -source 3.2-migration.
19
-- Error: tests/neg/refutable-pattern-binding-messages.scala:6:14 ------------------------------------------------------
210
6 | for Positive(i) <- List(1, 2, 3) do () // error: refutable extractor
311
| ^^^^^^^^^^^
@@ -6,6 +14,14 @@
614
| If this usage is intentional, this can be communicated by adding the `case` keyword before the full pattern,
715
| which will result in a filtering for expression (using `withFilter`).
816
| This patch can be rewritten automatically under -rewrite -source 3.2-migration.
17+
-- Error: tests/neg/refutable-pattern-binding-messages.scala:10:20 -----------------------------------------------------
18+
10 | val i :: is = List(1, 2, 3) // error: pattern type more specialized
19+
| ^^^^^^^^^^^^^
20+
| pattern's type ::[Int] is more specialized than the right hand side expression's type List[Int]
21+
|
22+
| If the narrowing is intentional, this can be communicated by adding `: @unchecked` after the expression,
23+
| which may result in a MatchError at runtime.
24+
| This patch can be rewritten automatically under -rewrite -source 3.2-migration.
925
-- Error: tests/neg/refutable-pattern-binding-messages.scala:11:11 -----------------------------------------------------
1026
11 | for ((x: String) <- xs) do () // error: pattern type more specialized
1127
| ^^^^^^
@@ -22,22 +38,6 @@
2238
| If the narrowing is intentional, this can be communicated by adding the `case` keyword before the full pattern,
2339
| which will result in a filtering for expression (using `withFilter`).
2440
| This patch can be rewritten automatically under -rewrite -source 3.2-migration.
25-
-- Error: tests/neg/refutable-pattern-binding-messages.scala:5:14 ------------------------------------------------------
26-
5 | val Positive(p) = 5 // error: refutable extractor
27-
| ^^^^^^^^^^^^^^^
28-
| pattern binding uses refutable extractor `Test.Positive`
29-
|
30-
| If this usage is intentional, this can be communicated by adding `: @unchecked` after the expression,
31-
| which may result in a MatchError at runtime.
32-
| This patch can be rewritten automatically under -rewrite -source 3.2-migration.
33-
-- Error: tests/neg/refutable-pattern-binding-messages.scala:10:20 -----------------------------------------------------
34-
10 | val i :: is = List(1, 2, 3) // error: pattern type more specialized
35-
| ^^^^^^^^^^^^^
36-
| pattern's type ::[Int] is more specialized than the right hand side expression's type List[Int]
37-
|
38-
| If the narrowing is intentional, this can be communicated by adding `: @unchecked` after the expression,
39-
| which may result in a MatchError at runtime.
40-
| This patch can be rewritten automatically under -rewrite -source 3.2-migration.
4141
-- Error: tests/neg/refutable-pattern-binding-messages.scala:16:10 -----------------------------------------------------
4242
16 | val 1 = 2 // error: pattern type does not match
4343
| ^

tests/neg/warn-value-discard.check

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
-- [E175] Potential Issue Error: tests/neg/warn-value-discard.scala:15:35 ----------------------------------------------
2-
15 | firstThing().map(_ => secondThing()) // error
3-
| ^^^^^^^^^^^^^
4-
| discarded non-Unit value of type Either[Failed, Unit]
5-
-- [E175] Potential Issue Error: tests/neg/warn-value-discard.scala:18:35 ----------------------------------------------
6-
18 | firstThing().map(_ => secondThing()) // error
7-
| ^^^^^^^^^^^^^
8-
| discarded non-Unit value of type Either[Failed, Unit]
91
-- [E175] Potential Issue Error: tests/neg/warn-value-discard.scala:27:36 ----------------------------------------------
102
27 | mutable.Set.empty[String].remove("") // error
113
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -18,3 +10,11 @@
1810
59 | mutable.Set.empty[String] += "" // error
1911
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2012
| discarded non-Unit value of type scala.collection.mutable.Set[String]
13+
-- [E175] Potential Issue Error: tests/neg/warn-value-discard.scala:15:35 ----------------------------------------------
14+
15 | firstThing().map(_ => secondThing()) // error
15+
| ^^^^^^^^^^^^^
16+
| discarded non-Unit value of type Either[Failed, Unit]
17+
-- [E175] Potential Issue Error: tests/neg/warn-value-discard.scala:18:35 ----------------------------------------------
18+
18 | firstThing().map(_ => secondThing()) // error
19+
| ^^^^^^^^^^^^^
20+
| discarded non-Unit value of type Either[Failed, Unit]
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// scalac: -Wvalue-discard
2+
3+
import scala.collection.mutable
4+
import scala.annotation.nowarn
5+
6+
object Foo:
7+
8+
def f(b: Boolean): String =
9+
val messageBuilder = mutable.StringBuilder()
10+
if b then
11+
// Here @nowarn is effective with or without -Wfatal-warnings
12+
// i.e. no warning without -Wfatal-warnings and no error with -Wfatal-warnings
13+
messageBuilder.append("helloworld").append("\n"): @nowarn("msg=discarded non-Unit value*")
14+
15+
messageBuilder.result()
16+
17+
def g(x: String => Unit) = ???
18+
def h: String =
19+
val messageBuilder = mutable.StringBuilder()
20+
g: s =>
21+
// here @nowarn is effective without -Wfatal-warnings (i.e. no warning)
22+
// But with -Wfatal-warnings we get an error
23+
messageBuilder.append("\n").append(s): @nowarn("msg=discarded non-Unit value*")
24+
messageBuilder.result()
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// scalac: -Wvalue-discard -Wconf:msg=non-Unit:s
2+
3+
import scala.collection.mutable
4+
import scala.annotation.nowarn
5+
6+
object Test:
7+
8+
def f(b: Boolean): String =
9+
val messageBuilder = mutable.StringBuilder()
10+
if b then
11+
// Here @nowarn is effective with or without -Wfatal-warnings
12+
// i.e. no warning without -Wfatal-warnings and no error with -Wfatal-warnings
13+
messageBuilder.append("helloworld").append("\n")
14+
15+
messageBuilder.result()
16+
17+
def g(x: String => Unit) = ???
18+
def h: String =
19+
val messageBuilder = mutable.StringBuilder()
20+
g: s =>
21+
// here @nowarn is effective without -Wfatal-warnings (i.e. no warning)
22+
// But with -Wfatal-warnings we get an error
23+
messageBuilder.append("\n").append(s)
24+
messageBuilder.result()
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// scalac: -Wnonunit-statement
2+
3+
class Node()
4+
class Elem(
5+
prefix: String,
6+
label: String,
7+
minimizeEmpty: Boolean,
8+
child: Node*
9+
) extends Node
10+
class Text(text: String) extends Node
11+
class NodeBuffer() {
12+
def &+(node: Node): NodeBuffer =
13+
this
14+
}
15+
class NodeSeq()
16+
object NodeSeq {
17+
def seqToNodeSeq(seq: NodeBuffer): Seq[Node] = ???
18+
}
19+
20+
object Main {
21+
def example() = {
22+
{
23+
new Elem(null, "foo", false,
24+
{
25+
val $buf: NodeBuffer = new NodeBuffer()
26+
$buf.&+(new Text("bar"))
27+
NodeSeq.seqToNodeSeq($buf)
28+
}*
29+
)
30+
}
31+
}: @annotation.nowarn()
32+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
case class F(i: Int)
2+
3+
object Main {
4+
def example() =
5+
List(1, 2, 3).map(F): @annotation.nowarn
6+
}

0 commit comments

Comments
 (0)