Skip to content

Commit c03d762

Browse files
committed
[ConstraintSystem] NFC: Clarify why upward propagation of literal conformances is ncessary at the moment
This is NFC because only literal protocols are tracked at the moment. Forward propagate (subtype -> supertype) only literal conformance requirements since that helps solver to infer more types at parameter positions. ```swift func foo<T: ExpressibleByStringLiteral>(_: String, _: T) -> T { fatalError() } func bar(_: Any?) {} func test() { bar(foo("", "")) } ``` If one of the literal arguments doesn't propagate its `ExpressibleByStringLiteral` conformance, we'd end up picking `T` with only one type `Any?` which is incorrect. This is not going to be necessary once bindings are filtered based of requirements placed on a type variable.
1 parent 0990fa9 commit c03d762

File tree

1 file changed

+27
-2
lines changed

1 file changed

+27
-2
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,33 @@ void ConstraintSystem::PotentialBindings::inferTransitiveBindings(
5656

5757
auto &bindings = relatedBindings->getSecond();
5858

59-
// Infer transitive protocol requirements.
60-
llvm::copy(bindings.Protocols, std::back_inserter(Protocols));
59+
// FIXME: This is a workaround necessary because solver doesn't filter
60+
// bindings based on protocol requirements placed on a type variable.
61+
//
62+
// Forward propagate (subtype -> supertype) only literal conformance
63+
// requirements since that helps solver to infer more types at
64+
// parameter positions.
65+
//
66+
// \code
67+
// func foo<T: ExpressibleByStringLiteral>(_: String, _: T) -> T {
68+
// fatalError()
69+
// }
70+
//
71+
// func bar(_: Any?) {}
72+
//
73+
// func test() {
74+
// bar(foo("", ""))
75+
// }
76+
// \endcode
77+
//
78+
// If one of the literal arguments doesn't propagate its
79+
// `ExpressibleByStringLiteral` conformance, we'd end up picking
80+
// `T` with only one type `Any?` which is incorrect.
81+
llvm::copy_if(bindings.Protocols, std::back_inserter(Protocols),
82+
[](const Constraint *protocol) {
83+
return protocol->getKind() ==
84+
ConstraintKind::LiteralConformsTo;
85+
});
6186

6287
// Infer transitive defaults.
6388
llvm::copy(bindings.Defaults, std::back_inserter(Defaults));

0 commit comments

Comments
 (0)