Skip to content

Commit 67101ca

Browse files
committed
Handle tracked class parameters
The current handling of class type refinements is unsound. We cannot simply use a variable for the capture set of a class argument. What we need to do instead is treat class arguments as tracked. In this commit we at least allow explicitly declared tracked arguments. This needed two modifications: - Don't additionally add a capture set for tracked arguments - Handle the case where a capture reference is of a singleton type which is another capture reference. As a next step we should treat all class arguments as implicitly tracked.
1 parent ba63208 commit 67101ca

File tree

3 files changed

+17
-3
lines changed

3 files changed

+17
-3
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ sealed abstract class CaptureSet extends Showable:
147147
* this subsumes this.f
148148
* x subsumes y ==> x* subsumes y, x subsumes y?
149149
* x subsumes y ==> x* subsumes y*, x? subsumes y?
150+
* x: x1.type /\ x1 subsumes y ==> x subsumes y
150151
*/
151152
extension (x: CaptureRef)
152153
private def subsumes(y: CaptureRef)(using Context): Boolean =
@@ -158,6 +159,10 @@ sealed abstract class CaptureSet extends Showable:
158159
case _ => false
159160
|| x.match
160161
case ReachCapability(x1) => x1.subsumes(y.stripReach)
162+
case x: TermRef =>
163+
x.info match
164+
case x1: CaptureRef => x1.subsumes(y)
165+
case _ => false
161166
case _ => false
162167

163168
/** {x} <:< this where <:< is subcapturing, but treating all variables

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
196196
case cls: ClassSymbol
197197
if !defn.isFunctionClass(cls) && cls.is(CaptureChecked) =>
198198
cls.paramGetters.foldLeft(tp) { (core, getter) =>
199-
if atPhase(thisPhase.next)(getter.termRef.isTracked) then
199+
if atPhase(thisPhase.next)(getter.termRef.isTracked)
200+
&& !getter.is(Tracked)
201+
then
200202
val getterType =
201203
mapInferred(refine = false)(tp.memberInfo(getter)).strippedDealias
202204
RefinedType(core, getter.name,

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6162,8 +6162,15 @@ object Types extends TypeUtils {
61626162
def inverse: BiTypeMap
61636163

61646164
/** A restriction of this map to a function on tracked CaptureRefs */
6165-
def forward(ref: CaptureRef): CaptureRef = this(ref) match
6166-
case result: CaptureRef if result.isTrackableRef => result
6165+
def forward(ref: CaptureRef): CaptureRef =
6166+
val result = this(ref)
6167+
def ensureTrackable(tp: Type): CaptureRef = tp match
6168+
case tp: CaptureRef =>
6169+
if tp.isTrackableRef then tp
6170+
else ensureTrackable(tp.underlying)
6171+
case _ =>
6172+
assert(false, i"not a trackable captureRef ref: $result, ${result.underlyingIterator.toList}")
6173+
ensureTrackable(result)
61676174

61686175
/** A restriction of the inverse to a function on tracked CaptureRefs */
61696176
def backward(ref: CaptureRef): CaptureRef = inverse(ref) match

0 commit comments

Comments
 (0)