Skip to content

Commit 9e97b8e

Browse files
committed
[CSOptimizer] Skip disfavored choices when they would result in a worse solution
1 parent e7b351d commit 9e97b8e

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6114,6 +6114,12 @@ class DisjunctionChoice {
61146114
return false;
61156115
}
61166116

6117+
bool isDisfavored() const {
6118+
if (auto *decl = getOverloadChoiceDecl(Choice))
6119+
return decl->getAttrs().hasAttribute<DisfavoredOverloadAttr>();
6120+
return false;
6121+
}
6122+
61176123
bool isBeginningOfPartition() const { return IsBeginningOfPartition; }
61186124

61196125
// FIXME: All three of the accessors below are required to support

lib/Sema/CSStep.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -635,9 +635,30 @@ bool DisjunctionStep::shouldSkip(const DisjunctionChoice &choice) const {
635635
if (choice.isDisabled())
636636
return skip("disabled");
637637

638-
// Skip unavailable overloads (unless in diagnostic mode).
639-
if (choice.isUnavailable() && !CS.shouldAttemptFixes())
640-
return skip("unavailable");
638+
if (!CS.shouldAttemptFixes()) {
639+
// Skip unavailable overloads.
640+
if (choice.isUnavailable())
641+
return skip("unavailable");
642+
643+
// Since the disfavored overloads are always located at the end of
644+
// the partition they could be skipped if there was at least one
645+
// valid solution for this partition already, because the solution
646+
// they produce would always be worse.
647+
if (choice.isDisfavored() && LastSolvedChoice) {
648+
bool canSkipDisfavored = true;
649+
auto &lastScore = LastSolvedChoice->second;
650+
for (unsigned i = 0, n = unsigned(SK_DisfavoredOverload) + 1; i != n;
651+
++i) {
652+
if (lastScore.Data[i] > 0) {
653+
canSkipDisfavored = false;
654+
break;
655+
}
656+
}
657+
658+
if (canSkipDisfavored)
659+
return skip("disfavored");
660+
}
661+
}
641662

642663
// If the solver already found a solution with a better overload choice that
643664
// can be unconditionally substituted by the current choice, skip the current

0 commit comments

Comments
 (0)