Skip to content

Commit eac944e

Browse files
committed
Try to pick the most informative note to display
1 parent 7ca78b1 commit eac944e

File tree

10 files changed

+86
-28
lines changed

10 files changed

+86
-28
lines changed

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,18 @@ object CaptureSet:
13171317
case _ =>
13181318
false
13191319

1320+
/** An include failure F1 covers another include failure F2 unless F2
1321+
* strictly subsumes F1, which means they describe the same capture sets
1322+
* and the element in F2 is more specific than the element in F1.
1323+
*/
1324+
override def covers(other: Note)(using Context) = other match
1325+
case other @ IncludeFailure(cs1, elem1, _) =>
1326+
val strictlySubsumes =
1327+
cs.elems == cs1.elems
1328+
&& elem1.singletonCaptureSet.mightSubcapture(elem.singletonCaptureSet)
1329+
!strictlySubsumes
1330+
case _ => false
1331+
13201332
def trailing(msg: String)(using Context): String =
13211333
i"""
13221334
|
@@ -1387,13 +1399,19 @@ object CaptureSet:
13871399
* @param hi the upper type of the orginal type comparison, or NoType if not known
13881400
*/
13891401
case class MutAdaptFailure(cs: CaptureSet, lo: Type = NoType, hi: Type = NoType) extends Note:
1402+
13901403
def render(using Context): String =
13911404
def ofType(tp: Type) = if tp.exists then i"of the mutable type $tp" else "of a mutable type"
13921405
i"""
13931406
|
13941407
|Note that $cs is an exclusive capture set ${ofType(hi)},
13951408
|it cannot subsume a read-only capture set ${ofType(lo)}."""
13961409

1410+
// Show only one failure of this kind
1411+
override def covers(other: Note)(using Context) =
1412+
other.isInstanceOf[MutAdaptFailure]
1413+
end MutAdaptFailure
1414+
13971415
/** A VarState serves as a snapshot mechanism that can undo
13981416
* additions of elements or super sets if an operation fails
13991417
*/

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3324,12 +3324,12 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
33243324
def reduceMatchWith[T](op: MatchReducer => T)(using Context): T =
33253325
inSubComparer(matchReducer)(op)
33263326

3327-
/** Add given note, provided there is not yet an error note with
3328-
* the same class as `note`.
3327+
/** Add given note, provided there is not yet an error note that covers `note`
3328+
* If the new note is added, any existing note covered by it is removed first.
33293329
*/
3330-
def addErrorNote(note: Note): Unit =
3331-
if errorNotes.forall(_._2.getClass != note.getClass) then
3332-
errorNotes = (recCount, note) :: errorNotes
3330+
def addErrorNote(note: Note)(using Context): Unit =
3331+
if !errorNotes.exists(_._2.covers(note)) then
3332+
errorNotes = (recCount, note) :: errorNotes.filterConserve(n => !note.covers(n._2))
33333333
assert(maxErrorLevel <= recCount)
33343334
maxErrorLevel = recCount
33353335

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ object Message:
4343

4444
/** A note can produce an added string for an error message */
4545
abstract class Note:
46-
46+
4747
/** Should the note be shown before the actual message or after?
4848
* Default is after.
4949
*/
@@ -52,6 +52,13 @@ object Message:
5252
/** The note rendered as part of an error message */
5353
def render(using Context): String
5454

55+
/** If note N1 covers note N2 then N1 and N2 won't be shown together in
56+
* an error message. Instead we show the note that's strictly better in terms
57+
* of the "covers" partial ordering, or, if there's no strict wionner, the first
58+
* added note.
59+
*/
60+
def covers(other: Note)(using Context): Boolean = false
61+
5562
object Note:
5663
def apply(msg: Context ?=> String) = new Note:
5764
def render(using Context) = msg

tests/neg-custom-args/captures/cc-poly-2.check

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
| Found: (d : Test.D^)
55
| Required: Test.D^{c1}
66
|
7-
| Note that capability cap is not included in capture set {c1}.
7+
| Note that capability d is not included in capture set {c1}.
88
|
9-
| where: ^ and cap refer to a fresh root capability in the type of value d
9+
| where: ^ refers to a fresh root capability in the type of value d
1010
|
1111
| longer explanation available when compiling with `-explain`
1212
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/cc-poly-2.scala:16:20 ------------------------------------
@@ -15,6 +15,6 @@
1515
| Found: (x : Test.D^{d})
1616
| Required: Test.D^{c1}
1717
|
18-
| Note that capability d is not included in capture set {c1}.
18+
| Note that capability x is not included in capture set {c1}.
1919
|
2020
| longer explanation available when compiling with `-explain`

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
| Found: (io : IO^)
55
| Required: IO^²
66
|
7-
| Note that capability cap is not included in capture set {cap²}
8-
| because cap in method setIO is not visible from cap² in variable myIO.
7+
| Note that capability io is not included in capture set {cap}
8+
| because (io : IO^) in method setIO is not visible from cap in variable myIO.
99
|
10-
| where: ^ and cap refer to a fresh root capability in the type of parameter io
11-
| ^² and cap² refer to a fresh root capability in the type of variable myIO
10+
| where: ^ refers to a fresh root capability in the type of parameter io
11+
| ^² and cap refer to a fresh root capability in the type of variable myIO
1212
|
1313
| longer explanation available when compiling with `-explain`
1414
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i23431.scala:11:13 ---------------------------------------
@@ -17,11 +17,11 @@
1717
| Found: (io2 : IO^)
1818
| Required: IO^²
1919
|
20-
| Note that capability cap is not included in capture set {cap²}
21-
| because cap in an enclosing function is not visible from cap² in variable myIO.
20+
| Note that capability io2 is not included in capture set {cap}
21+
| because (io2 : IO^) in an enclosing function is not visible from cap in variable myIO.
2222
|
23-
| where: ^ and cap refer to a fresh root capability in the type of parameter io2
24-
| ^² and cap² refer to a fresh root capability in the type of variable myIO
23+
| where: ^ refers to a fresh root capability in the type of parameter io2
24+
| ^² and cap refer to a fresh root capability in the type of variable myIO
2525
|
2626
| longer explanation available when compiling with `-explain`
2727
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i23431.scala:12:12 ---------------------------------------

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
| Found: (b : B{val elem1: A^{a}; val elem2: A^{a}}^{cap, a})
55
| Required: B^{async}
66
|
7-
| Note that capability cap is not included in capture set {async}.
7+
| Note that capability b is not included in capture set {async}.
88
|
99
| where: cap is a fresh root capability in the type of value b
1010
|

tests/neg-custom-args/captures/outer-var.check

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
| Found: (q : () => Unit)
55
| Required: () ->{p, q²} Unit
66
|
7-
| Note that capability cap is not included in capture set {p, q²}.
7+
| Note that capability q is not included in capture set {p, q²}.
88
|
9-
| where: => and cap refer to a fresh root capability in the type of parameter q
10-
| q is a parameter in method inner
11-
| q² is a parameter in method test
9+
| where: => refers to a fresh root capability in the type of parameter q
10+
| q is a parameter in method inner
11+
| q² is a parameter in method test
1212
|
1313
| longer explanation available when compiling with `-explain`
1414
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/outer-var.scala:13:9 -------------------------------------
@@ -39,9 +39,9 @@
3939
| Found: (q : () => Unit)
4040
| Required: () ->{p} Unit
4141
|
42-
| Note that capability cap cannot be included in capture set {p} of variable y.
42+
| Note that capability q cannot be included in capture set {p} of variable y.
4343
|
44-
| where: => and cap refer to a fresh root capability in the type of parameter q
44+
| where: => refers to a fresh root capability in the type of parameter q
4545
|
4646
| longer explanation available when compiling with `-explain`
4747
-- Error: tests/neg-custom-args/captures/outer-var.scala:17:57 ---------------------------------------------------------

tests/neg-custom-args/captures/scope-extrude-mut.check

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
| Found: (a1 : A^)
55
| Required: A^²
66
|
7-
| Note that capability cap is not included in capture set {cap²}
8-
| because cap in method b is not visible from cap² in variable a.
7+
| Note that capability a1 is not included in capture set {cap}
8+
| because (a1 : A^) in method b is not visible from cap in variable a.
99
|
10-
| where: ^ and cap refer to a fresh root capability classified as Mutable in the type of value a1
11-
| ^² and cap² refer to a fresh root capability classified as Mutable in the type of variable a
10+
| where: ^ refers to a fresh root capability classified as Mutable in the type of value a1
11+
| ^² and cap refer to a fresh root capability classified as Mutable in the type of variable a
1212
|
1313
| longer explanation available when compiling with `-explain`
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/scope-extrusions.scala:8:8 -------------------------------
2+
8 | v = x // error
3+
| ^
4+
| Found: (x : IO)
5+
| Required: IO^
6+
|
7+
| Note that capability x is not included in capture set {cap}
8+
| because (x : IO) in method f1 is not visible from cap in variable v.
9+
|
10+
| where: ^ and cap refer to a fresh root capability classified as SharedCapability in the type of variable v
11+
|
12+
| longer explanation available when compiling with `-explain`
13+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/scope-extrusions.scala:9:8 -------------------------------
14+
9 | w = g // error
15+
| ^
16+
| Found: () ->{x} Unit
17+
| Required: () => Unit
18+
|
19+
| Note that capability x is not included in capture set {cap}
20+
| because (x : IO) in method f1 is not visible from cap in variable w.
21+
|
22+
| where: => and cap refer to a fresh root capability in the type of variable w
23+
|
24+
| longer explanation available when compiling with `-explain`
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class IO extends caps.SharedCapability
2+
3+
def test(io: IO): Unit =
4+
var v: IO = io
5+
var w: () => Unit = () => ()
6+
def f1(x: IO) =
7+
def g() = println(x)
8+
v = x // error
9+
w = g // error

0 commit comments

Comments
 (0)