Skip to content

Commit 4abda8b

Browse files
committed
Refine subsumes rule; fix test
1 parent a8c624e commit 4abda8b

File tree

2 files changed

+28
-17
lines changed

2 files changed

+28
-17
lines changed

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

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,21 @@ trait CaptureRef extends TypeProxy, ValueType:
9393
final def invalidateCaches() =
9494
myCaptureSetRunId = NoRunId
9595

96-
/** x subsumes x
97-
* this subsumes this.f
96+
/** x subsumes x
97+
* x subsumes x.f
98+
* x =:= y ==> x subsumes y
9899
* x subsumes y ==> x* subsumes y, x subsumes y?
99100
* x subsumes y ==> x* subsumes y*, x? subsumes y?
100101
* x: x1.type /\ x1 subsumes y ==> x subsumes y
101-
* TODO: Document path cases
102+
* X = CapSet^cx, exists rx in cx, rx subsumes y ==> X subsumes y
103+
* Y = CapSet^cy, forall ry in cy, x subsumes ry ==> x subsumes Y
104+
* X: CapSet^c1...CapSet^c2, (CapSet^c1) subsumes y ==> X subsumes y
105+
* Y: CapSet^c1...CapSet^c2, x subsumes (CapSet^c2) ==> x subsumes Y
106+
* Contains[X, y] ==> X subsumes y
107+
*
108+
* TODO: Document cases with more comments.
102109
*/
103-
// import reporting.trace
104-
final def subsumes(y: CaptureRef)(using Context): Boolean = // trace.force(i"subsumes $this, $y"):
110+
final def subsumes(y: CaptureRef)(using Context): Boolean =
105111

106112
def subsumingRefs(x: Type, y: Type): Boolean = x match
107113
case x: CaptureRef => y match
@@ -136,11 +142,13 @@ trait CaptureRef extends TypeProxy, ValueType:
136142
case _ => false
137143
|| viaInfo(y.info)(subsumingRefs(this, _))
138144
case MaybeCapability(y1) => this.stripMaybe.subsumes(y1)
139-
case y: TypeRef if y.symbol.info.derivesFrom(defn.Caps_CapSet) =>
145+
case y: TypeRef if y.derivesFrom(defn.Caps_CapSet) =>
140146
y.info match
141-
case _: TypeAlias => y.captureSetOfInfo.elems.forall(this.subsumes)
142147
case TypeBounds(_, hi: CaptureRef) => this.subsumes(hi)
143148
case _ => y.captureSetOfInfo.elems.forall(this.subsumes)
149+
case AnnotatedType(parent, ann)
150+
if ann.symbol.isRetains && parent.derivesFrom(defn.Caps_CapSet) =>
151+
ann.tree.toCaptureSet.elems.forall(this.subsumes)
144152
case _ => false
145153
|| this.match
146154
case ReachCapability(x1) => x1.subsumes(y.stripReach)
@@ -149,8 +157,6 @@ trait CaptureRef extends TypeProxy, ValueType:
149157
case x: TypeRef if assumedContainsOf(x).contains(y) => true
150158
case x: TypeRef if x.derivesFrom(defn.Caps_CapSet) =>
151159
x.info match
152-
case _: TypeAlias =>
153-
x.captureSetOfInfo.elems.exists(_.subsumes(y))
154160
case TypeBounds(lo: CaptureRef, _) =>
155161
lo.subsumes(y)
156162
case _ =>

tests/pos-custom-args/captures/cc-poly-varargs.scala

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
1-
trait Cancellable
1+
abstract class Source[+T, Cap^]:
2+
def transformValuesWith[U](f: (T -> U)^{Cap^}): Source[U, Cap]^{this, f} = ???
23

3-
abstract class Source[+T, Cap^]
4-
5-
extension[T, Cap^](src: Source[T, Cap]^)
6-
def transformValuesWith[U](f: (T -> U)^{Cap^}): Source[U, Cap]^{src, f} = ???
4+
// TODO: The extension version of `transformValuesWith` doesn't work currently.
5+
// extension[T, Cap^](src: Source[T, Cap]^)
6+
// def transformValuesWith[U](f: (T -> U)^{Cap^}): Source[U, Cap]^{src, f} = ???
77

88
def race[T, Cap^](sources: Source[T, Cap]^{Cap^}*): Source[T, Cap]^{Cap^} = ???
99

10-
def either[T1, T2, Cap^](src1: Source[T1, Cap]^{Cap^}, src2: Source[T2, Cap]^{Cap^}): Source[Either[T1, T2], Cap]^{Cap^} =
10+
def either[T1, T2, Cap^](
11+
src1: Source[T1, Cap]^{Cap^},
12+
src2: Source[T2, Cap]^{Cap^}): Source[Either[T1, T2], Cap]^{Cap^} =
1113
val left = src1.transformValuesWith(Left(_))
1214
val right = src2.transformValuesWith(Right(_))
13-
race(left, right)
14-
15+
race[Either[T1, T2], Cap](left, right)
16+
// An explcit type argument is required here because the second argument is
17+
// inferred as `CapSet^{Cap^}` instead of `Cap`.
18+
// Although `CapSet^{Cap^}` subsums `Cap` in terms of capture set,
19+
// `Cap` is not a subtype of `CapSet^{Cap^}` in terms of subtyping.
1520

1621

1722

0 commit comments

Comments
 (0)