@@ -67,6 +67,21 @@ object Applications {
67
67
unapplySeqTypeElemTp(productSelectorTypes(tp, errorPos).last).exists
68
68
}
69
69
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
+
70
85
/** Does `tp` fit the "get match" conditions as an unapply result type?
71
86
* This is the case of `tp` has a `get` member as well as a
72
87
* parameterless `isEmpty` member of result type `Boolean`.
@@ -143,12 +158,17 @@ object Applications {
143
158
}
144
159
else tp :: Nil
145
160
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
152
172
153
173
def unapplyArgs (unapplyResult : Type , unapplyFn : Tree , args : List [untpd.Tree ], pos : SrcPos )(using Context ): List [Type ] = {
154
174
def getName (fn : Tree ): Name =
@@ -169,7 +189,7 @@ object Applications {
169
189
val elemTp = unapplySeqTypeElemTp(tp)
170
190
if (elemTp.exists) args.map(Function .const(elemTp))
171
191
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 )
173
193
else fallback
174
194
}
175
195
0 commit comments