@@ -94,6 +94,11 @@ bool BindingSet::isDelayed() const {
94
94
}
95
95
}
96
96
97
+ // Delay key path literal type binding until there is at least
98
+ // one contextual binding (or default is promoted into a binding).
99
+ if (TypeVar->getImpl ().isKeyPathType () && Bindings.empty ())
100
+ return true ;
101
+
97
102
if (isHole ()) {
98
103
auto *locator = TypeVar->getImpl ().getLocator ();
99
104
assert (locator && " a hole without locator?" );
@@ -169,6 +174,12 @@ bool BindingSet::isPotentiallyIncomplete() const {
169
174
if (Info.isGenericParameter ())
170
175
return true ;
171
176
177
+ // Key path literal type is incomplete until there is a
178
+ // contextual type or key path is resolved enough to infer
179
+ // capability and promote default into a binding.
180
+ if (TypeVar->getImpl ().isKeyPathType ())
181
+ return Bindings.empty ();
182
+
172
183
// If current type variable is associated with a code completion token
173
184
// it's possible that it doesn't have enough contextual information
174
185
// to be resolved to anything so let's delay considering it until everything
@@ -873,6 +884,65 @@ void PotentialBindings::addDefault(Constraint *constraint) {
873
884
Defaults.insert (constraint);
874
885
}
875
886
887
+ void BindingSet::addDefault (Constraint *constraint) {
888
+ auto defaultTy = constraint->getSecondType ();
889
+
890
+ if (TypeVar->getImpl ().isKeyPathType () && Bindings.empty ()) {
891
+ if (constraint->getKind () == ConstraintKind::FallbackType) {
892
+ auto &ctx = CS.getASTContext ();
893
+
894
+ bool isValid;
895
+ llvm::Optional<KeyPathCapability> capability;
896
+
897
+ std::tie (isValid, capability) = CS.inferKeyPathLiteralCapability (TypeVar);
898
+
899
+ if (!isValid) {
900
+ // If one of the references in a key path is invalid let's add
901
+ // a placeholder binding in diagnostic mode to indicate that
902
+ // the key path cannot be properly resolved.
903
+ if (CS.shouldAttemptFixes ()) {
904
+ addBinding ({PlaceholderType::get (ctx, TypeVar),
905
+ AllowedBindingKind::Exact, constraint});
906
+ }
907
+
908
+ // During normal solving the set has to stay empty.
909
+ return ;
910
+ }
911
+
912
+ if (capability) {
913
+ auto *keyPathType = defaultTy->castTo <BoundGenericType>();
914
+
915
+ auto root = keyPathType->getGenericArgs ()[0 ];
916
+ auto value = keyPathType->getGenericArgs ()[1 ];
917
+
918
+ switch (*capability) {
919
+ case KeyPathCapability::ReadOnly:
920
+ break ;
921
+
922
+ case KeyPathCapability::Writable:
923
+ keyPathType = BoundGenericType::get (ctx.getWritableKeyPathDecl (),
924
+ /* parent=*/ Type (), {root, value});
925
+ break ;
926
+
927
+ case KeyPathCapability::ReferenceWritable:
928
+ keyPathType =
929
+ BoundGenericType::get (ctx.getReferenceWritableKeyPathDecl (),
930
+ /* parent=*/ Type (), {root, value});
931
+ break ;
932
+ }
933
+
934
+ addBinding ({keyPathType, AllowedBindingKind::Exact, constraint});
935
+ }
936
+
937
+ // If key path is not yet sufficiently resolved, don't add any
938
+ // bindings.
939
+ return ;
940
+ }
941
+ }
942
+
943
+ Defaults.insert ({defaultTy->getCanonicalType (), constraint});
944
+ }
945
+
876
946
bool LiteralRequirement::isCoveredBy (Type type, ConstraintSystem &CS) const {
877
947
auto coversDefaultType = [](Type type, Type defaultType) -> bool {
878
948
if (!defaultType->hasUnboundGenericType ())
@@ -2097,6 +2167,10 @@ bool TypeVarBindingProducer::computeNext() {
2097
2167
}
2098
2168
2099
2169
if (newBindings.empty ()) {
2170
+ // If key path type had contextual types, let's not attempt fallback.
2171
+ if (TypeVar->getImpl ().isKeyPathType () && !ExploredTypes.empty ())
2172
+ return false ;
2173
+
2100
2174
// Add defaultable constraints (if any).
2101
2175
for (auto *constraint : DelayedDefaults) {
2102
2176
if (constraint->getKind () == ConstraintKind::FallbackType) {
0 commit comments