@@ -148,10 +148,21 @@ object Capabilities:
148148 * @param origin an indication where and why the FreshCap was created, used
149149 * for diagnostics
150150 */
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
153158 // fails initialization check without the @unchecked
154159
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+
155166 /** Is this fresh cap (definitely) classified? If that's the case, the
156167 * classifier cannot be changed anymore.
157168 * We need to distinguish `FreshCap`s that can still be classified from
@@ -198,8 +209,10 @@ object Capabilities:
198209 i " a fresh root capability $classifierStr$originStr"
199210
200211 object FreshCap :
212+ def apply (prefix : Type , origin : Origin )(using Context ): FreshCap =
213+ new FreshCap (prefix)(ctx.owner, origin, null )
201214 def apply (origin : Origin )(using Context ): FreshCap =
202- FreshCap (ctx.owner, origin)
215+ apply (ctx.owner.skipWeakOwner.thisType , origin)
203216
204217 /** A root capability associated with a function type. These are conceptually
205218 * existentially quantified over the function's result type.
@@ -703,12 +716,24 @@ object Capabilities:
703716 (this eq y)
704717 || this .match
705718 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+
706732 vs.ifNotSeen(this )(x.hiddenSet.elems.exists(_.subsumes(y)))
707733 || x.acceptsLevelOf(y)
708- && ( y.tryClassifyAs(x.hiddenSet.classifier)
709- || { capt.println(i " $y cannot be classified as $x" ); false }
710- )
734+ && classifierOK
711735 && canAddHidden
736+ && prefixAllowsAddHidden
712737 && vs.addHidden(x.hiddenSet, y)
713738 case x : ResultCap =>
714739 val result = y match
0 commit comments