@@ -628,6 +628,17 @@ class SpaceEngine(using Context) extends SpaceLogic {
628628 Typ (ConstantType (Constant (())), true ) :: Nil
629629 case tp if tp.classSymbol.isAllOf(JavaEnumTrait ) =>
630630 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+
631642 case tp =>
632643 def getChildren (sym : Symbol ): List [Symbol ] =
633644 sym.children.flatMap { child =>
@@ -669,9 +680,11 @@ class SpaceEngine(using Context) extends SpaceLogic {
669680 /** Abstract sealed types, or-types, Boolean and Java enums can be decomposed */
670681 def canDecompose (tp : Type ): Boolean =
671682 val res = tp.dealias match
683+ case AppliedType (tycon, _) if canDecompose(tycon) => true
684+ case tp : NamedType if canDecompose(tp.prefix) => true
672685 case _ : SingletonType => false
673686 case _ : OrType => true
674- case and : AndType => canDecompose(and. tp1) || canDecompose(and. tp2)
687+ case AndType (tp1, tp2) => canDecompose(tp1) || canDecompose(tp2)
675688 case _ =>
676689 val cls = tp.classSymbol
677690 cls.is(Sealed )
0 commit comments