@@ -154,21 +154,6 @@ object root:
154
154
override def eql (that : Annotation ) = that match
155
155
case Annot (kind) => this .kind eq kind
156
156
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
172
157
end Annot
173
158
174
159
def cap (using Context ): TermRef = defn.captureRoot.termRef
@@ -222,8 +207,7 @@ object root:
222
207
override def apply (t : Type ) =
223
208
if variance <= 0 then t
224
209
else t match
225
- case t : CaptureRef if t.isCap =>
226
- Fresh (origin)
210
+ case root(_) => assert(false )
227
211
case t @ CapturingType (parent : TypeRef , _) if parent.symbol == defn.Caps_CapSet =>
228
212
t
229
213
case t @ CapturingType (_, _) =>
@@ -237,6 +221,11 @@ object root:
237
221
case _ =>
238
222
mapFollowingAliases(t)
239
223
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
+
240
229
override def fuse (next : BiTypeMap )(using Context ) = next match
241
230
case next : Inverse => assert(false ); Some (IdentityTypeMap )
242
231
case _ => None
@@ -245,13 +234,14 @@ object root:
245
234
246
235
class Inverse extends BiTypeMap , FollowAliasesMap :
247
236
def apply (t : Type ): Type = t match
248
- case t @ Fresh (_) => cap
237
+ case root (_) => assert( false )
249
238
case t @ CapturingType (_, refs) => mapOver(t)
250
239
case _ => mapFollowingAliases(t)
251
240
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)
255
245
256
246
def inverse = thisMap
257
247
override def toString = thisMap.toString + " .inverse"
@@ -283,9 +273,7 @@ object root:
283
273
var localBinders : SimpleIdentitySet [MethodType ] = SimpleIdentitySet .empty
284
274
285
275
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 )
289
277
case t : MethodType =>
290
278
// skip parameters
291
279
val saved = localBinders
@@ -298,6 +286,14 @@ object root:
298
286
case _ =>
299
287
mapOver(t)
300
288
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
+
301
297
subst(tp)
302
298
end resultToFresh
303
299
@@ -320,15 +316,7 @@ object root:
320
316
private val seen = EqHashMap [CaptureRef , Result ]()
321
317
322
318
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 )
332
320
case defn.FunctionNOf (args, res, contextual) if t.typeSymbol.name.isImpureFunction =>
333
321
if variance > 0 then
334
322
super .mapOver:
@@ -337,26 +325,48 @@ object root:
337
325
else mapOver(t)
338
326
case _ =>
339
327
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
+
340
343
// .showing(i"mapcap $t = $result")
341
344
override def toString = " toVar"
342
345
343
346
object inverse extends BiTypeMap :
344
347
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`) =>
346
355
// do a reverse getOrElseUpdate on `seen` to produce the
347
356
// `Fresh` assosicated with `t`
348
357
val it = seen.iterator
349
358
var ref : CaptureRef | Null = null
350
359
while it.hasNext && ref == null do
351
360
val (k, v) = it.next
352
- if v.annot eq t.annot then ref = k
361
+ if v eq c then ref = k
353
362
if ref == null then
354
363
ref = Fresh (Origin .Unknown )
355
- seen(ref) = t
364
+ seen(ref) = c
356
365
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
360
370
end toVar
361
371
362
372
toVar(tp)
0 commit comments