Skip to content

Commit 5ede525

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. (cherry picked from commit 59908ee)
1 parent 96fc83f commit 5ede525

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
@@ -6169,8 +6169,13 @@ Type isPlaceholderVar(PatternBindingDecl *PB);
61696169
/// Dump an anchor node for a constraint locator or contextual type.
61706170
void dumpAnchor(ASTNode anchor, SourceManager *SM, raw_ostream &out);
61716171

6172+
bool isPackExpansionType(Type type);
6173+
61726174
bool isSingleUnlabeledPackExpansionTuple(Type type);
61736175

6176+
bool containsPackExpansionType(ArrayRef<AnyFunctionType::Param> params);
6177+
bool containsPackExpansionType(TupleType *tuple);
6178+
61746179
/// \returns null if \c type is not a single unlabeled pack expansion tuple.
61756180
Type getPatternTypeOfSingleUnlabeledPackExpansionTuple(Type type);
61766181

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

@@ -143,13 +143,13 @@ Type constraints::getPatternTypeOfSingleUnlabeledPackExpansionTuple(Type type) {
143143
return expansion->getPatternType();
144144
}
145145

146-
static bool containsPackExpansionType(ArrayRef<AnyFunctionType::Param> params) {
146+
bool constraints::containsPackExpansionType(ArrayRef<AnyFunctionType::Param> params) {
147147
return llvm::any_of(params, [&](const auto &param) {
148148
return isPackExpansionType(param.getPlainType());
149149
});
150150
}
151151

152-
static bool containsPackExpansionType(TupleType *tuple) {
152+
bool constraints::containsPackExpansionType(TupleType *tuple) {
153153
return llvm::any_of(tuple->getElements(), [&](const auto &elt) {
154154
return isPackExpansionType(elt.getType());
155155
});

0 commit comments

Comments
 (0)