@@ -111,21 +111,23 @@ object Applications {
111111 }
112112
113113 def productSelectorTypes (tp : Type , errorPos : SrcPos )(using Context ): List [Type ] = {
114- def tupleSelectors (n : Int , tp : Type ): List [Type ] = {
115- val sel = extractorMemberType(tp, nme.selectorName(n), errorPos)
116- // extractorMemberType will return NoType if this is the tail of tuple with an unknown tail
117- // such as `Int *: T` where `T <: Tuple`.
118- if (sel.exists) sel :: tupleSelectors(n + 1 , tp) else Nil
119- }
120- def genTupleSelectors (n : Int , tp : Type ): List [Type ] = tp match {
121- case tp : AppliedType if ! defn.isTupleClass(tp.tycon.typeSymbol) && tp.derivesFrom(defn.PairClass ) =>
122- val List (head, tail) = tp.args
123- head :: genTupleSelectors(n, tail)
124- case _ => tupleSelectors(n, tp)
125- }
126- genTupleSelectors(0 , tp)
114+ val sels = for (n <- Iterator .from(0 )) yield extractorMemberType(tp, nme.selectorName(n), errorPos)
115+ sels.takeWhile(_.exists).toList
127116 }
128117
118+ def tupleComponentTypes (tp : Type )(using Context ): List [Type ] =
119+ tp.widenExpr.dealias match
120+ case tp : AppliedType =>
121+ if defn.isTupleClass(tp.tycon.typeSymbol) then
122+ tp.args
123+ else if tp.tycon.derivesFrom(defn.PairClass ) then
124+ val List (head, tail) = tp.args
125+ head :: tupleComponentTypes(tail)
126+ else
127+ Nil
128+ case _ =>
129+ Nil
130+
129131 def productArity (tp : Type , errorPos : SrcPos = NoSourcePosition )(using Context ): Int =
130132 if (defn.isProductSubType(tp)) productSelectorTypes(tp, errorPos).size else - 1
131133
0 commit comments