Skip to content

Commit 6bdd534

Browse files
committed
[ConstraintSystem] Don't attempt property wrapper fixes for key path dynamic member lookup
If this is an attempt to fetch members through key path dynamic member lookup let's not try to apply any property wrapper related fixes because modifying base type would not change the result. Resolves: [SR-12520](https://bugs.swift.org/browse/SR-12520) Resolves: rdar://problem/61911108
1 parent a6fc9b3 commit 6bdd534

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2602,6 +2602,11 @@ static ConstraintFix *fixPropertyWrapperFailure(
26022602
ConstraintSystem &cs, Type baseTy, ConstraintLocator *locator,
26032603
llvm::function_ref<bool(SelectedOverload, VarDecl *, Type)> attemptFix,
26042604
Optional<Type> toType = None) {
2605+
// Don't attempt this fix if this is a key path dynamic member
2606+
// lookup which produced no results. Unwrapping or wrapping
2607+
// the base type is not going to produce desired results.
2608+
if (locator->isForKeyPathDynamicMemberLookup())
2609+
return nullptr;
26052610

26062611
Expr *baseExpr = nullptr;
26072612
if (auto *anchor = getAsExpr(locator->getAnchor())) {

test/Constraints/sr12520.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
@propertyWrapper
4+
@dynamicMemberLookup
5+
struct Binding<Value> {
6+
var wrappedValue: Value
7+
8+
subscript<Subject>(dynamicMember keyPath: WritableKeyPath<Value, Subject>) -> Binding<Subject> {
9+
get { fatalError() }
10+
}
11+
}
12+
13+
@propertyWrapper
14+
struct Wrapper<Value> {
15+
var wrappedValue: Value
16+
var projectedValue: Binding<Value>
17+
}
18+
19+
@dynamicMemberLookup class Foo {
20+
struct State {
21+
let value: Bool
22+
}
23+
24+
let currentState: State = State(value: false)
25+
26+
subscript<U>(dynamicMember keyPath: KeyPath<State, U>) -> U {
27+
return currentState[keyPath: keyPath]
28+
}
29+
}
30+
31+
struct Test {
32+
@Wrapper var foo: Foo
33+
34+
func test() {
35+
if foo.bar { // expected-error {{value of type 'Foo' has no dynamic member 'bar' using key path from root type 'Foo.State'}}
36+
}
37+
}
38+
}

0 commit comments

Comments
 (0)