@@ -148,10 +148,21 @@ object Capabilities:
148
148
* @param origin an indication where and why the FreshCap was created, used
149
149
* for diagnostics
150
150
*/
151
- case class FreshCap private (owner : Symbol , origin : Origin )(using @ constructorOnly ctx : Context ) extends RootCapability :
152
- val hiddenSet = CaptureSet .HiddenSet (owner, this : @ unchecked)
151
+ case class FreshCap (val prefix : Type )
152
+ (val owner : Symbol , val origin : Origin , origHidden : CaptureSet .HiddenSet | Null )
153
+ (using @ constructorOnly ctx : Context )
154
+ extends RootCapability :
155
+ val hiddenSet =
156
+ if origHidden == null then CaptureSet .HiddenSet (owner, this : @ unchecked)
157
+ else origHidden
153
158
// fails initialization check without the @unchecked
154
159
160
+ def derivedFreshCap (newPrefix : Type )(using Context ): FreshCap =
161
+ if newPrefix eq prefix then this
162
+ else FreshCap (newPrefix)(owner, origin, hiddenSet)
163
+
164
+ // assert(rootId != 10, i"fresh $prefix, ${ctx.owner}")
165
+
155
166
/** Is this fresh cap (definitely) classified? If that's the case, the
156
167
* classifier cannot be changed anymore.
157
168
* We need to distinguish `FreshCap`s that can still be classified from
@@ -198,8 +209,10 @@ object Capabilities:
198
209
i " a fresh root capability $classifierStr$originStr"
199
210
200
211
object FreshCap :
212
+ def apply (prefix : Type , origin : Origin )(using Context ): FreshCap =
213
+ new FreshCap (prefix)(ctx.owner, origin, null )
201
214
def apply (origin : Origin )(using Context ): FreshCap =
202
- FreshCap (ctx.owner, origin)
215
+ apply (ctx.owner.skipWeakOwner.thisType , origin)
203
216
204
217
/** A root capability associated with a function type. These are conceptually
205
218
* existentially quantified over the function's result type.
@@ -703,13 +716,23 @@ object Capabilities:
703
716
(this eq y)
704
717
|| this .match
705
718
case x : FreshCap =>
719
+ def prefixIsOpen (pre : Type ): Boolean = pre match
720
+ case NoPrefix | _ : ThisType => true
721
+ case pre : (TypeRef | AppliedType ) if pre.typeSymbol == x.ccOwner.skipWeakOwner => true
722
+ case pre : TypeProxy => prefixIsOpen(pre.superType)
723
+ case _ => false
724
+
706
725
vs.ifNotSeen(this )(x.hiddenSet.elems.exists(_.subsumes(y)))
707
726
|| x.acceptsLevelOf(y)
708
727
&& ( y.tryClassifyAs(x.hiddenSet.classifier)
709
728
|| { capt.println(i " $y cannot be classified as $x" ); false }
710
729
)
711
730
&& canAddHidden
712
731
&& vs.addHidden(x.hiddenSet, y)
732
+ && (prefixIsOpen(x.prefix)
733
+ /* || { println(i"closed fresh $x, ${x.rootId}, ${x.prefix}, ${x.ccOwner.skipWeakOwner.thisType}")
734
+ false
735
+ }*/ )
713
736
case x : ResultCap =>
714
737
val result = y match
715
738
case y : ResultCap => vs.unify(x, y)
0 commit comments