Skip to content

Commit ee0955a

Browse files
Merge pull request swiftlang#32841 from LucianoPAlmeida/SR-11184-keypath-application-iuo
[SR-11184] Delay binding of key path application projected result value
2 parents 08924c4 + 6d29e75 commit ee0955a

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,13 +547,28 @@ ConstraintSystem::getPotentialBindings(TypeVariableType *typeVar) const {
547547
}
548548
break;
549549
}
550+
case ConstraintKind::KeyPathApplication: {
551+
if (result.FullyBound)
552+
continue;
553+
554+
// If this variable is in the application projected result type, mark the
555+
// result as `FullyBound` to ensure we delay binding until we've bound
556+
// other type variables in the KeyPathApplication constraint. This ensures
557+
// we try to bind the key path type first, which can allow us to discover
558+
// additional bindings for the result type.
559+
SmallPtrSet<TypeVariableType *, 4> typeVars;
560+
findInferableTypeVars(simplifyType(constraint->getThirdType()), typeVars);
561+
if (typeVars.count(typeVar))
562+
result.FullyBound = true;
563+
564+
break;
565+
}
550566

551567
case ConstraintKind::BridgingConversion:
552568
case ConstraintKind::CheckedCast:
553569
case ConstraintKind::EscapableFunctionOf:
554570
case ConstraintKind::OpenedExistentialOf:
555571
case ConstraintKind::KeyPath:
556-
case ConstraintKind::KeyPathApplication:
557572
case ConstraintKind::FunctionInput:
558573
case ConstraintKind::FunctionResult:
559574
case ConstraintKind::OpaqueUnderlyingType:

test/Constraints/keypath.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,18 @@ func test_mismatch_with_contextual_optional_result() {
137137
let _ = A(B(), keyPath: \.arr)
138138
// expected-error@-1 {{key path value type '[Int]' cannot be converted to contextual type '[Int]?'}}
139139
}
140+
141+
// SR-11184
142+
class SR11184 {}
143+
144+
func fSR11184(_ c: SR11184!, _ kp: ReferenceWritableKeyPath<SR11184, String?>, _ str: String) {
145+
c[keyPath: kp] = str // OK
146+
c![keyPath: kp] = str // OK
147+
c?[keyPath: kp] = str // OK
148+
}
149+
150+
func fSR11184_O(_ c: SR11184!, _ kp: ReferenceWritableKeyPath<SR11184, String?>, _ str: String?) {
151+
c[keyPath: kp] = str // OK
152+
c![keyPath: kp] = str // OK
153+
c?[keyPath: kp] = str // OK
154+
}

0 commit comments

Comments
 (0)