Skip to content

Commit 523e6cc

Browse files
committed
[CSBindings] Adjust type variable viability condition
To be viable to be attempted next type variable should have at least one of the following: - a direct binding (from relational constraint); - a default (from `Defaultable` constraint); - a literal protocol conformance with a default type described by `LiteralConformsTo` constraint; Third condition was under-defined in 5.4 since it would consider _all_ protocol requirements, but that discounts the fact that only literal conformances could be binding sources, which leads to problems where type variables with incomplete set of bindings could be picked to be attempted. Resolves: rdar://77233864
1 parent b19c4d0 commit 523e6cc

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -577,8 +577,10 @@ ConstraintSystem::determineBestBindings() {
577577

578578
return bindings || !bindings.Defaults.empty() ||
579579
llvm::any_of(bindings.Protocols, [&](Constraint *constraint) {
580-
return bool(
581-
TypeChecker::getDefaultType(constraint->getProtocol(), DC));
580+
return constraint->getKind() ==
581+
ConstraintKind::LiteralConformsTo &&
582+
bool(TypeChecker::getDefaultType(constraint->getProtocol(),
583+
DC));
582584
});
583585
};
584586

test/Constraints/generics.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,3 +858,15 @@ func rdar56212087() {
858858

859859
setValue(foo("", ""), forKey: "") // Ok (T is inferred as a `String` instead of `Any?`)
860860
}
861+
862+
// rdar://77233864 - Ternary operator fails to deduce non-default literal type in SwiftUI preview
863+
func test_ternary_operator_with_regular_conformance_to_literal_protocol() {
864+
// Note that in this case `ExpressibleByIntegerLiteral` is a non-literal requirement
865+
func test<T: ExpressibleByIntegerLiteral>(_: T) -> T {
866+
fatalError()
867+
}
868+
869+
func bug(_: Float?) {}
870+
871+
bug(true ? test(0) : test(42)) // Ok - type is `CGFloat` for 0 and 42
872+
}

0 commit comments

Comments
 (0)