Skip to content

Commit c8a0a26

Browse files
committed
Fix concept of a parameter in which a path is rooted
pathRoot overshoots, selects `this` as the root of `this.param`.
1 parent bd4f772 commit c8a0a26

File tree

4 files changed

+22
-9
lines changed

4 files changed

+22
-9
lines changed

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -375,15 +375,18 @@ object Capabilities:
375375
case tp1: FreshCap => tp1.ccOwner
376376
case _ => NoSymbol
377377

378-
final def isParamPath(using Context): Boolean = this match
378+
final def paramPathRoot(using Context): Type = core match
379379
case tp1: NamedType =>
380380
tp1.prefix match
381381
case _: ThisType | NoPrefix =>
382-
tp1.symbol.is(Param) || tp1.symbol.is(ParamAccessor)
383-
case prefix: CoreCapability => prefix.isParamPath
384-
case _ => false
385-
case _: ParamRef => true
386-
case _ => false
382+
if tp1.symbol.is(Param) || tp1.symbol.is(ParamAccessor) then tp1
383+
else NoType
384+
case prefix: CoreCapability => prefix.paramPathRoot
385+
case _ => NoType
386+
case tp1: ParamRef => tp1
387+
case _ => NoType
388+
389+
final def isParamPath(using Context): Boolean = paramPathRoot.exists
387390

388391
final def ccOwner(using Context): Symbol = this match
389392
case self: ThisType => self.cls

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ class CheckCaptures extends Recheck, SymTransformer:
463463
def checkUseDeclared(c: Capability, env: Env, lastEnv: Env | Null) =
464464
if lastEnv != null && env.nestedClosure.exists && env.nestedClosure == lastEnv.owner then
465465
assert(ccConfig.deferredReaches) // access is from a nested closure under deferredReaches, so it's OK
466-
else c.pathRoot match
466+
else c.paramPathRoot match
467467
case ref: NamedType if !ref.symbol.isUseParam =>
468468
val what = if ref.isType then "Capture set parameter" else "Local reach capability"
469469
report.error(
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- Error: tests/neg-custom-args/captures/i23303.scala:6:36 -------------------------------------------------------------
2+
6 | def execute: Unit = ops.foreach(f => f()) // error
3+
| ^^^^^^^^
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
6+
-- Error: tests/neg-custom-args/captures/i23303.scala:9:22 -------------------------------------------------------------
7+
9 | () => ops.foreach(f => f()) // error
8+
| ^^^^^^^^
9+
| 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

tests/neg-custom-args/captures/i23303.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import language.experimental.captureChecking
22
import caps.use
33

4-
/*class Test:
4+
class Test:
55
class Runner(ops: List[() => Unit]):
66
def execute: Unit = ops.foreach(f => f()) // error
77

88
def Runner2(ops: List[() => Unit]) =
99
() => ops.foreach(f => f()) // error
10-
*/
10+
1111

1212
class Test2:
1313
class Runner(@use ops: List[() => Unit]):

0 commit comments

Comments
 (0)