Skip to content

Commit 1b7795b

Browse files
committed
[CSFix] Allow diagnosing invalid references in key path with multiple solutions
If multiple solutions have exactly a fix for exactly the same invalid member reference in key path, let's diagnose that as if there is no ambiguity there.
1 parent a7524e5 commit 1b7795b

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

include/swift/Sema/CSFix.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,10 +1520,18 @@ class AllowInvalidRefInKeyPath final : public ConstraintFix {
15201520

15211521
bool diagnose(const Solution &solution, bool asNote = false) const override;
15221522

1523+
bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override;
1524+
15231525
/// Determine whether give reference requires a fix and produce one.
15241526
static AllowInvalidRefInKeyPath *
15251527
forRef(ConstraintSystem &cs, ValueDecl *member, ConstraintLocator *locator);
15261528

1529+
bool isEqual(const ConstraintFix *other) const;
1530+
1531+
static bool classof(const ConstraintFix *fix) {
1532+
return fix->getKind() == FixKind::AllowInvalidRefInKeyPath;
1533+
}
1534+
15271535
private:
15281536
static AllowInvalidRefInKeyPath *create(ConstraintSystem &cs, RefKind kind,
15291537
ValueDecl *member,

lib/Sema/CSFix.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,29 @@ bool AllowInvalidRefInKeyPath::diagnose(const Solution &solution,
953953
llvm_unreachable("covered switch");
954954
}
955955

956+
bool AllowInvalidRefInKeyPath::diagnoseForAmbiguity(
957+
CommonFixesArray commonFixes) const {
958+
auto *primaryFix =
959+
commonFixes.front().second->getAs<AllowInvalidRefInKeyPath>();
960+
assert(primaryFix);
961+
962+
if (llvm::all_of(
963+
commonFixes,
964+
[&primaryFix](
965+
const std::pair<const Solution *, const ConstraintFix *> &entry) {
966+
return primaryFix->isEqual(entry.second);
967+
})) {
968+
return diagnose(*commonFixes.front().first);
969+
}
970+
971+
return false;
972+
}
973+
974+
bool AllowInvalidRefInKeyPath::isEqual(const ConstraintFix *other) const {
975+
auto *refFix = other->getAs<AllowInvalidRefInKeyPath>();
976+
return refFix ? Kind == refFix->Kind && Member == refFix->Member : false;
977+
}
978+
956979
AllowInvalidRefInKeyPath *
957980
AllowInvalidRefInKeyPath::forRef(ConstraintSystem &cs, ValueDecl *member,
958981
ConstraintLocator *locator) {

0 commit comments

Comments
 (0)