[CS] Add decl-ref outer alternatives as non-favored options.

Given something like `max(1, 2)` inside a type that conforms to Sequence, this
allows the compiler to consider Swift.max as well as the two methods with that
name on Sequence.
This commit is contained in:
Huon Wilson
2018-04-19 17:26:54 +10:00
parent a108c5830a
commit 285c2a469b
7 changed files with 101 additions and 36 deletions

View File

@@ -1472,11 +1472,12 @@ void ConstraintSystem::addOverloadSet(Type boundType,
ArrayRef<OverloadChoice> choices,
DeclContext *useDC,
ConstraintLocator *locator,
OverloadChoice *favoredChoice) {
OverloadChoice *favoredChoice,
ArrayRef<OverloadChoice> outerAlternatives) {
assert(!choices.empty() && "Empty overload set");
// If there is a single choice, add the bind overload directly.
if (choices.size() == 1) {
if (choices.size() == 1 && outerAlternatives.empty()) {
addBindOverloadConstraint(boundType, choices.front(), locator, useDC);
return;
}
@@ -1512,7 +1513,26 @@ void ConstraintSystem::addOverloadSet(Type boundType,
useDC, locator));
}
addDisjunctionConstraint(overloads, locator, ForgetChoice, favoredChoice);
auto innerDisjunction = Constraint::createDisjunction(*this, overloads,
locator, ForgetChoice);
if (outerAlternatives.empty()) {
if (favoredChoice)
innerDisjunction->setFavored();
addUnsolvedConstraint(innerDisjunction);
return;
}
SmallVector<Constraint *, 4> outerConstraints;
outerConstraints.push_back(innerDisjunction);
innerDisjunction->setFavored();
for (auto choice : outerAlternatives) {
outerConstraints.push_back(Constraint::createBindOverload(
*this, boundType, choice,
useDC, locator));
}
addDisjunctionConstraint(outerConstraints, locator, ForgetChoice, favoredChoice);
}
/// If we're resolving an overload set with a decl that has special type