20
20
#include " swift/AST/Type.h"
21
21
#include " swift/AST/Types.h"
22
22
#include " llvm/ADT/SmallVector.h"
23
+ #include < algorithm>
23
24
24
25
using namespace swift ;
25
26
@@ -104,4 +105,105 @@ bool TuplePackMatcher::match() {
104
105
}
105
106
106
107
return false ;
108
+ }
109
+
110
+ ParamPackMatcher::ParamPackMatcher (
111
+ ArrayRef<AnyFunctionType::Param> lhsParams,
112
+ ArrayRef<AnyFunctionType::Param> rhsParams,
113
+ ASTContext &ctx)
114
+ : lhsParams(lhsParams), rhsParams(rhsParams), ctx(ctx) {}
115
+
116
+ bool ParamPackMatcher::match () {
117
+ unsigned minLength = std::min (lhsParams.size (), rhsParams.size ());
118
+
119
+ // Consume the longest possible prefix where neither type in
120
+ // the pair is a pack expansion type.
121
+ unsigned prefixLength = 0 ;
122
+ for (unsigned i = 0 ; i < minLength; ++i) {
123
+ auto lhsParam = lhsParams[i];
124
+ auto rhsParam = rhsParams[i];
125
+
126
+ // FIXME: Check flags
127
+
128
+ auto lhsType = lhsParam.getPlainType ();
129
+ auto rhsType = rhsParam.getPlainType ();
130
+
131
+ if (lhsType->is <PackExpansionType>() ||
132
+ rhsType->is <PackExpansionType>()) {
133
+ break ;
134
+ }
135
+
136
+ // FIXME: Check flags
137
+
138
+ pairs.emplace_back (lhsType, rhsType, i);
139
+ ++prefixLength;
140
+ }
141
+
142
+ // Consume the longest possible suffix where neither type in
143
+ // the pair is a pack expansion type.
144
+ unsigned suffixLength = 0 ;
145
+ for (unsigned i = 0 ; i < minLength - prefixLength; ++i) {
146
+ auto lhsParam = lhsParams[lhsParams.size () - i - 1 ];
147
+ auto rhsParam = rhsParams[rhsParams.size () - i - 1 ];
148
+
149
+ // FIXME: Check flags
150
+
151
+ auto lhsType = lhsParam.getPlainType ();
152
+ auto rhsType = rhsParam.getPlainType ();
153
+
154
+ if (lhsType->is <PackExpansionType>() ||
155
+ rhsType->is <PackExpansionType>()) {
156
+ break ;
157
+ }
158
+
159
+ pairs.emplace_back (lhsType, rhsType, i);
160
+ ++suffixLength;
161
+ }
162
+
163
+ assert (prefixLength + suffixLength <= lhsParams.size ());
164
+ assert (prefixLength + suffixLength <= rhsParams.size ());
165
+
166
+ // Drop the consumed prefix and suffix from each list of types.
167
+ lhsParams = lhsParams.drop_front (prefixLength).drop_back (suffixLength);
168
+ rhsParams = rhsParams.drop_front (prefixLength).drop_back (suffixLength);
169
+
170
+ // If the left hand side is a single pack expansion type, bind it
171
+ // to what remains of the right hand side.
172
+ if (lhsParams.size () == 1 &&
173
+ lhsParams[0 ].getPlainType ()->is <PackExpansionType>()) {
174
+ SmallVector<Type, 2 > rhsTypes;
175
+ for (auto rhsParam : rhsParams) {
176
+ // FIXME: Check rhs flags
177
+ rhsTypes.push_back (rhsParam.getPlainType ());
178
+ }
179
+ auto rhs = PackType::get (ctx, rhsTypes);
180
+
181
+ // FIXME: Check lhs flags
182
+ pairs.emplace_back (lhsParams[0 ].getPlainType (), rhs, prefixLength);
183
+ return false ;
184
+ }
185
+
186
+ // If the right hand side is a single pack expansion type, bind it
187
+ // to what remains of the left hand side.
188
+ if (rhsParams.size () == 1 &&
189
+ rhsParams[0 ].getPlainType ()->is <PackExpansionType>()) {
190
+ SmallVector<Type, 2 > lhsTypes;
191
+ for (auto lhsParam : lhsParams) {
192
+ // FIXME: Check lhs flags
193
+ lhsTypes.push_back (lhsParam.getPlainType ());
194
+ }
195
+ auto lhs = PackType::get (ctx, lhsTypes);
196
+
197
+ // FIXME: Check rhs flags
198
+ pairs.emplace_back (lhs, rhsParams[0 ].getPlainType (), prefixLength);
199
+ return false ;
200
+ }
201
+
202
+ // Otherwise, all remaining possibilities are invalid:
203
+ // - Neither side has any pack expansions, and they have different lengths.
204
+ // - One side has a pack expansion but the other side is too short, eg
205
+ // {Int, T..., Float} vs {Int}.
206
+ // - The prefix and suffix are mismatched, so we're left with something
207
+ // like {T..., Int} vs {Float, U...}.
208
+ return true ;
107
209
}
0 commit comments