Skip to content

Commit 59908ee

Browse files
committed
[CSGen] Suppress favoring in presence of non-disfavored variadic generic overloads
Since this type of early favoring checks number of arguments and matches labels it would always favor non-variadic overloads which is incorrect.
1 parent 60c579c commit 59908ee

File tree

3 files changed

+32
-7
lines changed

3 files changed

+32
-7
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6268,11 +6268,16 @@ Type isPlaceholderVar(PatternBindingDecl *PB);
62686268
/// Dump an anchor node for a constraint locator or contextual type.
62696269
void dumpAnchor(ASTNode anchor, SourceManager *SM, raw_ostream &out);
62706270

6271+
bool isPackExpansionType(Type type);
6272+
62716273
/// Check whether the type is a tuple consisting of a single unlabeled element
62726274
/// of \c PackExpansionType or a type variable that represents a pack expansion
62736275
/// type.
62746276
bool isSingleUnlabeledPackExpansionTuple(Type type);
62756277

6278+
bool containsPackExpansionType(ArrayRef<AnyFunctionType::Param> params);
6279+
bool containsPackExpansionType(TupleType *tuple);
6280+
62766281
/// \returns null if \c type is not a single unlabeled pack expansion tuple.
62776282
Type getPatternTypeOfSingleUnlabeledPackExpansionTuple(Type type);
62786283

lib/Sema/CSGen.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,25 @@ namespace {
592592
// Find the argument type.
593593
size_t nArgs = expr->getArgs()->size();
594594
auto fnExpr = expr->getFn();
595-
595+
596+
auto mustConsiderVariadicGenericOverloads = [&](ValueDecl *overload) {
597+
if (overload->getAttrs().hasAttribute<DisfavoredOverloadAttr>())
598+
return false;
599+
600+
auto genericContext = overload->getAsGenericContext();
601+
if (!genericContext)
602+
return false;
603+
604+
auto *GPL = genericContext->getGenericParams();
605+
if (!GPL)
606+
return false;
607+
608+
return llvm::any_of(GPL->getParams(),
609+
[&](const GenericTypeParamDecl *GP) {
610+
return GP->isParameterPack();
611+
});
612+
};
613+
596614
// Check to ensure that we have an OverloadedDeclRef, and that we're not
597615
// favoring multiple overload constraints. (Otherwise, in this case
598616
// favoring is useless.
@@ -630,8 +648,9 @@ namespace {
630648
return nArgs == paramCount.first ||
631649
nArgs == paramCount.second;
632650
};
633-
634-
favorCallOverloads(expr, CS, isFavoredDecl);
651+
652+
favorCallOverloads(expr, CS, isFavoredDecl,
653+
mustConsiderVariadicGenericOverloads);
635654
}
636655

637656
// We only currently perform favoring for unary args.
@@ -655,7 +674,8 @@ namespace {
655674
// inside an extension context, since any archetypes in the parameter
656675
// list could match exactly.
657676
auto mustConsider = [&](ValueDecl *value) -> bool {
658-
return isa<ProtocolDecl>(value->getDeclContext());
677+
return isa<ProtocolDecl>(value->getDeclContext()) ||
678+
mustConsiderVariadicGenericOverloads(value);
659679
};
660680

661681
favorCallOverloads(expr, CS, isFavoredDecl, mustConsider);

lib/Sema/CSSimplify.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ static llvm::Optional<unsigned> scoreParamAndArgNameTypo(StringRef paramName,
117117
return dist;
118118
}
119119

120-
static bool isPackExpansionType(Type type) {
120+
bool constraints::isPackExpansionType(Type type) {
121121
if (type->is<PackExpansionType>())
122122
return true;
123123

@@ -152,13 +152,13 @@ Type constraints::getPatternTypeOfSingleUnlabeledPackExpansionTuple(Type type) {
152152
return {};
153153
}
154154

155-
static bool containsPackExpansionType(ArrayRef<AnyFunctionType::Param> params) {
155+
bool constraints::containsPackExpansionType(ArrayRef<AnyFunctionType::Param> params) {
156156
return llvm::any_of(params, [&](const auto &param) {
157157
return isPackExpansionType(param.getPlainType());
158158
});
159159
}
160160

161-
static bool containsPackExpansionType(TupleType *tuple) {
161+
bool constraints::containsPackExpansionType(TupleType *tuple) {
162162
return llvm::any_of(tuple->getElements(), [&](const auto &elt) {
163163
return isPackExpansionType(elt.getType());
164164
});

0 commit comments

Comments
 (0)