mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
28
test/Constraints/rdar71858936.swift
Normal file
28
test/Constraints/rdar71858936.swift
Normal 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user