Skip to content

Commit

Permalink
Merge pull request #14357 from dotty-staging/improve-explain-renderning
Browse files Browse the repository at this point in the history
Improve `-explain` rendering
  • Loading branch information
anatoliykmetyuk authored Feb 11, 2022
2 parents 06891dc + 0413501 commit 2d514d8
Show file tree
Hide file tree
Showing 87 changed files with 401 additions and 362 deletions.
4 changes: 0 additions & 4 deletions compiler/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ object ConsoleReporter {
/** Prints the message with the given position indication. */
def doReport(dia: Diagnostic)(using Context): Unit = {
printMessage(messageAndPos(dia))
if Diagnostic.shouldExplain(dia) then
printMessage(explanation(dia.msg))
else if dia.msg.canExplain then
printMessage("\nlonger explanation available when compiling with `-explain`")
}
}
}
13 changes: 13 additions & 0 deletions compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,19 @@ trait MessageRendering {
else sb.append(msg.message)
if (dia.isVerbose)
appendFilterHelp(dia, sb)

if Diagnostic.shouldExplain(dia) then
sb.append(EOL).append(newBox())
sb.append(EOL).append(offsetBox).append(" Explanation (enabled by `-explain`)")
sb.append(EOL).append(newBox(soft = true))
dia.msg.explanation.split(EOL).foreach { line =>
sb.append(EOL).append(offsetBox).append(if line.isEmpty then "" else " ").append(line)
}
sb.append(EOL).append(endBox)
else if dia.msg.canExplain then
sb.append(EOL).append(offsetBox)
sb.append(EOL).append(offsetBox).append(" longer explanation available when compiling with `-explain`")

sb.toString
}

Expand Down
9 changes: 4 additions & 5 deletions compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala
Original file line number Diff line number Diff line change
Expand Up @@ -142,18 +142,17 @@ object ErrorReporting {
|conforms to
| $expected
|but the comparison trace ended with `false`:
"""
|"""
val c = ctx.typerState.constraint
val constraintText =
if c.domainLambdas.isEmpty then
"the empty constraint"
else
i"""a constraint with:
|$c"""
i"""
|${TypeComparer.explained(_.isSubType(found, expected), header)}
|
|The tests were made under $constraintText"""
i"""${TypeComparer.explained(_.isSubType(found, expected), header)}
|
|The tests were made under $constraintText"""

/** Format `raw` implicitNotFound or implicitAmbiguous argument, replacing
* all occurrences of `${X}` where `X` is in `paramNames` with the
Expand Down
39 changes: 26 additions & 13 deletions compiler/test-resources/repl/errmsgs
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,51 @@ scala> val x: List[String] = List(1)
| ^
| Found: (1 : Int)
| Required: String
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
scala> val y: List[List[String]] = List(List(1))
-- [E007] Type Mismatch Error: -------------------------------------------------
1 | val y: List[List[String]] = List(List(1))
| ^
| Found: (1 : Int)
| Required: String
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
scala> val z: (List[String], List[Int]) = (List(1), List("a"))
-- [E007] Type Mismatch Error: -------------------------------------------------
1 | val z: (List[String], List[Int]) = (List(1), List("a"))
| ^
| Found: (1 : Int)
| Required: String
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
-- [E007] Type Mismatch Error: -------------------------------------------------
1 | val z: (List[String], List[Int]) = (List(1), List("a"))
| ^^^
| Found: ("a" : String)
| Required: Int
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
2 errors found
scala> val a: Inv[String] = new Inv(new Inv(1))
-- [E007] Type Mismatch Error: -------------------------------------------------
1 | val a: Inv[String] = new Inv(new Inv(1))
| ^^^^^^^^^^
| Found: Inv[Int]
| Required: String
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
scala> val b: Inv[String] = new Inv(1)
-- [E007] Type Mismatch Error: -------------------------------------------------
1 | val b: Inv[String] = new Inv(1)
| ^
| Found: (1 : Int)
| Required: String
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
scala> abstract class C { type T; val x: T; val s: Unit = { type T = String; var y: T = x; locally { def f() = { type T = Int; val z: T = y }; f() } }; }
-- [E007] Type Mismatch Error: -------------------------------------------------
Expand All @@ -55,7 +61,8 @@ scala> abstract class C { type T; val x: T; val s: Unit = { type T = String; var
|
|where: T is a type in class C
| T² is a type in the initializer of value s which is an alias of String
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
-- [E007] Type Mismatch Error: -------------------------------------------------
1 | abstract class C { type T; val x: T; val s: Unit = { type T = String; var y: T = x; locally { def f() = { type T = Int; val z: T = y }; f() } }; }
| ^
Expand All @@ -64,7 +71,8 @@ longer explanation available when compiling with `-explain`
|
|where: T is a type in the initializer of value s which is an alias of String
| T² is a type in method f which is an alias of Int
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
2 errors found
scala> class Foo() { def bar: Int = 1 }; val foo = new Foo(); foo.barr
-- [E008] Not Found Error: -----------------------------------------------------
Expand All @@ -78,33 +86,38 @@ scala> val x: List[Int] = "foo" :: List(1)
| ^^^^^
| Found: ("foo" : String)
| Required: Int
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
scala> while ((( foo ))) {}
-- [E006] Not Found Error: -----------------------------------------------------
1 | while ((( foo ))) {}
| ^^^
| Not found: foo
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
scala> val a: iDontExist = 1
-- [E006] Not Found Error: -----------------------------------------------------
1 | val a: iDontExist = 1
| ^^^^^^^^^^
| Not found: type iDontExist
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
scala> def foo1(x: => Int) = x _
-- [E099] Syntax Error: --------------------------------------------------------
1 | def foo1(x: => Int) = x _
| ^^^
|Only function types can be followed by _ but the current expression has type Int
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
scala> def foo2(x: => Int): () => Int = x _
-- [E099] Syntax Error: --------------------------------------------------------
1 | def foo2(x: => Int): () => Int = x _
| ^^^
|Only function types can be followed by _ but the current expression has type Int
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
3 changes: 2 additions & 1 deletion compiler/test-resources/repl/i13208.default.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ scala> try 1
| ^^^^^
| A try without catch or finally is equivalent to putting
| its body in a block; no exceptions are handled.
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
val res0: Int = 1
9 changes: 6 additions & 3 deletions compiler/test-resources/repl/i2063
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@ scala> class Foo extends Bar // with one tab
1 | class Foo extends Bar // with one tab
| ^^^
| Not found: type Bar
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
scala> class Foo extends Bar // with spaces
-- [E006] Not Found Error: -----------------------------------------------------
1 | class Foo extends Bar // with spaces
| ^^^
| Not found: type Bar
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
scala> class Foo extends Bar // with tabs
-- [E006] Not Found Error: -----------------------------------------------------
1 | class Foo extends Bar // with tabs
| ^^^
| Not found: type Bar
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
3 changes: 2 additions & 1 deletion compiler/test-resources/repl/i2213
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ scala> def x
1 | def x
| ^
| Missing return type
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
scala> def x: Int
-- [E067] Syntax Error: --------------------------------------------------------
1 | def x: Int
Expand Down
3 changes: 2 additions & 1 deletion compiler/test-resources/repl/i4217
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ scala> def foo(x: Option[Int]) = x match { case None => }
| match may not be exhaustive.
|
| It would fail on pattern case: Some(_)
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
def foo(x: Option[Int]): Unit
3 changes: 2 additions & 1 deletion compiler/test-resources/repl/i4566
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ scala> object test { type ::[A, B]; def a: Int :: Int = ???; def b: Int = a }
| ^
| Found: Int :: Int
| Required: Int
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
6 changes: 4 additions & 2 deletions compiler/test-resources/repl/i7644
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ scala> class T extends CanEqual
1 | class T extends CanEqual
| ^
| Cannot extend sealed trait CanEqual in a different source file
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
-- [E056] Syntax Error: --------------------------------------------------------
1 | class T extends CanEqual
| ^^^^^^^^
Expand All @@ -14,7 +15,8 @@ scala> class T extends CanEqual
1 | class T extends CanEqual
| ^
| Cannot extend sealed trait CanEqual in a different source file
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
-- [E056] Syntax Error: --------------------------------------------------------
1 | class T extends CanEqual
| ^^^^^^^^
Expand Down
3 changes: 2 additions & 1 deletion compiler/test-resources/repl/importFromObj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ scala> buf += xs
| ^^
| Found: (o.xs : List[Int])
| Required: Int
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
scala> buf ++= xs
val res0: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3)
Expand Down
6 changes: 4 additions & 2 deletions compiler/test-resources/repl/notFound
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ scala> Foo
1 | Foo
| ^^^
| Not found: Foo
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
scala> Bar
-- [E006] Not Found Error: -----------------------------------------------------
1 | Bar
| ^^^
| Not found: Bar
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
9 changes: 6 additions & 3 deletions compiler/test-resources/repl/nowarn.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ scala> @annotation.nowarn def f = try 1 // @nowarn doesn't work on first line, c
| ^^^^^
| A try without catch or finally is equivalent to putting
| its body in a block; no exceptions are handled.
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
def f: Int
scala> @annotation.nowarn def f = try 1
def f: Int
Expand All @@ -16,7 +17,8 @@ scala> def f = try 1
| ^^^^^
| A try without catch or finally is equivalent to putting
| its body in a block; no exceptions are handled.
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
def f: Int
scala> @annotation.nowarn def f = { 1; 2 }
def f: Int
Expand All @@ -26,5 +28,6 @@ scala> def f = { 1; 2 }
1 | def f = { 1; 2 }
| ^
|A pure expression does nothing in statement position; you may be omitting necessary parentheses
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
def f: Int
6 changes: 4 additions & 2 deletions compiler/test-resources/repl/overrides
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ scala> class B { override def foo(i: Int): Unit = {}; }
1 | class B { override def foo(i: Int): Unit = {}; }
| ^
| method foo overrides nothing
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
scala> class A { def foo: Unit = {}; }
// defined class A
Expand All @@ -12,5 +13,6 @@ scala> class B extends A { override def foo(i: Int): Unit = {}; }
1 | class B extends A { override def foo(i: Int): Unit = {}; }
| ^
| method foo has a different signature than the overridden declaration
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
3 changes: 2 additions & 1 deletion compiler/test-resources/repl/reset-command
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ scala> resetNoArgsStillWorks
1 | resetNoArgsStillWorks
| ^^^^^^^^^^^^^^^^^^^^^
| Not found: resetNoArgsStillWorks
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found

scala>:settings "-Dfoo=bar baz"
3 changes: 2 additions & 1 deletion compiler/test-resources/type-printer/type-mismatch
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ scala> val x: Foo[String] = res0
| ^^^^
| Found: (res0 : Foo[Int])
| Required: Foo[String]
longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
1 error found
4 changes: 2 additions & 2 deletions tests/neg-custom-args/explicit-nulls/byname-nullables.check
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
| ^
| Found: (x : String | Null)
| Required: String

longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
-- Error: tests/neg-custom-args/explicit-nulls/byname-nullables.scala:43:32 --------------------------------------------
43 | if x != null then f(identity(x), 1) // error: dropping not null check fails typing
| ^^^^^^^^^^^
Expand Down
8 changes: 4 additions & 4 deletions tests/neg-custom-args/explicit-nulls/i7883.check
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
6 | case r(hd, tl) => Some((hd, tl)) // error // error // error
| ^^
| Not found: hd

longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
-- [E006] Not Found Error: tests/neg-custom-args/explicit-nulls/i7883.scala:6:34 ---------------------------------------
6 | case r(hd, tl) => Some((hd, tl)) // error // error // error
| ^^
| Not found: tl

longer explanation available when compiling with `-explain`
|
| longer explanation available when compiling with `-explain`
Loading

0 comments on commit 2d514d8

Please sign in to comment.