Skip to content

Commit

Permalink
Handle CapsOf in more places
Browse files Browse the repository at this point in the history
  • Loading branch information
noti0na1 committed Nov 1, 2024
1 parent d9d1047 commit 593872a
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 3 deletions.
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/cc/CaptureOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ extension (tp: Type)
|| tp.isRootCapability
) && !tp.symbol.isOneOf(UnstableValueFlags)
case tp: TypeRef =>
tp.symbol.isAbstractOrParamType && tp.derivesFrom(defn.Caps_CapSet)
tp.symbol.isType && tp.derivesFrom(defn.Caps_CapSet)
case tp: TypeParamRef =>
tp.derivesFrom(defn.Caps_CapSet)
case AnnotatedType(parent, annot) =>
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dotty/tools/dotc/cc/CaptureRef.scala
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ trait CaptureRef extends TypeProxy, ValueType:
case ReachCapability(x1) => x1.subsumes(y.stripReach)
case x: TermRef => viaInfo(x.info)(subsumingRefs(_, y))
case x: TermParamRef => subsumesExistentially(x, y)
case x: TypeRef if x.symbol.info.derivesFrom(defn.Caps_CapSet) =>
x.captureSetOfInfo.elems.exists(_.subsumes(y))
case x: TypeRef => assumedContainsOf(x).contains(y)
case _ => false
end subsumes
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ object CheckCaptures:
elem match
case CapsOfApply(arg) =>
def isLegalCapsOfArg =
arg.symbol.isAbstractOrParamType && arg.symbol.info.derivesFrom(defn.Caps_CapSet)
arg.symbol.isType && arg.symbol.info.derivesFrom(defn.Caps_CapSet)
if !isLegalCapsOfArg then
report.error(
em"""$arg is not a legal prefix for `^` here,
Expand Down
4 changes: 3 additions & 1 deletion compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4007,7 +4007,7 @@ object Types extends TypeUtils {
(compute(status, parent, theAcc) /: refs.elems) {
(s, ref) => ref.stripReach match
case tp: TermParamRef if tp.binder eq thisLambdaType => combine(s, CaptureDeps)
case _ => s
case tp => combine(s, compute(status, tp, theAcc))
}
case _ =>
if tp.annot.refersToParamOf(thisLambdaType) then TrueDeps
Expand Down Expand Up @@ -6077,6 +6077,8 @@ object Types extends TypeUtils {
case tp: CaptureRef =>
if tp.isTrackableRef then tp
else ensureTrackable(tp.underlying)
case tp: TypeAlias =>
ensureTrackable(tp.alias)
case _ =>
assert(false, i"not a trackable captureRef ref: $result, ${result.underlyingIterator.toList}")
ensureTrackable(result)
Expand Down
25 changes: 25 additions & 0 deletions tests/neg-custom-args/captures/capture-poly.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import caps.*

trait Foo extends Capability

trait CaptureSet:
type C <: CapSet^

def capturePoly[C^](a: Foo^{C^}): Foo^{C^} = a
def capturePoly2(c: CaptureSet)(a: Foo^{c.C^}): Foo^{c.C^} = a

def test =
val x: Foo^ = ???
val y: Foo^ = ???

object X extends CaptureSet:
type C = CapSet^{x}

val z1: Foo^{X.C^} = x
val z2: Foo^{X.C^} = y // error

val z3: Foo^{x} = capturePoly(x)
val z4: Foo^{x} = capturePoly(y) // error

val z5: Foo^{x} = capturePoly2(X)(x)
val z6: Foo^{x} = capturePoly2(X)(y) // error

0 comments on commit 593872a

Please sign in to comment.