@@ -154,21 +154,6 @@ object root:
154154 override def eql (that : Annotation ) = that match
155155 case Annot (kind) => this .kind eq kind
156156 case _ => false
157-
158- /** Special treatment of `SubstBindingMaps` which can change the binder of
159- * Result instances
160- */
161- override def mapWith (tm : TypeMap )(using Context ) = kind match
162- case Kind .Result (binder) => tm match
163- case tm : Substituters .SubstBindingMap [MethodType ] @ unchecked if tm.from eq binder =>
164- derivedAnnotation(tm.to)
165- case tm : Substituters .SubstBindingsMap =>
166- var i = 0
167- while i < tm.from.length && (tm.from(i) ne binder) do i += 1
168- if i < tm.from.length then derivedAnnotation(tm.to(i).asInstanceOf [MethodType ])
169- else this
170- case _ => this
171- case _ => this
172157 end Annot
173158
174159 def cap (using Context ): TermRef = defn.captureRoot.termRef
@@ -222,8 +207,7 @@ object root:
222207 override def apply (t : Type ) =
223208 if variance <= 0 then t
224209 else t match
225- case t : CaptureRef if t.isCap =>
226- Fresh (origin)
210+ case root(_) => assert(false )
227211 case t @ CapturingType (parent : TypeRef , _) if parent.symbol == defn.Caps_CapSet =>
228212 t
229213 case t @ CapturingType (_, _) =>
@@ -237,6 +221,11 @@ object root:
237221 case _ =>
238222 mapFollowingAliases(t)
239223
224+ override def mapCapability (c : CaptureRef , deep : Boolean ): CaptureRef = c match
225+ case c : CaptureRef if c.isCap => Fresh (origin)
226+ case root(_) => c
227+ case _ => super .mapCapability(c, deep)
228+
240229 override def fuse (next : BiTypeMap )(using Context ) = next match
241230 case next : Inverse => assert(false ); Some (IdentityTypeMap )
242231 case _ => None
@@ -245,13 +234,14 @@ object root:
245234
246235 class Inverse extends BiTypeMap , FollowAliasesMap :
247236 def apply (t : Type ): Type = t match
248- case t @ Fresh (_) => cap
237+ case root (_) => assert( false )
249238 case t @ CapturingType (_, refs) => mapOver(t)
250239 case _ => mapFollowingAliases(t)
251240
252- override def fuse (next : BiTypeMap )(using Context ) = next match
253- case next : CapToFresh => assert(false ); Some (IdentityTypeMap )
254- case _ => None
241+ override def mapCapability (c : CaptureRef , deep : Boolean ): CaptureRef = c match
242+ case c @ Fresh (_) => cap
243+ case root(_) => c
244+ case _ => super .mapCapability(c, deep)
255245
256246 def inverse = thisMap
257247 override def toString = thisMap.toString + " .inverse"
@@ -283,9 +273,7 @@ object root:
283273 var localBinders : SimpleIdentitySet [MethodType ] = SimpleIdentitySet .empty
284274
285275 def apply (t : Type ): Type = t match
286- case t @ Result (binder) =>
287- if localBinders.contains(binder) then t // keep bound references
288- else seen.getOrElseUpdate(t.annot, Fresh (origin)) // map free references to Fresh()
276+ case root(_) => assert(false )
289277 case t : MethodType =>
290278 // skip parameters
291279 val saved = localBinders
@@ -298,6 +286,14 @@ object root:
298286 case _ =>
299287 mapOver(t)
300288
289+ override def mapCapability (c : CaptureRef , deep : Boolean ) = c match
290+ case t @ Result (binder) =>
291+ if localBinders.contains(binder) then t // keep bound references
292+ else seen.getOrElseUpdate(t.annot, Fresh (origin)) // map free references to Fresh()
293+ case root(_) => c
294+ case _ => super .mapCapability(c, deep)
295+ end subst
296+
301297 subst(tp)
302298 end resultToFresh
303299
@@ -320,15 +316,7 @@ object root:
320316 private val seen = EqHashMap [CaptureRef , Result ]()
321317
322318 def apply (t : Type ) = t match
323- case t : CaptureRef if t.isCapOrFresh =>
324- if variance > 0 then
325- seen.getOrElseUpdate(t, Result (mt))
326- else
327- if variance == 0 then
328- fail(em """ $tp captures the root capability `cap` in invariant position.
329- |This capability cannot be converted to an existential in the result type of a function. """ )
330- // we accept variance < 0, and leave the cap as it is
331- super .mapOver(t)
319+ case root(_) => assert(false )
332320 case defn.FunctionNOf (args, res, contextual) if t.typeSymbol.name.isImpureFunction =>
333321 if variance > 0 then
334322 super .mapOver:
@@ -337,26 +325,48 @@ object root:
337325 else mapOver(t)
338326 case _ =>
339327 mapOver(t)
328+
329+ override def mapCapability (c : CaptureRef , deep : Boolean ) = c match
330+ case c : CaptureRef if c.isCapOrFresh =>
331+ if variance > 0 then
332+ seen.getOrElseUpdate(c, Result (mt))
333+ else
334+ if variance == 0 then
335+ fail(em """ $tp captures the root capability `cap` in invariant position.
336+ |This capability cannot be converted to an existential in the result type of a function. """ )
337+ // we accept variance < 0, and leave the cap as it is
338+ c
339+ case root(_) => c
340+ case _ =>
341+ super .mapCapability(c, deep)
342+
340343 // .showing(i"mapcap $t = $result")
341344 override def toString = " toVar"
342345
343346 object inverse extends BiTypeMap :
344347 def apply (t : Type ) = t match
345- case t @ Result (`mt`) =>
348+ case root(_) => assert(false )
349+ case _ => mapOver(t)
350+ def inverse = toVar.this
351+ override def toString = " toVar.inverse"
352+
353+ override def mapCapability (c : CaptureRef , deep : Boolean ) = c match
354+ case c @ Result (`mt`) =>
346355 // do a reverse getOrElseUpdate on `seen` to produce the
347356 // `Fresh` assosicated with `t`
348357 val it = seen.iterator
349358 var ref : CaptureRef | Null = null
350359 while it.hasNext && ref == null do
351360 val (k, v) = it.next
352- if v.annot eq t.annot then ref = k
361+ if v eq c then ref = k
353362 if ref == null then
354363 ref = Fresh (Origin .Unknown )
355- seen(ref) = t
364+ seen(ref) = c
356365 ref
357- case _ => mapOver(t)
358- def inverse = toVar.this
359- override def toString = " toVar.inverse"
366+ case root(_) => c
367+ case _ =>
368+ super .mapCapability(c, deep)
369+ end inverse
360370 end toVar
361371
362372 toVar(tp)
0 commit comments