@@ -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,12 +716,24 @@ object Capabilities:
703
716
(this eq y)
704
717
|| this .match
705
718
case x : FreshCap =>
719
+ def classifierOK =
720
+ if y.tryClassifyAs(x.hiddenSet.classifier) then true
721
+ else
722
+ capt.println(i " $y cannot be classified as $x" )
723
+ false
724
+
725
+ def prefixAllowsAddHidden : Boolean = x.prefix match
726
+ case NoPrefix | _ : ThisType => true
727
+ case _ if CCState .collapseFresh => true
728
+ case pre =>
729
+ capt.println(i " fresh not open $x, ${x.rootId}, $pre, ${x.ccOwner.skipWeakOwner.thisType}" )
730
+ false
731
+
706
732
vs.ifNotSeen(this )(x.hiddenSet.elems.exists(_.subsumes(y)))
707
733
|| x.acceptsLevelOf(y)
708
- && ( y.tryClassifyAs(x.hiddenSet.classifier)
709
- || { capt.println(i " $y cannot be classified as $x" ); false }
710
- )
734
+ && classifierOK
711
735
&& canAddHidden
736
+ && prefixAllowsAddHidden
712
737
&& vs.addHidden(x.hiddenSet, y)
713
738
case x : ResultCap =>
714
739
val result = y match
0 commit comments