@@ -56,8 +56,33 @@ void ConstraintSystem::PotentialBindings::inferTransitiveBindings(
56
56
57
57
auto &bindings = relatedBindings->getSecond ();
58
58
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
+ });
61
86
62
87
// Infer transitive defaults.
63
88
llvm::copy (bindings.Defaults , std::back_inserter (Defaults));
@@ -906,15 +931,7 @@ bool ConstraintSystem::PotentialBindings::infer(
906
931
907
932
case ConstraintKind::ConformsTo:
908
933
case ConstraintKind::SelfObjectOfProtocol:
909
- // Swift 3 allowed the use of default types for normal conformances
910
- // to expressible-by-literal protocols.
911
- if (cs.getASTContext ().LangOpts .EffectiveLanguageVersion [0 ] >= 4 )
912
- return false ;
913
-
914
- if (!constraint->getSecondType ()->is <ProtocolType>())
915
- return false ;
916
-
917
- LLVM_FALLTHROUGH;
934
+ return false ;
918
935
919
936
case ConstraintKind::LiteralConformsTo: {
920
937
// Record constraint where protocol requirement originated
0 commit comments