Skip to content

Commit 75f9c6e

Browse files
committed
Fix setup of CapSet arguments.
These arguments tell the whole truth; they cannot possibly be decorated with another capture set. So we should not add a capture set variable.
1 parent 3dfd762 commit 75f9c6e

File tree

4 files changed

+25
-5
lines changed

4 files changed

+25
-5
lines changed

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,9 @@ extension (tp: Type)
264264
def boxed(using Context): Type = tp.dealias match
265265
case tp @ CapturingType(parent, refs) if !tp.isBoxed && !refs.isAlwaysEmpty =>
266266
tp.annot match
267-
case ann: CaptureAnnotation => AnnotatedType(parent, ann.boxedAnnot)
267+
case ann: CaptureAnnotation =>
268+
assert(!parent.derivesFrom(defn.Caps_CapSet))
269+
AnnotatedType(parent, ann.boxedAnnot)
268270
case ann => tp
269271
case tp: RealTypeBounds =>
270272
tp.derivedTypeBounds(tp.lo.boxed, tp.hi.boxed)

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

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ object CapturingType:
3333
* boxing status is the same or if A is boxed.
3434
*/
3535
def apply(parent: Type, refs: CaptureSet, boxed: Boolean = false)(using Context): Type =
36+
assert(!boxed || !parent.derivesFrom(defn.Caps_CapSet))
3637
if refs.isAlwaysEmpty && !refs.keepAlways then parent
3738
else parent match
3839
case parent @ CapturingType(parent1, refs1) if boxed || !parent.isBoxed =>

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

+7-4
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,10 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
134134
private def box(tp: Type)(using Context): Type =
135135
def recur(tp: Type): Type = tp.dealiasKeepAnnotsAndOpaques match
136136
case tp @ CapturingType(parent, refs) =>
137-
if tp.isBoxed then tp else tp.boxed
137+
if tp.isBoxed || parent.derivesFrom(defn.Caps_CapSet) then tp
138+
else tp.boxed
138139
case tp @ AnnotatedType(parent, ann) =>
139-
if ann.symbol.isRetains
140+
if ann.symbol.isRetains && !parent.derivesFrom(defn.Caps_CapSet)
140141
then CapturingType(parent, ann.tree.toCaptureSet, boxed = true)
141142
else tp.derivedAnnotatedType(box(parent), ann)
142143
case tp1 @ AppliedType(tycon, args) if defn.isNonRefinedFunction(tp1) =>
@@ -605,8 +606,10 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
605606
!refs.isEmpty
606607
case tp: (TypeRef | AppliedType) =>
607608
val sym = tp.typeSymbol
608-
if sym.isClass then !sym.isPureClass
609-
else instanceCanBeImpure(tp.superType)
609+
if sym.isClass
610+
then !sym.isPureClass
611+
else !tp.derivesFrom(defn.Caps_CapSet) // CapSet arguments don't get other capture set variables added
612+
&& instanceCanBeImpure(tp.superType)
610613
case tp: (RefinedOrRecType | MatchType) =>
611614
instanceCanBeImpure(tp.underlying)
612615
case tp: AndType =>

tests/pos/polycap.scala

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import language.experimental.captureChecking
2+
3+
class Source[+T, Cap^]
4+
5+
def completed[T, Cap^](result: T): Source[T, Cap] =
6+
//val fut = new Source[T, Cap]()
7+
val fut2 = new Source[T, Cap]()
8+
fut2: Source[T, Cap]
9+
10+
11+
12+
13+
14+

0 commit comments

Comments
 (0)