Skip to content

Commit b902516

Browse files
authored
Merge pull request #12717 from rssh/better-type-reporting-1
added to type mismatch reporting output of tree, which can't be typed
2 parents 2260aa2 + 0913a90 commit b902516

File tree

9 files changed

+69
-6
lines changed

9 files changed

+69
-6
lines changed

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ import transform.SymUtils._
241241
}
242242
}
243243

244-
class TypeMismatch(found: Type, expected: Type, addenda: => String*)(using Context)
244+
class TypeMismatch(found: Type, expected: Type, inTree: Option[untpd.Tree], addenda: => String*)(using Context)
245245
extends TypeMismatchMsg(found, expected)(TypeMismatchID):
246246

247247
// replace constrained TypeParamRefs and their typevars by their bounds where possible
@@ -280,7 +280,13 @@ import transform.SymUtils._
280280
val (foundStr, expectedStr) = Formatting.typeDiff(found2, expected2)(using printCtx)
281281
s"""|Found: $foundStr
282282
|Required: $expectedStr""".stripMargin
283-
+ whereSuffix + postScript
283+
+ whereSuffix + postScript
284+
285+
override def explain =
286+
val treeStr = inTree.map(x => s"\nTree: ${x.show}").getOrElse("")
287+
treeStr + "\n" + super.explain
288+
289+
284290
end TypeMismatch
285291

286292
class NotAMember(site: Type, val name: Name, selected: String, addendum: => String = "")(using Context)

compiler/src/dotty/tools/dotc/transform/TreeChecker.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ class TreeChecker extends Phase with SymTransformer {
592592
!isPrimaryConstructorReturn &&
593593
!pt.isInstanceOf[FunOrPolyProto])
594594
assert(tree.tpe <:< pt, {
595-
val mismatch = TypeMismatch(tree.tpe, pt)
595+
val mismatch = TypeMismatch(tree.tpe, pt, Some(tree))
596596
i"""|${mismatch.msg}
597597
|found: ${infoStr(tree.tpe)}
598598
|expected: ${infoStr(pt)}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ trait Applications extends Compatibility {
441441
// it might be healed by an implicit conversion
442442
()
443443
else
444-
fail(TypeMismatch(methType.resultType, resultType))
444+
fail(TypeMismatch(methType.resultType, resultType, None))
445445

446446
// match all arguments with corresponding formal parameters
447447
matchArgs(orderedArgs, methType.paramInfos, 0)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ object ErrorReporting {
131131
case If(_, _, elsep @ Literal(Constant(()))) if elsep.span.isSynthetic =>
132132
"\nMaybe you are missing an else part for the conditional?"
133133
case _ => ""
134-
errorTree(tree, TypeMismatch(treeTp, pt, implicitFailure.whyNoConversion, missingElse))
134+
errorTree(tree, TypeMismatch(treeTp, pt, Some(tree), implicitFailure.whyNoConversion, missingElse))
135135
}
136136

137137
/** A subtype log explaining why `found` does not conform to `expected` */

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3882,7 +3882,7 @@ class Typer extends Namer
38823882
// - it complicates the protocol
38833883
// - such code patterns usually implies hidden errors in the code
38843884
// - it's safe/sound to reject the code
3885-
report.error(TypeMismatch(tree.tpe, pt, "\npattern type is incompatible with expected type"), tree.srcPos)
3885+
report.error(TypeMismatch(tree.tpe, pt, Some(tree), "\npattern type is incompatible with expected type"), tree.srcPos)
38863886
else
38873887
val cmp =
38883888
untpd.Apply(

compiler/test/dotty/tools/dotc/CompilationTests.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ class CompilationTests {
177177
compileFile("tests/neg-custom-args/matchable.scala", defaultOptions.and("-Xfatal-warnings", "-source", "future")),
178178
compileFile("tests/neg-custom-args/i7314.scala", defaultOptions.and("-Xfatal-warnings", "-source", "future")),
179179
compileFile("tests/neg-custom-args/feature-shadowing.scala", defaultOptions.and("-Xfatal-warnings", "-feature")),
180+
compileDir("tests/neg-custom-args/hidden-type-errors", defaultOptions.and("-explain")),
180181
).checkExpectedErrors()
181182
}
182183

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-- [E007] Type Mismatch Error: tests/neg-custom-args/hidden-type-errors/Test.scala:6:24 --------------------------------
2+
6 | val x = X.doSomething("XXX") // error
3+
| ^^^^^^^^^^^^^^^^^^^^
4+
| Found: String
5+
| Required: Int
6+
| This location contains code that was inlined from Test.scala:6
7+
8+
Explanation
9+
===========
10+
11+
Tree: t12717.A.bar("XXX")
12+
13+
I tried to show that
14+
String
15+
conforms to
16+
Int
17+
but the comparison trace ended with `false`:
18+
19+
==> String <: Int
20+
==> String <: Int (recurring)
21+
==> String <: Int (recurring)
22+
<== String <: Int (recurring) = false
23+
<== String <: Int (recurring) = false
24+
<== String <: Int = false
25+
26+
The tests were made under the empty constraint
27+
28+
1 error found
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package t12717
2+
3+
import scala.quoted._
4+
5+
object A:
6+
7+
def foo(x:Int): Int = ???
8+
9+
def bar(x:String): String = ???
10+
11+
12+
object X:
13+
14+
inline def doSomething[T](inline x:T):Any = ${
15+
doSomethingImpl('x)
16+
}
17+
18+
def doSomethingImpl[T:Type](x:Expr[T])(using Quotes):Expr[Any] =
19+
import quotes.reflect._
20+
val aTerm = '{A}.asTerm
21+
val xBar = Apply(Select.unique(aTerm,"bar"),List(x.asTerm))
22+
Apply(Select.unique(aTerm,"foo"), List(xBar)).asExpr
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package t12717
2+
3+
4+
object Test:
5+
6+
val x = X.doSomething("XXX") // error

0 commit comments

Comments
 (0)