@@ -259,9 +259,17 @@ extension (tp: Type)
259259 * occurrences of cap are allowed in instance types of type variables.
260260 */
261261 def withReachCaptures (ref : Type )(using Context ): Type =
262- object narrowCaps extends TypeMap :
262+ class CheckContraCaps extends TypeTraverser :
263263 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)
264271
272+ object narrowCaps extends TypeMap :
265273 /** Has the variance been flipped at this point? */
266274 private var isFlipped : Boolean = false
267275
@@ -270,12 +278,8 @@ extension (tp: Type)
270278 try
271279 if variance <= 0 then isFlipped = true
272280 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)
279283 case _ => t match
280284 case t @ CapturingType (p, cs) =>
281285 t.derivedCapturingType(apply(p), cs) // don't map capture set variables
@@ -284,12 +288,14 @@ extension (tp: Type)
284288 finally isFlipped = saved
285289 ref match
286290 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)
289295 if tp1 ne tp then capt.println(i " narrow $tp of $ref to $tp1" )
290296 tp1
291297 else
292- capt.println(i " cannot narrow $tp of $ref to $tp1 " )
298+ capt.println(i " cannot narrow $tp of $ref" )
293299 tp
294300 case _ =>
295301 tp
0 commit comments