Skip to content

Commit 57f2bbb

Browse files
committed
Perform subscript disambiguation also for error message addenda
1 parent 8ed4527 commit 57f2bbb

Some content is hidden

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

73 files changed

+520
-328
lines changed

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

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,16 +1079,15 @@ class CheckCaptures extends Recheck, SymTransformer:
10791079
| Externally visible type: $expected""",
10801080
tree.srcPos)
10811081

1082-
def addenda(expected: Type) = new Addenda:
1083-
override def toAdd(using Context) =
1084-
def result = if tree.isInstanceOf[ValDef] then"" else " result"
1085-
i"""
1086-
|
1087-
|Note that the expected type $expected
1088-
|is the previously inferred$result type of $sym
1089-
|which is also the type seen in separately compiled sources.
1090-
|The new inferred type $tp
1091-
|must conform to this type.""" :: Nil
1082+
def addenda(expected: Type) = Addenda:
1083+
def result = if tree.isInstanceOf[ValDef] then"" else " result"
1084+
i"""
1085+
|
1086+
|Note that the expected type $expected
1087+
|is the previously inferred$result type of $sym
1088+
|which is also the type seen in separately compiled sources.
1089+
|The new inferred type $tp
1090+
|must conform to this type."""
10921091

10931092
tree.tpt match
10941093
case tpt: InferredTypeTree if !canUseInferred =>
@@ -1276,6 +1275,7 @@ class CheckCaptures extends Recheck, SymTransformer:
12761275
else new Addenda:
12771276
override def toAdd(using Context) = notes.map: note =>
12781277
i"""
1278+
|
12791279
|Note that ${note.description}."""
12801280

12811281
/** Addendas for error messages that show where we have under-approximated by
@@ -1291,13 +1291,11 @@ class CheckCaptures extends Recheck, SymTransformer:
12911291
(parent, " deep")
12921292
case _ =>
12931293
(original, "")*/
1294-
add ++ new Addenda:
1295-
override def toAdd(using Context): List[String] =
1294+
add ++ Addenda:
12961295
i"""
12971296
|
12981297
|Note that a capability $ref in a capture set appearing in contravariant position
12991298
|was mapped to $mapped which is not a capability. Therefore, it was under-approximated to the empty set."""
1300-
:: Nil
13011299
case _ =>
13021300
foldOver(add, t)
13031301

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import ast.Trees
1717
import config.{Feature, MigrationVersion, ScalaVersion}
1818
import transform.patmat.Space
1919
import transform.patmat.SpaceEngine
20-
import typer.ErrorReporting.{err, matchReductionAddendum, substitutableTypeSymbolsInScope}
20+
import typer.ErrorReporting.{err, matchReductionAddendum, substitutableTypeSymbolsInScope, Addenda, NothingToAdd}
2121
import typer.ProtoTypes.{ViewProto, SelectionProto, FunProto}
2222
import typer.Implicits.*
2323
import typer.Inferencing
@@ -297,7 +297,7 @@ extends NotFoundMsg(MissingIdentID) {
297297
}
298298
}
299299

300-
class TypeMismatch(val found: Type, expected: Type, val inTree: Option[untpd.Tree], addenda: => String*)(using Context)
300+
class TypeMismatch(val found: Type, expected: Type, val inTree: Option[untpd.Tree], addenda: Addenda = NothingToAdd)(using Context)
301301
extends TypeMismatchMsg(found, expected)(TypeMismatchID):
302302

303303
def msg(using Context) =
@@ -349,12 +349,12 @@ class TypeMismatch(val found: Type, expected: Type, val inTree: Option[untpd.Tre
349349
|Required: $expectedStr${reported.notes}"""
350350
end msg
351351

352-
override def msgPostscript(using Context) =
352+
override def msgPostscript(using Context): String =
353353
def importSuggestions =
354354
if expected.isTopType || found.isBottomType then ""
355355
else ctx.typer.importSuggestionAddendum(ViewProto(found.widen, expected))
356-
super.msgPostscript
357-
++ addenda.dropWhile(_.isEmpty).headOption.getOrElse(importSuggestions)
356+
357+
addenda.toAdd.mkString ++ super.msgPostscript ++ importSuggestions
358358

359359
override def explain(using Context) =
360360
val treeStr = inTree.map(x => s"\nTree:\n\n${x.show}\n").getOrElse("")

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

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,16 @@ object ErrorReporting {
7373

7474
/** A mixin trait that can produce added elements for an error message */
7575
trait Addenda:
76-
self =>
77-
def toAdd(using Context): List[String] = Nil
78-
def ++ (follow: Addenda) = new Addenda:
79-
override def toAdd(using Context) = self.toAdd ++ follow.toAdd
76+
def toAdd(using Context): List[String]
77+
def ++(follow: Addenda) = new Addenda:
78+
def toAdd(using Context) = Addenda.this.toAdd ++ follow.toAdd
79+
80+
object Addenda:
81+
def apply(msg: Context ?=> String): Addenda = new Addenda:
82+
def toAdd(using Context) = msg :: Nil
8083

81-
object NothingToAdd extends Addenda
84+
object NothingToAdd extends Addenda:
85+
def toAdd(using Context): List[String] = Nil
8286

8387
class Errors(using Context) {
8488

@@ -195,10 +199,11 @@ object ErrorReporting {
195199

196200
def missingElse = tree match
197201
case If(_, _, elsep @ Literal(Constant(()))) if elsep.span.isSynthetic =>
198-
"\nMaybe you are missing an else part for the conditional?"
199-
case _ => ""
202+
Addenda("\nMaybe you are missing an else part for the conditional?")
203+
case _ =>
204+
NothingToAdd
200205

201-
errorTree(tree, TypeMismatch(treeTp, expectedTp, Some(tree), (addenda.toAdd :+ missingElse)*))
206+
errorTree(tree, TypeMismatch(treeTp, expectedTp, Some(tree), addenda ++ missingElse))
202207
}
203208

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

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,8 @@ object Implicits:
481481
if (argument.isEmpty) i"match type ${clarify(expectedType)}"
482482
else i"convert from ${argument.tpe} to ${clarify(expectedType)}"
483483
}
484+
485+
def toAdd(using Context) = Nil
484486
}
485487

486488
class NoMatchingImplicits(val expectedType: Type, val argument: Tree, constraint: Constraint = OrderingConstraint.empty)

tests/neg-custom-args/captures/box-adapt-cases.check

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
| ^^^^^^^^^^^^^^^^
44
| Found: (cap: Cap^{io}) ->{io} Int
55
| Required: Cap^{io} -> Int
6+
|
67
| Note that capability io is not included in capture set {}.
78
|
89
| longer explanation available when compiling with `-explain`
@@ -11,6 +12,7 @@
1112
| ^^^^^^^^^^^^^^^^
1213
| Found: (cap: Cap^'s1) ->{io, fs} Int
1314
| Required: Cap^{io, fs} ->{io} Int
15+
|
1416
| Note that capability fs is not included in capture set {io}.
1517
|
1618
| longer explanation available when compiling with `-explain`

tests/neg-custom-args/captures/byname.check

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,17 @@
1010
|Found: () ?->{cap1} Int ->{cap1} Int
1111
|Required: () ?=> Int ->{cap2} Int
1212
|
13-
|where: ?=> refers to a fresh root capability created in method test when checking argument to parameter ff of method h
14-
|
1513
|Note that capability cap1 is not included in capture set {cap2}.
1614
|
15+
|where: ?=> refers to a fresh root capability created in method test when checking argument to parameter ff of method h
16+
|
1717
| longer explanation available when compiling with `-explain`
1818
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/byname.scala:19:5 ----------------------------------------
1919
19 | h(g()) // error
2020
| ^^^
2121
| Found: () ?->{cap2} I^'s1
2222
| Required: () ?->{cap1} I
23+
|
2324
| Note that capability cap2 is not included in capture set {cap1}.
2425
|
2526
| longer explanation available when compiling with `-explain`
@@ -28,6 +29,7 @@
2829
| ^^^^^^^^^
2930
| Found: () ->{cap2} I^'s2
3031
| Required: () ->{cap1} I
32+
|
3133
| Note that capability cap2 is not included in capture set {cap1}.
3234
|
3335
| longer explanation available when compiling with `-explain`

tests/neg-custom-args/captures/capt-depfun.check

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
| Found: Str^{} ->{ac, y, z} Str^{y, z}
55
| Required: Str^{y, z} => Str^{y, z}
66
|
7-
| where: => refers to a fresh root capability in the type of value dc
8-
|
97
| Note that capability y is not included in capture set {}.
108
|
9+
| where: => refers to a fresh root capability in the type of value dc
10+
|
1111
| longer explanation available when compiling with `-explain`

tests/neg-custom-args/captures/capt1.check

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44
| Found: () ->{x} C
55
| Required: () -> C
6+
|
67
| Note that capability x is not included in capture set {}.
78
|
89
| longer explanation available when compiling with `-explain`
@@ -11,6 +12,7 @@
1112
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1213
| Found: () ->{x} C^'s1
1314
| Required: Matchable
15+
|
1416
| Note that capability x is not included in capture set {}.
1517
|
1618
| longer explanation available when compiling with `-explain`
@@ -19,6 +21,7 @@
1921
| ^
2022
| Found: (y: Int) ->{x} Int
2123
| Required: Matchable
24+
|
2225
| Note that capability x is not included in capture set {}.
2326
16 | f
2427
|
@@ -28,6 +31,7 @@
2831
| ^
2932
| Found: A^{x}
3033
| Required: A
34+
|
3135
| Note that capability x is not included in capture set {}.
3236
23 | def m() = if x == null then y else y
3337
24 | F(22)
@@ -38,6 +42,7 @@
3842
| ^
3943
| Found: A^{x}
4044
| Required: A
45+
|
4146
| Note that capability x is not included in capture set {}.
4247
28 | def m() = if x == null then y else y
4348
|
@@ -55,11 +60,13 @@
5560
|Found: () ->'s2 C^
5661
|Required: () -> C^²
5762
|
58-
|where: ^ refers to a root capability associated with the result type of (): C^
59-
| ^² refers to a fresh root capability created in value z2 when checking argument to parameter a of method h
63+
|Note that capability cap is not included in capture set {cap²}
64+
|because cap is not visible from cap² in value z2.
6065
|
61-
|Note that capability <cap of (): C^> is not included in capture set {cap}
62-
|because <cap of (): C^> is not visible from cap in value z2.
66+
|where: ^ refers to a root capability associated with the result type of (): C^
67+
| ^² refers to a fresh root capability created in value z2 when checking argument to parameter a of method h
68+
| cap is a root capability associated with the result type of (): C^
69+
| cap² is a fresh root capability created in value z2 when checking argument to parameter a of method h
6370
|
6471
| longer explanation available when compiling with `-explain`
6572
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:37:5 -----------------------------------------
@@ -68,11 +75,13 @@
6875
|Found: () ->'s3 C^
6976
|Required: () -> C^²
7077
|
71-
|where: ^ refers to a root capability associated with the result type of (): C^
72-
| ^² refers to a fresh root capability created in value z2 when checking argument to parameter b of method h
78+
|Note that capability cap is not included in capture set {cap²}
79+
|because cap is not visible from cap² in value z2.
7380
|
74-
|Note that capability <cap of (): C^> is not included in capture set {cap}
75-
|because <cap of (): C^> is not visible from cap in value z2.
81+
|where: ^ refers to a root capability associated with the result type of (): C^
82+
| ^² refers to a fresh root capability created in value z2 when checking argument to parameter b of method h
83+
| cap is a root capability associated with the result type of (): C^
84+
| cap² is a fresh root capability created in value z2 when checking argument to parameter b of method h
7685
|
7786
| longer explanation available when compiling with `-explain`
7887
-- Error: tests/neg-custom-args/captures/capt1.scala:38:13 -------------------------------------------------------------

tests/neg-custom-args/captures/cc-existential-conformance.check

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,31 @@
44
| Found: (x : A -> (x²: A) -> B^)
55
| Required: A -> A -> B^²
66
|
7-
| where: ^ refers to a root capability associated with the result type of (x²: A): B^
8-
| ^² refers to a fresh root capability in the type of value y
9-
| x is a value in method test
10-
| x² is a reference to a value parameter
7+
| Note that capability cap is not included in capture set {cap²}
8+
| because cap is not visible from cap² in value y.
119
|
12-
| Note that capability <cap of (x: A): B^> is not included in capture set {cap}
13-
| because <cap of (x: A): B^> is not visible from cap in value y.
10+
| where: ^ refers to a root capability associated with the result type of (x²: A): B^
11+
| ^² refers to a fresh root capability in the type of value y
12+
| cap is a root capability associated with the result type of (x²: A): B^
13+
| cap² is a fresh root capability in the type of value y
14+
| x is a value in method test
15+
| x² is a reference to a value parameter
1416
|
1517
| longer explanation available when compiling with `-explain`
1618
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/cc-existential-conformance.scala:9:29 --------------------
1719
9 | val z: A -> (x: A) -> B^ = y // error
1820
| ^
19-
| Found: A -> A -> B^{y*}
20-
| Required: A -> (x: A) -> B^
21+
| Found: A -> A -> B^{y*}
22+
| Required: A -> (x: A) -> B^
2123
|
22-
| where: ^ refers to a root capability associated with the result type of (x: A): B^
24+
| Note that capability y* is not included in capture set {cap}.
2325
|
24-
| Note that capability y* is not included in capture set {<cap of (x: A): B^>}.
26+
| Note that the existential capture root in B^²
27+
| cannot subsume the capability y* since that capability is not a `Sharable` capability..
28+
|
29+
| where: ^ refers to a root capability associated with the result type of (x: A): B^
30+
| ^² refers to the universal root capability
31+
| cap is a root capability associated with the result type of (x: A): B^
2532
|
2633
| longer explanation available when compiling with `-explain`
2734
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/cc-existential-conformance.scala:13:19 -------------------
@@ -30,13 +37,15 @@
3037
| Found: (x : (x²: A) -> B^)
3138
| Required: A -> B^²
3239
|
33-
| where: ^ refers to a root capability associated with the result type of (x²: A): B^
34-
| ^² refers to a fresh root capability in the type of value y
35-
| x is a value in method test2
36-
| x² is a reference to a value parameter
40+
| Note that capability cap is not included in capture set {cap²}
41+
| because cap is not visible from cap² in value y.
3742
|
38-
| Note that capability <cap of (x: A): B^> is not included in capture set {cap}
39-
| because <cap of (x: A): B^> is not visible from cap in value y.
43+
| where: ^ refers to a root capability associated with the result type of (x²: A): B^
44+
| ^² refers to a fresh root capability in the type of value y
45+
| cap is a root capability associated with the result type of (x²: A): B^
46+
| cap² is a fresh root capability in the type of value y
47+
| x is a value in method test2
48+
| x² is a reference to a value parameter
4049
|
4150
| longer explanation available when compiling with `-explain`
4251
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/cc-existential-conformance.scala:14:24 -------------------
@@ -45,8 +54,13 @@
4554
| Found: A -> B^{y*}
4655
| Required: (x: A) -> B^
4756
|
48-
| where: ^ refers to a root capability associated with the result type of (x: A): B^
57+
| Note that capability y* is not included in capture set {cap}.
58+
|
59+
| Note that the existential capture root in B^²
60+
| cannot subsume the capability y* since that capability is not a `Sharable` capability..
4961
|
50-
| Note that capability y* is not included in capture set {<cap of (x: A): B^>}.
62+
| where: ^ refers to a root capability associated with the result type of (x: A): B^
63+
| ^² refers to the universal root capability
64+
| cap is a root capability associated with the result type of (x: A): B^
5165
|
5266
| longer explanation available when compiling with `-explain`

tests/neg-custom-args/captures/cc-glb.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
| ^^
44
| Found: (x1 : (Foo[T] & Foo[Any])^{io})
55
| Required: Foo[T]
6+
|
67
| Note that capability io is not included in capture set {}.
78
|
89
| longer explanation available when compiling with `-explain`

0 commit comments

Comments
 (0)