Skip to content

Commit 96441c1

Browse files
committed
[CSFix] Account for nested structural errors related to function argument mismatches
When it comes to contextual mismatches `ContextualType` is not guaranteed to be the last element in the patch since contextual type could be a function too which could would have `contextual type -> function argument` path.
1 parent c5ae6c9 commit 96441c1

File tree

2 files changed

+10
-6
lines changed

2 files changed

+10
-6
lines changed

lib/Sema/CSFix.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,15 @@ ContextualMismatch *ContextualMismatch::create(ConstraintSystem &cs, Type lhs,
262262
/// and the contextual type.
263263
static Optional<std::tuple<ContextualTypePurpose, Type, Type>>
264264
getStructuralTypeContext(ConstraintSystem &cs, ConstraintLocator *locator) {
265-
if (auto contextualType = cs.getContextualType(locator->getAnchor())) {
266-
if (auto *anchor = simplifyLocatorToAnchor(locator))
267-
return std::make_tuple(cs.getContextualTypePurpose(locator->getAnchor()),
268-
cs.getType(anchor),
269-
contextualType);
265+
if (locator->findLast<LocatorPathElt::ContextualType>()) {
266+
assert(locator->isLastElement<LocatorPathElt::ContextualType>() ||
267+
locator->isLastElement<LocatorPathElt::FunctionArgument>());
268+
269+
auto *anchor = locator->getAnchor();
270+
auto contextualType = cs.getContextualType(anchor);
271+
auto exprType = cs.getType(anchor);
272+
return std::make_tuple(cs.getContextualTypePurpose(anchor), exprType,
273+
contextualType);
270274
} else if (auto argApplyInfo = cs.getFunctionArgApplyInfo(locator)) {
271275
return std::make_tuple(CTP_CallArgument,
272276
argApplyInfo->getArgType(),

test/Constraints/sr10595.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ class B<Y> : Nested { // expected-error {{type 'B<Y>' does not conform to protoc
1515

1616
class C<M> {
1717
func cFunc(_ a: A<M>) {
18-
let function: (B<Int>, ReferenceWritableKeyPath<M, Int>) -> Void = a.f // expected-error {{cannot convert value of type '(_, WritableKeyPath<M, _.U>) -> ()' to specified type '(B<Int>, ReferenceWritableKeyPath<M, Int>) -> Void'}}
18+
let function: (B<Int>, ReferenceWritableKeyPath<M, Int>) -> Void = a.f // expected-error {{cannot convert value of type '(B<Int>, WritableKeyPath<M, B<Int>.U>) -> ()' to specified type '(B<Int>, ReferenceWritableKeyPath<M, Int>) -> Void'}}
1919
}
2020
}

0 commit comments

Comments
 (0)