@@ -94,6 +94,11 @@ bool BindingSet::isDelayed() const {
9494 }
9595 }
9696
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+
97102 if (isHole ()) {
98103 auto *locator = TypeVar->getImpl ().getLocator ();
99104 assert (locator && " a hole without locator?" );
@@ -169,6 +174,12 @@ bool BindingSet::isPotentiallyIncomplete() const {
169174 if (Info.isGenericParameter ())
170175 return true ;
171176
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+
172183 // If current type variable is associated with a code completion token
173184 // it's possible that it doesn't have enough contextual information
174185 // to be resolved to anything so let's delay considering it until everything
@@ -873,6 +884,65 @@ void PotentialBindings::addDefault(Constraint *constraint) {
873884 Defaults.insert (constraint);
874885}
875886
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+
876946bool LiteralRequirement::isCoveredBy (Type type, ConstraintSystem &CS) const {
877947 auto coversDefaultType = [](Type type, Type defaultType) -> bool {
878948 if (!defaultType->hasUnboundGenericType ())
@@ -2097,6 +2167,10 @@ bool TypeVarBindingProducer::computeNext() {
20972167 }
20982168
20992169 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+
21002174 // Add defaultable constraints (if any).
21012175 for (auto *constraint : DelayedDefaults) {
21022176 if (constraint->getKind () == ConstraintKind::FallbackType) {
0 commit comments