@@ -237,8 +237,8 @@ extends tpd.TreeTraverser:
237
237
// Don't map capture sets, since that would implicitly normalize sets that
238
238
// are not well-formed.
239
239
t.derivedAnnotatedType(t3, ann)
240
- case _ =>
241
- mapOverFollowingAliases(t)
240
+ case t =>
241
+ normalizeCaptures( mapOverFollowingAliases(t) )
242
242
243
243
private def transformExplicitType (tp : Type , boxed : Boolean , mapRoots : Boolean )(using Context ): Type =
244
244
val tp1 = expandAliases(tp)
@@ -560,10 +560,8 @@ extends tpd.TreeTraverser:
560
560
false
561
561
}.showing(i " can have inferred capture $tp = $result" , capt)
562
562
563
- /** Add a capture set variable to `tp` if necessary, or maybe pull out
564
- * an embedded capture set variable from a part of `tp`.
565
- */
566
- def decorate (tp : Type , mapRoots : Boolean , addedSet : Type => CaptureSet )(using Context ): Type = tp match
563
+ /** Pull out an embedded capture set from a part of `tp` */
564
+ def normalizeCaptures (tp : Type )(using Context ): Type = tp match
567
565
case tp @ RefinedType (parent @ CapturingType (parent1, refs), rname, rinfo) =>
568
566
CapturingType (tp.derivedRefinedType(parent1, rname, rinfo), refs, parent.isBoxed)
569
567
case tp : RecType =>
@@ -575,33 +573,37 @@ extends tpd.TreeTraverser:
575
573
// by `mapInferred`. Hence if the underlying type admits capture variables
576
574
// a variable was already added, and the first case above would apply.
577
575
case AndType (tp1 @ CapturingType (parent1, refs1), tp2 @ CapturingType (parent2, refs2)) =>
578
- assert(refs1.elems.isEmpty)
579
- assert(refs2.elems.isEmpty)
580
576
assert(tp1.isBoxed == tp2.isBoxed)
581
577
CapturingType (AndType (parent1, parent2), refs1 ** refs2, tp1.isBoxed)
582
578
case tp @ OrType (tp1 @ CapturingType (parent1, refs1), tp2 @ CapturingType (parent2, refs2)) =>
583
- assert(refs1.elems.isEmpty)
584
- assert(refs2.elems.isEmpty)
585
579
assert(tp1.isBoxed == tp2.isBoxed)
586
580
CapturingType (OrType (parent1, parent2, tp.isSoft), refs1 ++ refs2, tp1.isBoxed)
587
581
case tp @ OrType (tp1 @ CapturingType (parent1, refs1), tp2) =>
588
582
CapturingType (OrType (parent1, tp2, tp.isSoft), refs1, tp1.isBoxed)
589
583
case tp @ OrType (tp1, tp2 @ CapturingType (parent2, refs2)) =>
590
584
CapturingType (OrType (tp1, parent2, tp.isSoft), refs2, tp2.isBoxed)
591
585
case tp : LazyRef =>
592
- decorate(tp.ref, mapRoots, addedSet)
593
- case _ if tp.typeSymbol == defn.FromJavaObjectSymbol =>
586
+ normalizeCaptures(tp.ref)
587
+ case _ =>
588
+ tp
589
+
590
+ /** Add a capture set variable to `tp` if necessary, or maybe pull out
591
+ * an embedded capture set variable from a part of `tp`.
592
+ */
593
+ def decorate (tp : Type , mapRoots : Boolean , addedSet : Type => CaptureSet )(using Context ): Type =
594
+ if tp.typeSymbol == defn.FromJavaObjectSymbol then
594
595
// For capture checking, we assume Object from Java is the same as Any
595
596
tp
596
- case _ =>
597
+ else
597
598
def maybeAdd (target : Type , fallback : Type ) =
598
599
if needsVariable(target) then CapturingType (target, addedSet(target))
599
600
else fallback
600
- val tp1 = tp.dealiasKeepAnnots
601
- if tp1 ne tp then
601
+ val tp0 = normalizeCaptures(tp)
602
+ val tp1 = tp0.dealiasKeepAnnots
603
+ if tp1 ne tp0 then
602
604
val tp2 = transformExplicitType(tp1, boxed = false , mapRoots)
603
- maybeAdd(tp2, if tp2 ne tp1 then tp2 else tp )
604
- else maybeAdd(tp, tp )
605
+ maybeAdd(tp2, if tp2 ne tp1 then tp2 else tp0 )
606
+ else maybeAdd(tp0, tp0 )
605
607
606
608
/** Add a capture set variable to `tp` if necessary, or maybe pull out
607
609
* an embedded capture set variable from a part of `tp`.
0 commit comments