Skip to content

Commit 6a27388

Browse files
committed
Avoid double-feature reporting
The extended explanation attached to the first feature warning would fool the reporter if the feature is reported again at the same position. Use a conventional leading `"----"` to demarcate the explanation, and use only the prefix to see if the error has already been issued at a position.
1 parent 043c5ad commit 6a27388

File tree

6 files changed

+52
-3
lines changed

6 files changed

+52
-3
lines changed

src/compiler/scala/tools/nsc/Reporting.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ trait Reporting extends scala.reflect.internal.Reporting { self: ast.Positions w
9797
val explain = (
9898
if (reportedFeature contains featureTrait) "" else
9999
s"""|
100+
|----
100101
|This can be achieved by adding the import clause 'import $fqname'
101102
|or by setting the compiler option -language:$featureName.
102103
|See the Scaladoc for value $fqname for a discussion

src/compiler/scala/tools/nsc/reporters/DisplayReporter.scala

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ trait PrintReporter extends InternalReporter {
4646

4747
/** Format a message and emit it. */
4848
def display(pos: Position, msg: String, severity: Severity): Unit = {
49-
val text = formatMessage(pos, s"${clabel(severity)}${msg}", shortname)
49+
val text = formatMessage(pos, s"${clabel(severity)}${DisplayReporter.explanation(msg)}", shortname)
5050
severity match {
5151
case INFO => echoMessage(text)
5252
case _ => printMessage(text)
@@ -97,6 +97,21 @@ object DisplayReporter {
9797
writer: PrintWriter = new PrintWriter(Console.err, true),
9898
echoWriter: PrintWriter = new PrintWriter(Console.out, true)
9999
) = new DisplayReporter(settings, reader, writer, echoWriter)
100+
101+
/** Take the message with its explanation, if it has one. */
102+
def explanation(msg: String): String = splitting(msg, explaining = true)
103+
104+
/** Take the message without its explanation, if it has one. */
105+
def stripExplanation(msg: String): String = splitting(msg, explaining = false)
106+
107+
/** Split a message into a prefix and an optional explanation that follows a line starting with `"----"`. */
108+
private def splitting(msg: String, explaining: Boolean): String =
109+
if (msg.indexOf("\n----") > 0) {
110+
val (err, exp) = msg.lines.span(!_.startsWith("----"))
111+
if (explaining) (err ++ exp.drop(1)).mkString("\n") else err.mkString("\n")
112+
} else {
113+
msg
114+
}
100115
}
101116

102117
/** A reporter that filters by position and forwards for display */

src/compiler/scala/tools/nsc/reporters/PositionFilter.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,18 @@ trait PositionFiltering extends InternalReporter with Filtering {
4646
case ERROR => true // already error at position
4747
case highest
4848
if highest.id > severity.id => true // already message higher than present severity
49-
case `severity` => messages(fpos) contains msg // already issued this exact message
49+
case `severity` => matchAt(fpos, msg) // already issued this (in)exact message
5050
case _ => false // good to go
5151
}
5252

5353
suppress || {
5454
positions(fpos) = severity
55-
messages(fpos) ::= msg
55+
messages(fpos) ::= DisplayReporter.stripExplanation(msg) // ignore explanatory suffix for suppressing duplicates
5656
false
5757
}
5858
}
59+
// was a prefix of the msg already reported at this position for purposes of suppressing repetition?
60+
private def matchAt(pos: Position, msg: String): Boolean = messages(pos).exists(msg.startsWith(_))
5961
}
6062

6163
/** This reporter implements filtering by severity and position.

test/files/neg/double-feature.check

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
double-feature.scala:4: warning: implicit conversion method f should be enabled
2+
by making the implicit value scala.language.implicitConversions visible.
3+
This can be achieved by adding the import clause 'import scala.language.implicitConversions'
4+
or by setting the compiler option -language:implicitConversions.
5+
See the Scaladoc for value scala.language.implicitConversions for a discussion
6+
why the feature should be explicitly enabled.
7+
implicit def f(t: T): String = "I am the tee"
8+
^
9+
double-feature.scala:6: warning: postfix operator + should be enabled
10+
by making the implicit value scala.language.postfixOps visible.
11+
This can be achieved by adding the import clause 'import scala.language.postfixOps'
12+
or by setting the compiler option -language:postfixOps.
13+
See the Scaladoc for value scala.language.postfixOps for a discussion
14+
why the feature should be explicitly enabled.
15+
val g: Int => Int = 1 +
16+
^
17+
error: No warnings can be incurred under -Xfatal-warnings.
18+
two warnings found
19+
one error found

test/files/neg/double-feature.flags

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-feature -Xfatal-warnings

test/files/neg/double-feature.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
object Test {
3+
trait T
4+
implicit def f(t: T): String = "I am the tee"
5+
//val n = "hello, world" length
6+
val g: Int => Int = 1 +
7+
def main(args: Array[String]): Unit = println {(
8+
null.asInstanceOf[T] : String,
9+
List(1).map(g),
10+
)}
11+
}

0 commit comments

Comments
 (0)