@@ -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,13 +716,23 @@ object Capabilities:
703716 (this eq y)
704717 || this .match
705718 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+
706725 vs.ifNotSeen(this )(x.hiddenSet.elems.exists(_.subsumes(y)))
707726 || x.acceptsLevelOf(y)
708727 && ( y.tryClassifyAs(x.hiddenSet.classifier)
709728 || { capt.println(i " $y cannot be classified as $x" ); false }
710729 )
711730 && canAddHidden
712731 && 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+ }*/ )
713736 case x : ResultCap =>
714737 val result = y match
715738 case y : ResultCap => vs.unify(x, y)
0 commit comments