Skip to content

Commit 143931a

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. (cherry picked from commit 65e83a8)
1 parent 9ae7a75 commit 143931a

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
@@ -15693,6 +15693,22 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
1569315693
unsigned impact = 1;
1569415694
if (type1->isMarkerExistential() || type2->isMarkerExistential())
1569515695
++impact;
15696+
15697+
// If generic arguments mismatch ends up being recorded on the result
15698+
// of the chain or a try expression it means that there is a contextual
15699+
// conversion mismatch.
15700+
//
15701+
// For optional conversions the solver currently generates a disjunction
15702+
// with two choices - bind and optional-to-optional conversion which is
15703+
// anchored on the contextual expression. If we can get a fix recorded
15704+
// there that would result in a better diagnostic. It's only possible
15705+
// for optional-to-optional choice because it doesn't bind the
15706+
// variable immediately, so we need to downgrade direct fixes to prevent
15707+
// `bind` choice from considered better.
15708+
if (fix->directlyAt<OptionalEvaluationExpr>() ||
15709+
fix->directlyAt<AnyTryExpr>())
15710+
impact += 2;
15711+
1569615712
return recordFix(fix, impact) ? SolutionKind::Error : SolutionKind::Solved;
1569715713
}
1569815714

0 commit comments

Comments
 (0)