Skip to content

Commit d24684b

Browse files
committed
Improve -explain rendering
1 parent e523c8d commit d24684b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+459
-320
lines changed

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ object ConsoleReporter {
3232
/** Prints the message with the given position indication. */
3333
def doReport(dia: Diagnostic)(using Context): Unit = {
3434
printMessage(messageAndPos(dia))
35-
if Diagnostic.shouldExplain(dia) then
36-
printMessage(explanation(dia.msg))
37-
else if dia.msg.canExplain then
38-
printMessage("\nlonger explanation available when compiling with `-explain`")
3935
}
4036
}
4137
}

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,20 @@ trait MessageRendering {
248248
else sb.append(msg.message)
249249
if (dia.isVerbose)
250250
appendFilterHelp(dia, sb)
251+
252+
if Diagnostic.shouldExplain(dia) then
253+
sb.append(EOL).append(newBox())
254+
sb.append(EOL).append(offsetBox).append(" Explanation")
255+
sb.append(EOL).append(newBox(soft = true))
256+
dia.msg.explanation.split(EOL).foreach { line =>
257+
sb.append(EOL).append(offsetBox).append(if line.isEmpty then "" else " ").append(line)
258+
}
259+
sb.append(EOL).append(endBox)
260+
else if dia.msg.canExplain then
261+
sb.append(EOL).append(newBox())
262+
sb.append(EOL).append(offsetBox).append(" longer explanation available when compiling with `-explain`")
263+
sb.append(EOL).append(endBox)
264+
251265
sb.toString
252266
}
253267

compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,18 +142,17 @@ object ErrorReporting {
142142
|conforms to
143143
| $expected
144144
|but the comparison trace ended with `false`:
145-
"""
145+
|"""
146146
val c = ctx.typerState.constraint
147147
val constraintText =
148148
if c.domainLambdas.isEmpty then
149149
"the empty constraint"
150150
else
151151
i"""a constraint with:
152152
|$c"""
153-
i"""
154-
|${TypeComparer.explained(_.isSubType(found, expected), header)}
155-
|
156-
|The tests were made under $constraintText"""
153+
i"""${TypeComparer.explained(_.isSubType(found, expected), header)}
154+
|
155+
|The tests were made under $constraintText"""
157156

158157
/** Format `raw` implicitNotFound or implicitAmbiguous argument, replacing
159158
* all occurrences of `${X}` where `X` is in `paramNames` with the

tests/neg-custom-args/explicit-nulls/byname-nullables.check

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
| ^
44
| Found: (x : String | Null)
55
| Required: String
6-
7-
longer explanation available when compiling with `-explain`
6+
|--------------------------------------------------------------------------------------------------------------------
7+
| longer explanation available when compiling with `-explain`
8+
·--------------------------------------------------------------------------------------------------------------------
89
-- Error: tests/neg-custom-args/explicit-nulls/byname-nullables.scala:43:32 --------------------------------------------
910
43 | if x != null then f(identity(x), 1) // error: dropping not null check fails typing
1011
| ^^^^^^^^^^^

tests/neg-custom-args/explicit-nulls/i7883.check

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010
6 | case r(hd, tl) => Some((hd, tl)) // error // error // error
1111
| ^^
1212
| Not found: hd
13-
14-
longer explanation available when compiling with `-explain`
13+
|---------------------------------------------------------------------------------------------------------------------
14+
| longer explanation available when compiling with `-explain`
15+
·---------------------------------------------------------------------------------------------------------------------
1516
-- [E006] Not Found Error: tests/neg-custom-args/explicit-nulls/i7883.scala:6:34 ---------------------------------------
1617
6 | case r(hd, tl) => Some((hd, tl)) // error // error // error
1718
| ^^
1819
| Not found: tl
19-
20-
longer explanation available when compiling with `-explain`
20+
|---------------------------------------------------------------------------------------------------------------------
21+
| longer explanation available when compiling with `-explain`
22+
·---------------------------------------------------------------------------------------------------------------------

tests/neg-custom-args/i11637.check

Lines changed: 48 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,56 +2,55 @@
22
11 | var h = new HKT3_1[FunctorImpl](); // error // error
33
| ^
44
| Type argument test2.FunctorImpl does not conform to upper bound [Generic2[T <: String] <: Set[T]] =>> Any
5-
6-
Explanation
7-
===========
8-
9-
I tried to show that
10-
test2.FunctorImpl
11-
conforms to
12-
[Generic2[T <: String] <: Set[T]] =>> Any
13-
but the comparison trace ended with `false`:
14-
15-
==> test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any
16-
==> type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]]
17-
==> [T <: String] =>> Set[T] <: Iterable
18-
==> type bounds [] <: type bounds [ <: String]
19-
==> Any <: String
20-
==> Any <: String
21-
<== Any <: String = false
22-
<== Any <: String = false
23-
<== type bounds [] <: type bounds [ <: String] = false
24-
<== [T <: String] =>> Set[T] <: Iterable = false
25-
<== type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] = false
26-
<== test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any = false
27-
28-
The tests were made under the empty constraint
29-
5+
|--------------------------------------------------------------------------------------------------------------------
6+
| Explanation
7+
|····················································································································
8+
| I tried to show that
9+
| test2.FunctorImpl
10+
| conforms to
11+
| [Generic2[T <: String] <: Set[T]] =>> Any
12+
| but the comparison trace ended with `false`:
13+
|
14+
| ==> test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any
15+
| ==> type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]]
16+
| ==> [T <: String] =>> Set[T] <: Iterable
17+
| ==> type bounds [] <: type bounds [ <: String]
18+
| ==> Any <: String
19+
| ==> Any <: String
20+
| <== Any <: String = false
21+
| <== Any <: String = false
22+
| <== type bounds [] <: type bounds [ <: String] = false
23+
| <== [T <: String] =>> Set[T] <: Iterable = false
24+
| <== type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] = false
25+
| <== test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any = false
26+
|
27+
| The tests were made under the empty constraint
28+
·--------------------------------------------------------------------------------------------------------------------
3029
-- [E057] Type Mismatch Error: tests/neg-custom-args/i11637.scala:11:21 ------------------------------------------------
3130
11 | var h = new HKT3_1[FunctorImpl](); // error // error
3231
| ^
3332
| Type argument test2.FunctorImpl does not conform to upper bound [Generic2[T <: String] <: Set[T]] =>> Any
34-
35-
Explanation
36-
===========
37-
38-
I tried to show that
39-
test2.FunctorImpl
40-
conforms to
41-
[Generic2[T <: String] <: Set[T]] =>> Any
42-
but the comparison trace ended with `false`:
43-
44-
==> test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any
45-
==> type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]]
46-
==> [T <: String] =>> Set[T] <: Iterable
47-
==> type bounds [] <: type bounds [ <: String]
48-
==> Any <: String
49-
==> Any <: String
50-
<== Any <: String = false
51-
<== Any <: String = false
52-
<== type bounds [] <: type bounds [ <: String] = false
53-
<== [T <: String] =>> Set[T] <: Iterable = false
54-
<== type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] = false
55-
<== test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any = false
56-
57-
The tests were made under the empty constraint
33+
|--------------------------------------------------------------------------------------------------------------------
34+
| Explanation
35+
|····················································································································
36+
| I tried to show that
37+
| test2.FunctorImpl
38+
| conforms to
39+
| [Generic2[T <: String] <: Set[T]] =>> Any
40+
| but the comparison trace ended with `false`:
41+
|
42+
| ==> test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any
43+
| ==> type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]]
44+
| ==> [T <: String] =>> Set[T] <: Iterable
45+
| ==> type bounds [] <: type bounds [ <: String]
46+
| ==> Any <: String
47+
| ==> Any <: String
48+
| <== Any <: String = false
49+
| <== Any <: String = false
50+
| <== type bounds [] <: type bounds [ <: String] = false
51+
| <== [T <: String] =>> Set[T] <: Iterable = false
52+
| <== type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] = false
53+
| <== test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any = false
54+
|
55+
| The tests were made under the empty constraint
56+
·--------------------------------------------------------------------------------------------------------------------

tests/neg-custom-args/i13026.check

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@
33
| ^^^^^^^^^^^^
44
| Found: ("not an int" : String)
55
| Required: Int
6-
7-
longer explanation available when compiling with `-explain`
6+
|---------------------------------------------------------------------------------------------------------------------
7+
| longer explanation available when compiling with `-explain`
8+
·---------------------------------------------------------------------------------------------------------------------
89
-- [E007] Type Mismatch Error: tests/neg-custom-args/i13026.scala:2:13 -------------------------------------------------
910
2 |val y: Int = "not an int" // error
1011
| ^^^^^^^^^^^^
1112
| Found: ("not an int" : String)
1213
| Required: Int
13-
14-
longer explanation available when compiling with `-explain`
14+
|---------------------------------------------------------------------------------------------------------------------
15+
| longer explanation available when compiling with `-explain`
16+
·---------------------------------------------------------------------------------------------------------------------
1517
-- [E008] Not Found Error: tests/neg-custom-args/i13026.scala:3:20 -----------------------------------------------------
1618
3 |def foo(x: Any) = x.foo // error
1719
| ^^^^^

tests/neg-custom-args/i13838.check

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@
2222
| You can change the behavior by setting the `-Ximplicit-search-limit` value.
2323
| Smaller values cause the search to fail faster.
2424
| Larger values might make a very large search problem succeed.
25-
26-
longer explanation available when compiling with `-explain`
25+
|--------------------------------------------------------------------------------------------------------------------
26+
| longer explanation available when compiling with `-explain`
27+
·--------------------------------------------------------------------------------------------------------------------

tests/neg-custom-args/jdk-9-app.check

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
4 | println(ProcessHandle.current().pid()) // error: not found
33
| ^^^^^^^^^^^^^
44
| Not found: ProcessHandle
5-
6-
longer explanation available when compiling with `-explain`
5+
|---------------------------------------------------------------------------------------------------------------------
6+
| longer explanation available when compiling with `-explain`
7+
·---------------------------------------------------------------------------------------------------------------------

tests/neg-custom-args/kind-projector-underscores.check

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@
66
10 | type -_ = Int // error -_ not allowed as a type def name without backticks
77
| ^
88
| =, >:, or <: expected, but '_' found
9-
10-
longer explanation available when compiling with `-explain`
9+
|--------------------------------------------------------------------------------------------------------------------
10+
| longer explanation available when compiling with `-explain`
11+
·--------------------------------------------------------------------------------------------------------------------
1112
-- [E095] Syntax Error: tests/neg-custom-args/kind-projector-underscores.scala:11:8 ------------------------------------
1213
11 | type +_ = Int // error +_ not allowed as a type def name without backticks
1314
| ^
1415
| =, >:, or <: expected, but '_' found
15-
16-
longer explanation available when compiling with `-explain`
16+
|--------------------------------------------------------------------------------------------------------------------
17+
| longer explanation available when compiling with `-explain`
18+
·--------------------------------------------------------------------------------------------------------------------
1719
-- Error: tests/neg-custom-args/kind-projector-underscores.scala:14:51 -------------------------------------------------
1820
14 |class BacktickUnderscoreIsNotFine extends Foo[List[`_`]] // error wildcard invalid as backquoted identifier
1921
| ^

tests/neg-custom-args/nowarn/nowarn-parser-error.check

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
3 | def def // error
33
| ^^^
44
| an identifier expected, but 'def' found
5-
6-
longer explanation available when compiling with `-explain`
5+
|---------------------------------------------------------------------------------------------------------------------
6+
| longer explanation available when compiling with `-explain`
7+
·---------------------------------------------------------------------------------------------------------------------
78
-- [E000] Syntax Warning: tests/neg-custom-args/nowarn/nowarn-parser-error.scala:2:10 ----------------------------------
89
2 | def a = try 1 // warn
910
| ^^^^^
1011
| A try without catch or finally is equivalent to putting
1112
| its body in a block; no exceptions are handled.
12-
13-
longer explanation available when compiling with `-explain`
13+
|---------------------------------------------------------------------------------------------------------------------
14+
| longer explanation available when compiling with `-explain`
15+
·---------------------------------------------------------------------------------------------------------------------

tests/neg-custom-args/nowarn/nowarn-typer-error.check

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
4 | def t1 = / // error
33
| ^
44
| Not found: /
5-
6-
longer explanation available when compiling with `-explain`
5+
|---------------------------------------------------------------------------------------------------------------------
6+
| longer explanation available when compiling with `-explain`
7+
·---------------------------------------------------------------------------------------------------------------------

tests/neg-custom-args/nowarn/nowarn.check

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,25 @@
33
| ^^^^^
44
| A try without catch or finally is equivalent to putting
55
| its body in a block; no exceptions are handled.
6-
7-
longer explanation available when compiling with `-explain`
6+
|---------------------------------------------------------------------------------------------------------------------
7+
| longer explanation available when compiling with `-explain`
8+
·---------------------------------------------------------------------------------------------------------------------
89
-- [E000] Syntax Warning: tests/neg-custom-args/nowarn/nowarn.scala:23:25 ----------------------------------------------
910
23 |@nowarn(o.inl) def t2d = try 1 // two warnings (`inl` is not a compile-time constant)
1011
| ^^^^^
1112
| A try without catch or finally is equivalent to putting
1213
| its body in a block; no exceptions are handled.
13-
14-
longer explanation available when compiling with `-explain`
14+
|--------------------------------------------------------------------------------------------------------------------
15+
| longer explanation available when compiling with `-explain`
16+
·--------------------------------------------------------------------------------------------------------------------
1517
-- [E000] Syntax Warning: tests/neg-custom-args/nowarn/nowarn.scala:31:26 ----------------------------------------------
1618
31 |@nowarn("id=1") def t4d = try 1 // error and warning (unused nowarn, wrong id)
1719
| ^^^^^
1820
| A try without catch or finally is equivalent to putting
1921
| its body in a block; no exceptions are handled.
20-
21-
longer explanation available when compiling with `-explain`
22+
|--------------------------------------------------------------------------------------------------------------------
23+
| longer explanation available when compiling with `-explain`
24+
·--------------------------------------------------------------------------------------------------------------------
2225
-- [E000] Syntax Warning: tests/neg-custom-args/nowarn/nowarn.scala:33:28 ----------------------------------------------
2326
33 |@nowarn("verbose") def t5 = try 1 // warning with details
2427
| ^^^^^
@@ -27,14 +30,16 @@ longer explanation available when compiling with `-explain`
2730
Matching filters for @nowarn or -Wconf:
2831
- id=E0
2932
- name=EmptyCatchOrFinallyBlock
30-
31-
longer explanation available when compiling with `-explain`
33+
|--------------------------------------------------------------------------------------------------------------------
34+
| longer explanation available when compiling with `-explain`
35+
·--------------------------------------------------------------------------------------------------------------------
3236
-- [E129] Potential Issue Warning: tests/neg-custom-args/nowarn/nowarn.scala:13:11 -------------------------------------
3337
13 |def t2 = { 1; 2 } // warning (the invalid nowarn doesn't silence anything)
3438
| ^
3539
| A pure expression does nothing in statement position; you may be omitting necessary parentheses
36-
37-
longer explanation available when compiling with `-explain`
40+
|--------------------------------------------------------------------------------------------------------------------
41+
| longer explanation available when compiling with `-explain`
42+
·--------------------------------------------------------------------------------------------------------------------
3843
-- Warning: tests/neg-custom-args/nowarn/nowarn.scala:12:8 -------------------------------------------------------------
3944
12 |@nowarn("wat?") // warning (typer, invalid filter)
4045
| ^^^^^^
@@ -44,8 +49,9 @@ longer explanation available when compiling with `-explain`
4449
16 |def t2a = { 1; 2 } // warning (invalid nowarn doesn't silence)
4550
| ^
4651
| A pure expression does nothing in statement position; you may be omitting necessary parentheses
47-
48-
longer explanation available when compiling with `-explain`
52+
|--------------------------------------------------------------------------------------------------------------------
53+
| longer explanation available when compiling with `-explain`
54+
·--------------------------------------------------------------------------------------------------------------------
4955
-- Warning: tests/neg-custom-args/nowarn/nowarn.scala:15:8 -------------------------------------------------------------
5056
15 |@nowarn(t1a.toString) // warning (typer, argument not a compile-time constant)
5157
| ^^^^^^^^^^^^

tests/neg-macros/beta-reduce-inline-result.check

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
55
| Found: Int
66
| Required: (4 : Int)
7-
8-
longer explanation available when compiling with `-explain`
7+
|--------------------------------------------------------------------------------------------------------------------
8+
| longer explanation available when compiling with `-explain`
9+
·--------------------------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)