Skip to content

Commit 5132d55

Browse files
committed
Charge deep capture set for arguments to @consume parameters
1 parent 8d15e88 commit 5132d55

File tree

3 files changed

+20
-5
lines changed

3 files changed

+20
-5
lines changed

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -698,8 +698,8 @@ class CheckCaptures extends Recheck, SymTransformer:
698698
val freshenedFormal = Fresh.fromCap(formal)
699699
val argType = recheck(arg, freshenedFormal)
700700
.showing(i"recheck arg $arg vs $freshenedFormal", capt)
701-
if formal.hasAnnotation(defn.UseAnnot) then
702-
// The @use annotation is added to `formal` by `prepareFunction`
701+
if formal.hasAnnotation(defn.UseAnnot) || formal.hasAnnotation(defn.ConsumeAnnot) then
702+
// The @use and/or @consume annotation is added to `formal` by `prepareFunction`
703703
capt.println(i"charging deep capture set of $arg: ${argType} = ${argType.deepCaptureSet}")
704704
markFree(argType.deepCaptureSet, arg)
705705
if formal.containsCap then

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

+16-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,22 @@
66
-- Error: tests/neg-custom-args/captures/unsound-reach-6.scala:11:14 ---------------------------------------------------
77
11 | val z = f(ys) // error @consume failure
88
| ^^
9-
|Separation failure: argument to @consume parameter with type (ys : List[box () ->{io} Unit]) refers to non-local parameter ys
9+
| Local reach capability ys* leaks into capture scope of method test.
10+
| To allow this, the parameter ys should be declared with a @use annotation
11+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/unsound-reach-6.scala:13:22 ------------------------------
12+
13 | val _: () -> Unit = x // error
13+
| ^
14+
| Found: (x : () ->{ys*} Unit)
15+
| Required: () -> Unit
16+
|
17+
| longer explanation available when compiling with `-explain`
18+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/unsound-reach-6.scala:21:22 ------------------------------
19+
21 | val _: () -> Unit = x // error
20+
| ^
21+
| Found: (x : () ->{io} Unit)
22+
| Required: () -> Unit
23+
|
24+
| longer explanation available when compiling with `-explain`
1025
-- Error: tests/neg-custom-args/captures/unsound-reach-6.scala:19:14 ---------------------------------------------------
1126
19 | val z = f(ys) // error @consume failure
1227
| ^^

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ def test(io: IO^)(ys: List[() ->{io} Unit]) =
1010
val x = () =>
1111
val z = f(ys) // error @consume failure
1212
z()
13-
val _: () -> Unit = x // !!! ys* gets lost
13+
val _: () -> Unit = x // error
1414
()
1515

1616
def test(io: IO^) =
1717
def ys: List[() ->{io} Unit] = ???
1818
val x = () =>
1919
val z = f(ys) // error @consume failure
2020
z()
21-
val _: () -> Unit = x // !!! io gets lost
21+
val _: () -> Unit = x // error
2222
()
2323

2424

0 commit comments

Comments
 (0)