@@ -117,11 +117,47 @@ static bool isArithmeticOperator(ValueDecl *decl) {
117
117
return decl->isOperator () && decl->getBaseIdentifier ().isArithmeticOperator ();
118
118
}
119
119
120
+ // / Generic choices are supported only if they are not complex enough
121
+ // / that would they'd require solving to figure out whether they are a
122
+ // / potential match or not.
123
+ static bool isSupportedGenericOverloadChoice (ValueDecl *decl,
124
+ GenericFunctionType *choiceType) {
125
+ // Same type requirements cannot be handled because each
126
+ // candidate-parameter pair is (currently) considered in isolation.
127
+ if (llvm::any_of (choiceType->getRequirements (), [](const Requirement &req) {
128
+ switch (req.getKind ()) {
129
+ case RequirementKind::SameType:
130
+ case RequirementKind::SameShape:
131
+ return true ;
132
+
133
+ case RequirementKind::Conformance:
134
+ case RequirementKind::Superclass:
135
+ case RequirementKind::Layout:
136
+ return false ;
137
+ }
138
+ }))
139
+ return false ;
140
+
141
+ // If there are no same-type requirements, allow signatures
142
+ // that use only concrete types or generic parameters directly
143
+ // in their parameter positions i.e. `(T, Int)`.
144
+
145
+ auto *paramList = getParameterList (decl);
146
+ if (!paramList)
147
+ return false ;
148
+
149
+ return llvm::all_of (paramList->getArray (), [](const ParamDecl *P) {
150
+ auto paramType = P->getInterfaceType ();
151
+ return paramType->is <GenericTypeParamType>() ||
152
+ !paramType->hasTypeParameter ();
153
+ });
154
+ }
155
+
120
156
static bool isSupportedDisjunction (Constraint *disjunction) {
121
157
auto choices = disjunction->getNestedConstraints ();
122
158
123
- if (isSupportedOperator (disjunction))
124
- return true ;
159
+ if (isOperatorDisjunction (disjunction))
160
+ return isSupportedOperator (disjunction) ;
125
161
126
162
if (auto *ctor = dyn_cast_or_null<ConstructorDecl>(
127
163
getOverloadChoiceDecl (choices.front ()))) {
@@ -130,7 +166,7 @@ static bool isSupportedDisjunction(Constraint *disjunction) {
130
166
}
131
167
132
168
// Non-operator disjunctions are supported only if they don't
133
- // have any generic choices.
169
+ // have any complex generic choices.
134
170
return llvm::all_of (choices, [&](Constraint *choice) {
135
171
if (choice->isDisabled ())
136
172
return true ;
@@ -144,7 +180,18 @@ static bool isSupportedDisjunction(Constraint *disjunction) {
144
180
if (decl->isImplicitlyUnwrappedOptional ())
145
181
return false ;
146
182
147
- return decl->getInterfaceType ()->is <FunctionType>();
183
+ auto choiceType = decl->getInterfaceType ()->getAs <AnyFunctionType>();
184
+ if (!choiceType || choiceType->hasError ())
185
+ return false ;
186
+
187
+ // Non-generic choices are always supported.
188
+ if (choiceType->is <FunctionType>())
189
+ return true ;
190
+
191
+ if (auto *genericFn = choiceType->getAs <GenericFunctionType>())
192
+ return isSupportedGenericOverloadChoice (decl, genericFn);
193
+
194
+ return false ;
148
195
}
149
196
150
197
return false ;
0 commit comments