Skip to content

Commit 65e83a8

Browse files
committed
[CSSimplify] Increase impact of a generic argument mismatch if mismatch is contextual
If generic arguments mismatch ends up being recorded on the result of the chain or `try` expression it means that there is a contextual conversion mismatch. For optional conversions the solver currently generates a disjunction with two choices - bind and optional-to-optional conversion which is anchored on the contextual expression. If we can get a fix recorded there that would result in a better diagnostic. It's only possible for optional-to-optional choice because it doesn't bind the variable immediately, so we need to downgrade direct fixes to prevent `bind` choice from considered better.
1 parent 71a8d8d commit 65e83a8

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

include/swift/Sema/CSFix.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,11 @@ class ConstraintFix {
560560
return false;
561561
}
562562

563+
template <typename E>
564+
bool directlyAt() const {
565+
return getLocator()->directlyAt<E>();
566+
}
567+
563568
void print(llvm::raw_ostream &Out) const;
564569

565570
SWIFT_DEBUG_DUMP;

lib/Sema/CSSimplify.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15696,6 +15696,22 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
1569615696
unsigned impact = 1;
1569715697
if (type1->isMarkerExistential() || type2->isMarkerExistential())
1569815698
++impact;
15699+
15700+
// If generic arguments mismatch ends up being recorded on the result
15701+
// of the chain or a try expression it means that there is a contextual
15702+
// conversion mismatch.
15703+
//
15704+
// For optional conversions the solver currently generates a disjunction
15705+
// with two choices - bind and optional-to-optional conversion which is
15706+
// anchored on the contextual expression. If we can get a fix recorded
15707+
// there that would result in a better diagnostic. It's only possible
15708+
// for optional-to-optional choice because it doesn't bind the
15709+
// variable immediately, so we need to downgrade direct fixes to prevent
15710+
// `bind` choice from considered better.
15711+
if (fix->directlyAt<OptionalEvaluationExpr>() ||
15712+
fix->directlyAt<AnyTryExpr>())
15713+
impact += 2;
15714+
1569915715
return recordFix(fix, impact) ? SolutionKind::Error : SolutionKind::Solved;
1570015716
}
1570115717

0 commit comments

Comments
 (0)