Skip to content

Commit 6ae1a89

Browse files
committed
Work capture root determination into AsSeenFrom
1 parent 3d2a4cd commit 6ae1a89

File tree

4 files changed

+27
-13
lines changed

4 files changed

+27
-13
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ object CaptureSet:
511511
if elem.isRootCapability then res
512512
else res.orElse(addNewElems(elem.captureSetOfInfo.elems, origin))
513513
else
514-
//assert(id != 2, newElems)
514+
//assert(id != 19 || !elem.isLocalRootCapability, elem.asInstanceOf[TermRef].localRootOwner)
515515
elems += elem
516516
if elem.isGenericRootCapability then rootAddedHandler()
517517
newElemAddedHandler(elem)

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -382,11 +382,6 @@ class CheckCaptures extends Recheck, SymTransformer:
382382
tp1 = mapRoots(sym.localRoot.termRef, rootVar)(tp1)
383383
if tp1 ne tpw then
384384
ccSetup.println(i"INST local $sym: $tp, ${sym.localRoot} = $tp1")
385-
if sym.owner.isClass then
386-
val tp2 = CaptureRoot.instantiateOuterClassRoots(sym, pre, rootVar)(tp1)
387-
if tp2 ne tp1 then
388-
ccSetup.println(i"INST class $sym: $tp, ${sym.localRoot} in $pre = $tp2")
389-
tp1 = tp2
390385
if tpw eq tp1 then tp else tp1
391386
else
392387
tp

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import StdNames._
1111
import collection.mutable
1212
import ast.tpd._
1313
import reporting.trace
14-
import config.Printers.typr
14+
import config.Printers.{typr, ccSetup}
1515
import config.Feature
1616
import transform.SymUtils.*
1717
import typer.ProtoTypes._
@@ -93,13 +93,25 @@ object TypeOps:
9393
}
9494
}
9595

96+
def mapLocalRoot(tp: TermRef): Type =
97+
if tp.symbol.owner.isLocalDummy then
98+
val pre1 = toPrefix(pre, cls, tp.localRootOwner.asClass)
99+
if pre1 ne tp then pre1.captureSet.impliedRoot(tp)
100+
.showing(i"map local root $tp from $pre to $result", ccSetup)
101+
else tp
102+
else tp
103+
96104
trace.conditionally(track, s"asSeen ${tp.show} from (${pre.show}, ${cls.show})", show = true) { // !!! DEBUG
97105
// All cases except for ThisType are the same as in Map. Inlined for performance
98106
// TODO: generalize the inlining trick?
99107
tp match {
100108
case tp: NamedType =>
101109
val sym = tp.symbol
102-
if (sym.isStatic && !sym.maybeOwner.seesOpaques || (tp.prefix `eq` NoPrefix)) tp
110+
if sym.isStatic && !sym.maybeOwner.seesOpaques then tp
111+
else if tp.prefix `eq` NoPrefix then
112+
if tp.name == nme.LOCAL_CAPTURE_ROOT
113+
then mapLocalRoot(tp.asInstanceOf[TermRef])
114+
else tp
103115
else derivedSelect(tp, atVariance(variance max 0)(this(tp.prefix)))
104116
case tp: LambdaType =>
105117
mapOverLambda(tp) // special cased common case

tests/pos-custom-args/captures/test.scala

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
class C
22
type Cap = C^
33

4-
class Foo(x: Cap):
5-
this: Foo^{x} =>
4+
type Proc = () => Unit
5+
6+
class Ref(p: () => Unit):
7+
private var x: () => Unit = p
8+
def set(x: () ->{cap[Ref]} Unit): Unit = this.x = x
9+
def get: () => Unit = x
10+
11+
def test(c: () => Unit) =
12+
val p: () => Unit = ???
13+
val r = Ref(p)
14+
val x = r.get
15+
r.set(x)
616

7-
def test(c: Cap) =
8-
val x = Foo(c)
9-
()

0 commit comments

Comments
 (0)