Skip to content

Commit 5ebba42

Browse files
committed
[ConstraintSystem] Mark type variable representing closure parameter (in the body) as incomplete
Restore recently removed logic to mark type variable representing closure parameter used in the body of a closure as potentially incomplete to delay attempting it until `BindParam` is simplified. Resolves: rdar://problem/71858936
1 parent 887464b commit 5ebba42

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,25 @@ bool ConstraintSystem::PotentialBindings::isPotentiallyIncomplete() const {
7777
return true;
7878
}
7979

80+
// If there is a `bind param` constraint associated with
81+
// current type variable, result should be aware of that
82+
// fact. Binding set might be incomplete until
83+
// this constraint is resolved, because we currently don't
84+
// look-through constraints expect to `subtype` to try and
85+
// find related bindings.
86+
// This only affects type variable that appears one the
87+
// right-hand side of the `bind param` constraint and
88+
// represents result type of the closure body, because
89+
// left-hand side gets types from overload choices.
90+
if (llvm::any_of(
91+
EquivalentTo,
92+
[&](const std::pair<TypeVariableType *, Constraint *> &equivalence) {
93+
auto *constraint = equivalence.second;
94+
return constraint->getKind() == ConstraintKind::BindParam &&
95+
constraint->getSecondType()->isEqual(TypeVar);
96+
}))
97+
return true;
98+
8099
return false;
81100
}
82101

test/Constraints/rdar71858936.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
@propertyWrapper
4+
@dynamicMemberLookup
5+
struct Binding<Value> {
6+
var wrappedValue: Value
7+
8+
init(get: @escaping () -> Value, set: @escaping (Value) -> Void) {
9+
self.wrappedValue = get()
10+
}
11+
12+
subscript<Subject>(dynamicMember keyPath: WritableKeyPath<Value, Subject>) -> Binding<Subject> {
13+
get { fatalError() }
14+
}
15+
}
16+
17+
class S {
18+
var value: String = ""
19+
var buffer: String? = nil
20+
21+
var body: String {
22+
let binding = Binding(
23+
get: { self.buffer ?? self.value },
24+
set: { self.buffer = $0 }
25+
)
26+
return binding.wrappedValue
27+
}
28+
}

0 commit comments

Comments
 (0)