Skip to content

Commit 7a3550f

Browse files
committed
Better error message if inferred type does not conform to externally visible type.
1 parent ef763b9 commit 7a3550f

File tree

2 files changed

+35
-49
lines changed

2 files changed

+35
-49
lines changed

compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,16 @@ class CheckCaptures extends Recheck, SymTransformer:
10671067
// too annoying. This is a hole since a defualt getter's result type
10681068
// might leak into a type variable.
10691069

1070+
def fail(tree: Tree, expected: Type, addenda: Addenda): Unit =
1071+
def maybeResult = if sym.is(Method) then " result" else ""
1072+
report.error(
1073+
em"""$sym needs an explicit$maybeResult type because the inferred type does not conform to
1074+
|the type that is externally visible in other compilation units.
1075+
|
1076+
| Inferred type : ${tree.tpe}
1077+
| Externally visible type: $expected""",
1078+
tree.srcPos)
1079+
10701080
def addenda(expected: Type) = new Addenda:
10711081
override def toAdd(using Context) =
10721082
def result = if tree.isInstanceOf[ValDef] then"" else " result"
@@ -1083,7 +1093,7 @@ class CheckCaptures extends Recheck, SymTransformer:
10831093
val expected = tpt.tpe.dropAllRetains
10841094
todoAtPostCheck += { () =>
10851095
withCapAsRoot:
1086-
checkConformsExpr(tp, expected, tree.rhs, addenda(expected))
1096+
testAdapted(tp, expected, tree.rhs, addenda(expected))(fail)
10871097
// The check that inferred <: expected is done after recheck so that it
10881098
// does not interfere with normal rechecking by constraining capture set variables.
10891099
}
Lines changed: 24 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,48 @@
1-
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15116.scala:5:13 ----------------------------------------
1+
-- Error: tests/neg-custom-args/captures/i15116.scala:5:13 -------------------------------------------------------------
22
5 | val x = Foo(m) // error
33
| ^^^^^^
4-
| Found: test.Foo{val m: (Bar.this.m² : test.STR^)}^{Bar.this.m²}
5-
| Required: test.Foo
4+
| value x needs an explicit type because the inferred type does not conform to
5+
| the type that is externally visible in other compilation units.
6+
|
7+
| Inferred type : test.Foo{val m: (Bar.this.m² : test.STR^)}^{Bar.this.m²}
8+
| Externally visible type: test.Foo
69
|
710
| where: ^ refers to a fresh root capability in the type of value m²
811
| m is a value in class Foo
912
| m² is a value in class Bar
10-
|
11-
|
12-
| Note that the expected type test.Foo
13-
| is the previously inferred type of value x
14-
| which is also the type seen in separately compiled sources.
15-
| The new inferred type test.Foo{val m: (Bar.this.m : test.STR^)}^{Bar.this.m}
16-
| must conform to this type.
17-
|
18-
| longer explanation available when compiling with `-explain`
19-
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15116.scala:7:13 ----------------------------------------
13+
-- Error: tests/neg-custom-args/captures/i15116.scala:7:13 -------------------------------------------------------------
2014
7 | val x = Foo(m) // error
2115
| ^^^^^^
22-
| Found: test.Foo{val m: (Baz.this.m² : test.STR^)}^{Baz.this.m²}
23-
| Required: test.Foo
16+
| value x needs an explicit type because the inferred type does not conform to
17+
| the type that is externally visible in other compilation units.
18+
|
19+
| Inferred type : test.Foo{val m: (Baz.this.m² : test.STR^)}^{Baz.this.m²}
20+
| Externally visible type: test.Foo
2421
|
2522
| where: ^ refers to a fresh root capability in the type of value m²
2623
| m is a value in class Foo
2724
| m² is a value in trait Baz
28-
|
29-
|
30-
| Note that the expected type test.Foo
31-
| is the previously inferred type of value x
32-
| which is also the type seen in separately compiled sources.
33-
| The new inferred type test.Foo{val m: (Baz.this.m : test.STR^)}^{Baz.this.m}
34-
| must conform to this type.
35-
|
36-
| longer explanation available when compiling with `-explain`
37-
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15116.scala:9:13 ----------------------------------------
25+
-- Error: tests/neg-custom-args/captures/i15116.scala:9:13 -------------------------------------------------------------
3826
9 | val x = Foo(m) // error
3927
| ^^^^^^
40-
| Found: test.Foo{val m: (Bar1.this.m² : test.STR^)}^{Bar1.this.m²}
41-
| Required: test.Foo
28+
| value x needs an explicit type because the inferred type does not conform to
29+
| the type that is externally visible in other compilation units.
30+
|
31+
| Inferred type : test.Foo{val m: (Bar1.this.m² : test.STR^)}^{Bar1.this.m²}
32+
| Externally visible type: test.Foo
4233
|
4334
| where: ^ refers to a fresh root capability in the type of value m²
4435
| m is a value in class Foo
4536
| m² is a value in class Bar1
46-
|
47-
|
48-
| Note that the expected type test.Foo
49-
| is the previously inferred type of value x
50-
| which is also the type seen in separately compiled sources.
51-
| The new inferred type test.Foo{val m: (Bar1.this.m : test.STR^)}^{Bar1.this.m}
52-
| must conform to this type.
53-
|
54-
| longer explanation available when compiling with `-explain`
55-
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15116.scala:11:13 ---------------------------------------
37+
-- Error: tests/neg-custom-args/captures/i15116.scala:11:13 ------------------------------------------------------------
5638
11 | val x = Foo(m) // error
5739
| ^^^^^^
58-
| Found: test.Foo{val m: (Baz2.this.m² : test.STR^)}^{Baz2.this.m²}
59-
| Required: test.Foo
40+
| value x needs an explicit type because the inferred type does not conform to
41+
| the type that is externally visible in other compilation units.
42+
|
43+
| Inferred type : test.Foo{val m: (Baz2.this.m² : test.STR^)}^{Baz2.this.m²}
44+
| Externally visible type: test.Foo
6045
|
6146
| where: ^ refers to a fresh root capability in the type of value m²
6247
| m is a value in class Foo
6348
| m² is a value in trait Baz2
64-
|
65-
|
66-
| Note that the expected type test.Foo
67-
| is the previously inferred type of value x
68-
| which is also the type seen in separately compiled sources.
69-
| The new inferred type test.Foo{val m: (Baz2.this.m : test.STR^)}^{Baz2.this.m}
70-
| must conform to this type.
71-
|
72-
| longer explanation available when compiling with `-explain`

0 commit comments

Comments
 (0)