Skip to content

Commit 0bca6ce

Browse files
[Sema] Do not skip key path last component/value equal constraint failure fix
1 parent 891e053 commit 0bca6ce

File tree

3 files changed

+41
-4
lines changed

3 files changed

+41
-4
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5973,6 +5973,9 @@ bool ArgumentMismatchFailure::diagnoseAsError() {
59735973
if (diagnoseTrailingClosureMismatch())
59745974
return true;
59755975

5976+
if (diagnoseKeyPathAsFunctionResultMismatch())
5977+
return true;
5978+
59765979
auto argType = getFromType();
59775980
auto paramType = getToType();
59785981

@@ -6227,6 +6230,31 @@ bool ArgumentMismatchFailure::diagnoseTrailingClosureMismatch() const {
62276230
return true;
62286231
}
62296232

6233+
bool ArgumentMismatchFailure::diagnoseKeyPathAsFunctionResultMismatch() const {
6234+
auto argExpr = getArgExpr();
6235+
if (!isExpr<KeyPathExpr>(argExpr))
6236+
return false;
6237+
6238+
auto argType = getFromType();
6239+
auto paramType = getToType();
6240+
6241+
if (!isKnownKeyPathType(argType))
6242+
return false;
6243+
6244+
auto kpType = argType->castTo<BoundGenericType>();
6245+
auto kpRootType = kpType->getGenericArgs()[0];
6246+
auto kpValueType = kpType->getGenericArgs()[1];
6247+
6248+
auto paramFnType = paramType->getAs<FunctionType>();
6249+
if (!(paramFnType && paramFnType->getNumParams() == 1 &&
6250+
paramFnType->getParams().front().getPlainType()->isEqual(kpRootType)))
6251+
return false;
6252+
6253+
emitDiagnostic(diag::expr_smart_keypath_value_covert_to_contextual_type,
6254+
kpValueType, paramFnType->getResult());
6255+
return true;
6256+
}
6257+
62306258
void ExpandArrayIntoVarargsFailure::tryDropArrayBracketsFixIt(
62316259
const Expr *anchor) const {
62326260
// If this is an array literal, offer to remove the brackets and pass the

lib/Sema/CSDiagnostics.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,6 +1909,12 @@ class ArgumentMismatchFailure : public ContextualFailure {
19091909
/// closures being passed to non-closure parameters.
19101910
bool diagnoseTrailingClosureMismatch() const;
19111911

1912+
/// Tailored key path as function diagnostics for argument mismatches where
1913+
/// argument is a keypath expression that has a root type that matches a
1914+
/// function parameter, but keypath value don't match the function parameter
1915+
/// result value.
1916+
bool diagnoseKeyPathAsFunctionResultMismatch() const;
1917+
19121918
protected:
19131919
/// \returns The position of the argument being diagnosed, starting at 1.
19141920
unsigned getArgPosition() const { return Info.getArgPosition(); }

lib/Sema/CSSimplify.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3795,10 +3795,13 @@ bool ConstraintSystem::repairFailures(
37953795
// there is going to be a constraint to match result of the
37963796
// member lookup to the generic parameter `V` of *KeyPath<R, V>
37973797
// type associated with key path expression, which we need to
3798-
// fix-up here.
3799-
if (isExpr<KeyPathExpr>(anchor)) {
3800-
auto *fnType = lhs->getAs<FunctionType>();
3801-
if (fnType && fnType->getResult()->isEqual(rhs))
3798+
// fix-up here unless last component has already a invalid type or
3799+
// instance fix recorded.
3800+
if (auto *kpExpr = getAsExpr<KeyPathExpr>(anchor)) {
3801+
auto i = kpExpr->getComponents().size() - 1;
3802+
auto lastCompLoc = getConstraintLocator(
3803+
locator.withPathElement(LocatorPathElt::KeyPathComponent(i)));
3804+
if (hasFixFor(lastCompLoc, FixKind::AllowTypeOrInstanceMember))
38023805
return true;
38033806

38043807
auto lastComponentType = lhs->lookThroughAllOptionalTypes();

0 commit comments

Comments
 (0)