@@ -633,6 +633,17 @@ class SpaceEngine(using Context) extends SpaceLogic {
633633 Typ (ConstantType (Constant (())), true ) :: Nil
634634 case tp if tp.classSymbol.isAllOf(JavaEnumTrait ) =>
635635 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+
636647 case tp =>
637648 def getChildren (sym : Symbol ): List [Symbol ] =
638649 sym.children.flatMap { child =>
@@ -674,9 +685,11 @@ class SpaceEngine(using Context) extends SpaceLogic {
674685 /** Abstract sealed types, or-types, Boolean and Java enums can be decomposed */
675686 def canDecompose (tp : Type ): Boolean =
676687 val res = tp.dealias match
688+ case AppliedType (tycon, _) if canDecompose(tycon) => true
689+ case tp : NamedType if canDecompose(tp.prefix) => true
677690 case _ : SingletonType => false
678691 case _ : OrType => true
679- case and : AndType => canDecompose(and. tp1) || canDecompose(and. tp2)
692+ case AndType (tp1, tp2) => canDecompose(tp1) || canDecompose(tp2)
680693 case _ =>
681694 val cls = tp.classSymbol
682695 cls.is(Sealed )
0 commit comments