@@ -259,9 +259,17 @@ extension (tp: Type)
259
259
* occurrences of cap are allowed in instance types of type variables.
260
260
*/
261
261
def withReachCaptures (ref : Type )(using Context ): Type =
262
- object narrowCaps extends TypeMap :
262
+ class CheckContraCaps extends TypeTraverser :
263
263
var ok = true
264
+ def traverse (t : Type ): Unit =
265
+ if ok then
266
+ t match
267
+ case CapturingType (_, cs) if cs.isUniversal && variance <= 0 =>
268
+ ok = false
269
+ case _ =>
270
+ traverseChildren(t)
264
271
272
+ object narrowCaps extends TypeMap :
265
273
/** Has the variance been flipped at this point? */
266
274
private var isFlipped : Boolean = false
267
275
@@ -270,12 +278,8 @@ extension (tp: Type)
270
278
try
271
279
if variance <= 0 then isFlipped = true
272
280
t.dealias match
273
- case t1 @ CapturingType (p, cs) if cs.isUniversal =>
274
- if variance > 0 then
275
- t1.derivedCapturingType(apply(p), if isFlipped then cs else ref.reach.singletonCaptureSet)
276
- else
277
- ok = false
278
- t
281
+ case t1 @ CapturingType (p, cs) if cs.isUniversal && ! isFlipped =>
282
+ t1.derivedCapturingType(apply(p), ref.reach.singletonCaptureSet)
279
283
case _ => t match
280
284
case t @ CapturingType (p, cs) =>
281
285
t.derivedCapturingType(apply(p), cs) // don't map capture set variables
@@ -284,12 +288,14 @@ extension (tp: Type)
284
288
finally isFlipped = saved
285
289
ref match
286
290
case ref : CaptureRef if ref.isTrackableRef =>
287
- val tp1 = narrowCaps(tp)
288
- if narrowCaps.ok then
291
+ val checker = new CheckContraCaps
292
+ checker.traverse(tp)
293
+ if checker.ok then
294
+ val tp1 = narrowCaps(tp)
289
295
if tp1 ne tp then capt.println(i " narrow $tp of $ref to $tp1" )
290
296
tp1
291
297
else
292
- capt.println(i " cannot narrow $tp of $ref to $tp1 " )
298
+ capt.println(i " cannot narrow $tp of $ref" )
293
299
tp
294
300
case _ =>
295
301
tp
0 commit comments