Skip to content

Commit 593872a

Browse files
committed
Handle CapsOf in more places
1 parent d9d1047 commit 593872a

File tree

5 files changed

+32
-3
lines changed

5 files changed

+32
-3
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ extension (tp: Type)
198198
|| tp.isRootCapability
199199
) && !tp.symbol.isOneOf(UnstableValueFlags)
200200
case tp: TypeRef =>
201-
tp.symbol.isAbstractOrParamType && tp.derivesFrom(defn.Caps_CapSet)
201+
tp.symbol.isType && tp.derivesFrom(defn.Caps_CapSet)
202202
case tp: TypeParamRef =>
203203
tp.derivesFrom(defn.Caps_CapSet)
204204
case AnnotatedType(parent, annot) =>

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

+2
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ trait CaptureRef extends TypeProxy, ValueType:
140140
case ReachCapability(x1) => x1.subsumes(y.stripReach)
141141
case x: TermRef => viaInfo(x.info)(subsumingRefs(_, y))
142142
case x: TermParamRef => subsumesExistentially(x, y)
143+
case x: TypeRef if x.symbol.info.derivesFrom(defn.Caps_CapSet) =>
144+
x.captureSetOfInfo.elems.exists(_.subsumes(y))
143145
case x: TypeRef => assumedContainsOf(x).contains(y)
144146
case _ => false
145147
end subsumes

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ object CheckCaptures:
132132
elem match
133133
case CapsOfApply(arg) =>
134134
def isLegalCapsOfArg =
135-
arg.symbol.isAbstractOrParamType && arg.symbol.info.derivesFrom(defn.Caps_CapSet)
135+
arg.symbol.isType && arg.symbol.info.derivesFrom(defn.Caps_CapSet)
136136
if !isLegalCapsOfArg then
137137
report.error(
138138
em"""$arg is not a legal prefix for `^` here,

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -4007,7 +4007,7 @@ object Types extends TypeUtils {
40074007
(compute(status, parent, theAcc) /: refs.elems) {
40084008
(s, ref) => ref.stripReach match
40094009
case tp: TermParamRef if tp.binder eq thisLambdaType => combine(s, CaptureDeps)
4010-
case _ => s
4010+
case tp => combine(s, compute(status, tp, theAcc))
40114011
}
40124012
case _ =>
40134013
if tp.annot.refersToParamOf(thisLambdaType) then TrueDeps
@@ -6077,6 +6077,8 @@ object Types extends TypeUtils {
60776077
case tp: CaptureRef =>
60786078
if tp.isTrackableRef then tp
60796079
else ensureTrackable(tp.underlying)
6080+
case tp: TypeAlias =>
6081+
ensureTrackable(tp.alias)
60806082
case _ =>
60816083
assert(false, i"not a trackable captureRef ref: $result, ${result.underlyingIterator.toList}")
60826084
ensureTrackable(result)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import caps.*
2+
3+
trait Foo extends Capability
4+
5+
trait CaptureSet:
6+
type C <: CapSet^
7+
8+
def capturePoly[C^](a: Foo^{C^}): Foo^{C^} = a
9+
def capturePoly2(c: CaptureSet)(a: Foo^{c.C^}): Foo^{c.C^} = a
10+
11+
def test =
12+
val x: Foo^ = ???
13+
val y: Foo^ = ???
14+
15+
object X extends CaptureSet:
16+
type C = CapSet^{x}
17+
18+
val z1: Foo^{X.C^} = x
19+
val z2: Foo^{X.C^} = y // error
20+
21+
val z3: Foo^{x} = capturePoly(x)
22+
val z4: Foo^{x} = capturePoly(y) // error
23+
24+
val z5: Foo^{x} = capturePoly2(X)(x)
25+
val z6: Foo^{x} = capturePoly2(X)(y) // error

0 commit comments

Comments
 (0)