Skip to content

Commit 7f39a94

Browse files
authored
Merge pull request swiftlang#23245 from xedin/further-simplify-add-overload-choice
[ConstraintSystem] Move "outer" candidates handling to `simplifyMembe…
2 parents 1eabe78 + 70c59af commit 7f39a94

File tree

3 files changed

+71
-45
lines changed

3 files changed

+71
-45
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4020,9 +4020,21 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
40204020

40214021
// If we found viable candidates, then we're done!
40224022
if (!result.ViableCandidates.empty()) {
4023-
addOverloadSet(memberTy, result.ViableCandidates, useDC, locator,
4024-
result.getFavoredChoice(), outerAlternatives);
4023+
llvm::SmallVector<Constraint *, 8> candidates;
4024+
generateConstraints(candidates, memberTy, result.ViableCandidates,
4025+
useDC, locator, result.getFavoredChoice());
40254026

4027+
if (!outerAlternatives.empty()) {
4028+
// If local scope has a single choice,
4029+
// it should always be preferred.
4030+
if (candidates.size() == 1)
4031+
candidates.front()->setFavored();
4032+
4033+
generateConstraints(candidates, memberTy, outerAlternatives,
4034+
useDC, locator);
4035+
}
4036+
4037+
addOverloadSet(candidates, locator);
40264038
return SolutionKind::Solved;
40274039
}
40284040

lib/Sema/ConstraintSystem.cpp

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,56 +1480,31 @@ void ConstraintSystem::addOverloadSet(Type boundType,
14801480
ArrayRef<OverloadChoice> choices,
14811481
DeclContext *useDC,
14821482
ConstraintLocator *locator,
1483-
OverloadChoice *favoredChoice,
1484-
ArrayRef<OverloadChoice> outerAlternatives) {
1485-
assert(!choices.empty() && "Empty overload set");
1486-
1483+
OverloadChoice *favoredChoice) {
14871484
// If there is a single choice, add the bind overload directly.
1488-
if (choices.size() == 1 && outerAlternatives.empty()) {
1485+
if (choices.size() == 1) {
14891486
addBindOverloadConstraint(boundType, choices.front(), locator, useDC);
14901487
return;
14911488
}
14921489

1493-
auto recordChoice = [&](SmallVectorImpl<Constraint *> &choices,
1494-
const OverloadChoice &choice,
1495-
bool isFavored = false) {
1496-
auto *constraint = Constraint::createBindOverload(*this, boundType, choice,
1497-
useDC, locator);
1498-
if (isFavored)
1499-
constraint->setFavored();
1500-
1501-
choices.push_back(constraint);
1502-
};
1503-
1504-
SmallVector<Constraint *, 4> overloads;
1505-
// As we do for other favored constraints, if a favored overload has been
1506-
// specified, let it be the first term in the disjunction.
1507-
if (favoredChoice) {
1508-
assert((!favoredChoice->isDecl() ||
1509-
!favoredChoice->getDecl()->getAttrs().isUnavailable(
1510-
getASTContext())) &&
1511-
"Cannot make unavailable decl favored!");
1512-
recordChoice(overloads, *favoredChoice, /*isFavored=*/true);
1513-
}
1514-
1515-
for (auto &choice : choices) {
1516-
if (favoredChoice && (favoredChoice == &choice))
1517-
continue;
1518-
1519-
recordChoice(overloads, choice);
1520-
}
1490+
SmallVector<Constraint *, 4> candidates;
1491+
generateConstraints(candidates, boundType, choices, useDC, locator,
1492+
favoredChoice);
1493+
// For an overload set (disjunction) from newly generated candidates.
1494+
addOverloadSet(candidates, locator);
1495+
}
15211496

1522-
if (!outerAlternatives.empty()) {
1523-
// If local scope has a single choice,
1524-
// it should always be preferred.
1525-
if (overloads.size() == 1)
1526-
overloads.front()->setFavored();
1497+
void ConstraintSystem::addOverloadSet(ArrayRef<Constraint *> choices,
1498+
ConstraintLocator *locator) {
1499+
assert(!choices.empty() && "Empty overload set");
15271500

1528-
for (auto &choice : outerAlternatives)
1529-
recordChoice(overloads, choice);
1501+
// If there is a single choice, attempt it right away.
1502+
if (choices.size() == 1) {
1503+
simplifyConstraint(*choices.front());
1504+
return;
15301505
}
15311506

1532-
addDisjunctionConstraint(overloads, locator, ForgetChoice);
1507+
addDisjunctionConstraint(choices, locator, ForgetChoice);
15331508
}
15341509

15351510
/// If we're resolving an overload set with a decl that has special type
@@ -2677,3 +2652,34 @@ Expr *constraints::getArgumentExpr(Expr *expr, unsigned index) {
26772652
assert(isa<TupleExpr>(argExpr));
26782653
return cast<TupleExpr>(argExpr)->getElement(index);
26792654
}
2655+
2656+
void ConstraintSystem::generateConstraints(
2657+
SmallVectorImpl<Constraint *> &constraints, Type type,
2658+
ArrayRef<OverloadChoice> choices, DeclContext *useDC,
2659+
ConstraintLocator *locator, OverloadChoice *favoredChoice) {
2660+
auto recordChoice = [&](SmallVectorImpl<Constraint *> &choices,
2661+
const OverloadChoice &choice,
2662+
bool isFavored = false) {
2663+
auto *constraint =
2664+
Constraint::createBindOverload(*this, type, choice, useDC, locator);
2665+
if (isFavored)
2666+
constraint->setFavored();
2667+
2668+
choices.push_back(constraint);
2669+
};
2670+
2671+
if (favoredChoice) {
2672+
assert((!favoredChoice->isDecl() ||
2673+
!favoredChoice->getDecl()->getAttrs().isUnavailable(
2674+
getASTContext())) &&
2675+
"Cannot make unavailable decl favored!");
2676+
recordChoice(constraints, *favoredChoice, /*isFavored=*/true);
2677+
}
2678+
2679+
for (const auto &choice : choices) {
2680+
if (favoredChoice && (favoredChoice == &choice))
2681+
continue;
2682+
2683+
recordChoice(constraints, choice);
2684+
}
2685+
}

lib/Sema/ConstraintSystem.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2417,8 +2417,10 @@ class ConstraintSystem {
24172417
/// sets.
24182418
void addOverloadSet(Type boundType, ArrayRef<OverloadChoice> choices,
24192419
DeclContext *useDC, ConstraintLocator *locator,
2420-
OverloadChoice *favored = nullptr,
2421-
ArrayRef<OverloadChoice> outerAlternatives = {});
2420+
OverloadChoice *favored = nullptr);
2421+
2422+
void addOverloadSet(ArrayRef<Constraint *> choices,
2423+
ConstraintLocator *locator);
24222424

24232425
/// Retrieve the allocator used by this constraint system.
24242426
llvm::BumpPtrAllocator &getAllocator() { return Allocator; }
@@ -2455,6 +2457,12 @@ class ConstraintSystem {
24552457
/// \returns a possibly-sanitized initializer, or null if an error occurred.
24562458
Type generateConstraints(Pattern *P, ConstraintLocatorBuilder locator);
24572459

2460+
/// Generate constraints for a given set of overload choices.
2461+
void generateConstraints(SmallVectorImpl<Constraint *> &constraints,
2462+
Type type, ArrayRef<OverloadChoice> choices,
2463+
DeclContext *useDC, ConstraintLocator *locator,
2464+
OverloadChoice *favoredChoice = nullptr);
2465+
24582466
/// Propagate constraints in an effort to enforce local
24592467
/// consistency to reduce the time to solve the system.
24602468
///

0 commit comments

Comments
 (0)