@@ -628,6 +628,17 @@ class SpaceEngine(using Context) extends SpaceLogic {
628
628
Typ (ConstantType (Constant (())), true ) :: Nil
629
629
case tp if tp.classSymbol.isAllOf(JavaEnumTrait ) =>
630
630
tp.classSymbol.children.map(sym => Typ (sym.termRef, true ))
631
+
632
+ case tp @ AppliedType (tycon, targs) if tp.classSymbol.children.isEmpty && canDecompose(tycon) =>
633
+ // It might not obvious that it's OK to apply the type arguments of a parent type to child types.
634
+ // But this is guarded by `tp.classSymbol.children.isEmpty`,
635
+ // meaning we'll decompose to the same class, just not the same type.
636
+ // For instance, from i15029, `decompose((X | Y).Field[T]) = [X.Field[T], Y.Field[T]]`.
637
+ rec(tycon, Nil ).map(typ => Typ (tp.derivedAppliedType(typ.tp, targs)))
638
+
639
+ case tp : NamedType if canDecompose(tp.prefix) =>
640
+ rec(tp.prefix, Nil ).map(typ => Typ (tp.derivedSelect(typ.tp)))
641
+
631
642
case tp =>
632
643
def getChildren (sym : Symbol ): List [Symbol ] =
633
644
sym.children.flatMap { child =>
@@ -669,9 +680,11 @@ class SpaceEngine(using Context) extends SpaceLogic {
669
680
/** Abstract sealed types, or-types, Boolean and Java enums can be decomposed */
670
681
def canDecompose (tp : Type ): Boolean =
671
682
val res = tp.dealias match
683
+ case AppliedType (tycon, _) if canDecompose(tycon) => true
684
+ case tp : NamedType if canDecompose(tp.prefix) => true
672
685
case _ : SingletonType => false
673
686
case _ : OrType => true
674
- case and : AndType => canDecompose(and. tp1) || canDecompose(and. tp2)
687
+ case AndType (tp1, tp2) => canDecompose(tp1) || canDecompose(tp2)
675
688
case _ =>
676
689
val cls = tp.classSymbol
677
690
cls.is(Sealed )
0 commit comments