[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
This commit is contained in:
Pavel Yaskevich
2020-12-01 20:35:34 -08:00
parent 887464b7b6
commit 5ebba42268
2 changed files with 47 additions and 0 deletions

View File

@@ -77,6 +77,25 @@ bool ConstraintSystem::PotentialBindings::isPotentiallyIncomplete() const {
return true;
}
// If there is a `bind param` constraint associated with
// current type variable, result should be aware of that
// fact. Binding set might be incomplete until
// this constraint is resolved, because we currently don't
// look-through constraints expect to `subtype` to try and
// find related bindings.
// This only affects type variable that appears one the
// right-hand side of the `bind param` constraint and
// represents result type of the closure body, because
// left-hand side gets types from overload choices.
if (llvm::any_of(
EquivalentTo,
[&](const std::pair<TypeVariableType *, Constraint *> &equivalence) {
auto *constraint = equivalence.second;
return constraint->getKind() == ConstraintKind::BindParam &&
constraint->getSecondType()->isEqual(TypeVar);
}))
return true;
return false;
}

View File

@@ -0,0 +1,28 @@
// RUN: %target-typecheck-verify-swift
@propertyWrapper
@dynamicMemberLookup
struct Binding<Value> {
var wrappedValue: Value
init(get: @escaping () -> Value, set: @escaping (Value) -> Void) {
self.wrappedValue = get()
}
subscript<Subject>(dynamicMember keyPath: WritableKeyPath<Value, Subject>) -> Binding<Subject> {
get { fatalError() }
}
}
class S {
var value: String = ""
var buffer: String? = nil
var body: String {
let binding = Binding(
get: { self.buffer ?? self.value },
set: { self.buffer = $0 }
)
return binding.wrappedValue
}
}