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