Skip to content

Commit e3dd109

Browse files
committed
Fix error message for leaks
1 parent 3c69f59 commit e3dd109

File tree

11 files changed

+26
-20
lines changed

11 files changed

+26
-20
lines changed

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -544,15 +544,21 @@ class CheckCaptures extends Recheck, SymTransformer:
544544
useInfos += ((tree, cs, curEnv))
545545
end markFree
546546

547-
/** If capability `c` refers to a parameter that is not @use declared, report an error.
547+
/** If capability `c` refers to a parameter that is not implicitly or explicitly
548+
* @use declared, report an error.
548549
*/
549550
def checkUseDeclared(c: Capability, pos: SrcPos)(using Context): Unit =
550551
c.paramPathRoot match
551552
case ref: NamedType if !ref.symbol.isUseParam =>
552553
val what = if ref.isType then "Capture set parameter" else "Local reach capability"
554+
def mitigation =
555+
if ccConfig.allowUse
556+
then i"\nTo allow this, the ${ref.symbol} should be declared with a @use annotation."
557+
else if !ref.isType then i"\nYou could try to abstract the capabilities referred to by $c in a capset variable."
558+
else ""
553559
report.error(
554-
em"""$what $c leaks into capture scope of ${ownerStr(ref.symbol.owner)}.
555-
|To allow this, the ${ref.symbol} should be declared with a @use annotation""", pos)
560+
em"$what $c leaks into capture scope of ${ownerStr(ref.symbol.owner)}.$mitigation",
561+
pos)
556562
case _ =>
557563

558564
/** Include references captured by the called method in the current environment stack */
@@ -1785,7 +1791,7 @@ class CheckCaptures extends Recheck, SymTransformer:
17851791

17861792
override def checkInheritedTraitParameters: Boolean = false
17871793

1788-
/** Check that overrides don't change the @use or @consume status of their parameters */
1794+
/** Check that overrides don't change the @use, @consume, or @reserve status of their parameters */
17891795
override def additionalChecks(member: Symbol, other: Symbol)(using Context): Unit =
17901796
for
17911797
(params1, params2) <- member.rawParamss.lazyZip(other.rawParamss)

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,8 @@ class PlainPrinter(_ctx: Context) extends Printer {
379379
finally elideCapabilityCaps = saved
380380

381381
/** Print the annotation that are meant to be on the parameter symbol but was moved
382-
* to parameter types. Examples are `@use` and `@consume`. */
382+
* to parameter types. Examples are `@use` and `@consume`.
383+
*/
383384
protected def specialAnnotText(sym: ClassSymbol, tp: Type): Text =
384385
Str(s"@${sym.name} ").provided(tp.hasAnnotation(sym))
385386

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
22 | runOps(ops1) // error
2121
| ^^^^^^
2222
| Local reach capability ops* leaks into capture scope of method delayedRunOps2.
23-
| To allow this, the parameter ops should be declared with a @use annotation
23+
| You could try to abstract the capabilities referred to by ops* in a capset variable.
2424
-- Error: tests/neg-custom-args/captures/delayedRunops.scala:21:16 -----------------------------------------------------
2525
21 | val ops1: List[() => Unit] = ops // error
2626
| ^^^^^^^^^^^^^^^^

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
11 | ops.foreach: op => // error
1010
| ^
1111
| Local reach capability ops* leaks into capture scope of method runOpsAlt.
12-
| To allow this, the parameter ops should be declared with a @use annotation
12+
| You could try to abstract the capabilities referred to by ops* in a capset variable.
1313
12 | op()

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
10 | val io = x.unbox // error: local reach capability {x*} leaks
33
| ^^^^^^^
44
| Local reach capability x.unbox* leaks into capture scope of method foo.
5-
| To allow this, the parameter x should be declared with a @use annotation
5+
| You could try to abstract the capabilities referred to by x.unbox* in a capset variable.
66
-- Error: tests/neg-custom-args/captures/i21442.scala:18:14 ------------------------------------------------------------
77
18 | val io = x1.unbox // error
88
| ^^^^^^^^
99
| Local reach capability x* leaks into capture scope of method bar.
10-
| To allow this, the parameter x should be declared with a @use annotation
10+
| You could try to abstract the capabilities referred to by x* in a capset variable.
1111
-- Error: tests/neg-custom-args/captures/i21442.scala:17:10 ------------------------------------------------------------
1212
17 | val x1: Boxed[IO^] = x // error
1313
| ^^^^^^^^^^
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
-- Error: tests/neg-custom-args/captures/i23303.scala:6:36 -------------------------------------------------------------
22
6 | def execute: Unit = ops.foreach(f => f()) // error
33
| ^^^^^^^^
4-
| Local reach capability Runner.this.ops* leaks into capture scope of class Runner.
5-
| To allow this, the value ops should be declared with a @use annotation
4+
| Local reach capability Runner.this.ops* leaks into capture scope of class Runner.
5+
| You could try to abstract the capabilities referred to by Runner.this.ops* in a capset variable.
66
-- Error: tests/neg-custom-args/captures/i23303.scala:9:22 -------------------------------------------------------------
77
9 | () => ops.foreach(f => f()) // error
88
| ^^^^^^^^
99
| Local reach capability ops* leaks into capture scope of method Runner2.
10-
| To allow this, the parameter ops should be declared with a @use annotation
10+
| You could try to abstract the capabilities referred to by ops* in a capset variable.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
24 | var x: () ->{xs*} Unit = ys.head // error
33
| ^^^^^^^
44
| Local reach capability ops* leaks into capture scope of method localReach3.
5-
| To allow this, the parameter ops should be declared with a @use annotation
5+
| You could try to abstract the capabilities referred to by ops* in a capset variable.
66
-- Error: tests/neg-custom-args/captures/localReaches.scala:27:11 ------------------------------------------------------
77
27 | x = ys.head // error
88
| ^^^^^^^
99
| Local reach capability ops* leaks into capture scope of method localReach3.
10-
| To allow this, the parameter ops should be declared with a @use annotation
10+
| You could try to abstract the capabilities referred to by ops* in a capset variable.
1111
-- Error: tests/neg-custom-args/captures/localReaches.scala:14:10 ------------------------------------------------------
1212
14 | val xs: List[() => Unit] = op :: Nil // error
1313
| ^^^^^^^^^^^^^^^^

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,4 @@
114114
39 | val next: () => Unit = cur.head // error
115115
| ^^^^^^^^
116116
| Local reach capability xs* leaks into capture scope of method runAll2.
117-
| To allow this, the parameter xs should be declared with a @use annotation
117+
| You could try to abstract the capabilities referred to by xs* in a capset variable.

tests/neg-custom-args/captures/unsound-reach-6.check

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
7 | println(xs.head) // error
1717
| ^^^^^^^
1818
| Local reach capability xs* leaks into capture scope of method f.
19-
| To allow this, the parameter xs should be declared with a @use annotation
19+
| You could try to abstract the capabilities referred to by xs* in a capset variable.
2020
-- Error: tests/neg-custom-args/captures/unsound-reach-6.scala:11:14 ---------------------------------------------------
2121
11 | val z = f(ys) // error @consume failure
2222
| ^^
2323
| Local reach capability ys* leaks into capture scope of method test.
24-
| To allow this, the parameter ys should be declared with a @use annotation
24+
| You could try to abstract the capabilities referred to by ys* in a capset variable.
2525
-- Error: tests/neg-custom-args/captures/unsound-reach-6.scala:19:14 ---------------------------------------------------
2626
19 | val z = f(ys) // error @consume failure
2727
| ^^

tests/neg-custom-args/captures/use-capset.check

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,3 @@
1616
5 |private def g[C^] = (xs: List[Object^{C}]) => xs.head // error TODO: allow this
1717
| ^^^^^^^
1818
| Capture set parameter C leaks into capture scope of method g.
19-
| To allow this, the type C should be declared with a @use annotation

0 commit comments

Comments
 (0)