@@ -67,6 +67,21 @@ object Applications {
6767 unapplySeqTypeElemTp(productSelectorTypes(tp, errorPos).last).exists
6868 }
6969
70+ /** Does `tp` fit the "product-seq match" conditions for a `NonEmptyTuple` as
71+ * an unapply result type for a pattern with `numArgs` subpatterns?
72+ * This is the case if (1) `tp` derives from `NonEmptyTuple`.
73+ * (2) `tp.tupleElementTypes` exists.
74+ * (3) `tp.tupleElementTypes.last` conforms to Seq match
75+ */
76+ def isNonEmptyTupleSeqMatch (tp : Type , numArgs : Int , errorPos : SrcPos = NoSourcePosition )(using Context ): Boolean = {
77+ tp.derivesFrom(defn.NonEmptyTupleClass )
78+ && tp.tupleElementTypes.exists { elemTypes =>
79+ val arity = elemTypes.size
80+ arity > 0 && arity <= numArgs + 1 &&
81+ unapplySeqTypeElemTp(elemTypes.last).exists
82+ }
83+ }
84+
7085 /** Does `tp` fit the "get match" conditions as an unapply result type?
7186 * This is the case of `tp` has a `get` member as well as a
7287 * parameterless `isEmpty` member of result type `Boolean`.
@@ -143,12 +158,17 @@ object Applications {
143158 }
144159 else tp :: Nil
145160
146- def productSeqSelectors (tp : Type , argsNum : Int , pos : SrcPos )(using Context ): List [Type ] = {
147- val selTps = productSelectorTypes(tp, pos)
148- val arity = selTps.length
149- val elemTp = unapplySeqTypeElemTp(selTps.last)
150- (0 until argsNum).map(i => if (i < arity - 1 ) selTps(i) else elemTp).toList
151- }
161+ def productSeqSelectors (tp : Type , argsNum : Int , pos : SrcPos )(using Context ): List [Type ] =
162+ seqSelectors(productSelectorTypes(tp, pos), argsNum)
163+
164+ def nonEmptyTupleSeqSelectors (tp : Type , argsNum : Int , pos : SrcPos )(using Context ): List [Type ] =
165+ seqSelectors(tp.tupleElementTypes.get, argsNum)
166+
167+ private def seqSelectors (selectorTypes : List [Type ], argsNum : Int )(using Context ): List [Type ] =
168+ val arity = selectorTypes.length
169+ val elemTp = unapplySeqTypeElemTp(selectorTypes.last)
170+ (0 until argsNum).map(i => if (i < arity - 1 ) selectorTypes(i) else elemTp).toList
171+ end seqSelectors
152172
153173 def unapplyArgs (unapplyResult : Type , unapplyFn : Tree , args : List [untpd.Tree ], pos : SrcPos )(using Context ): List [Type ] = {
154174 def getName (fn : Tree ): Name =
@@ -169,7 +189,7 @@ object Applications {
169189 val elemTp = unapplySeqTypeElemTp(tp)
170190 if (elemTp.exists) args.map(Function .const(elemTp))
171191 else if (isProductSeqMatch(tp, args.length, pos)) productSeqSelectors(tp, args.length, pos)
172- else if tp.derivesFrom(defn. NonEmptyTupleClass ) then foldApplyTupleType (tp)
192+ else if isNonEmptyTupleSeqMatch(tp, args.length, pos ) then nonEmptyTupleSeqSelectors (tp, args.length, pos )
173193 else fallback
174194 }
175195
0 commit comments