Skip to content

Commit 1384ff0

Browse files
author
Amritpan Kaur
committed
[CSBinding] Allow inference to bind AnyKeyPath as a KeyPath
that can be converted to AnyKeyPath later.
1 parent df17f19 commit 1384ff0

File tree

3 files changed

+24
-33
lines changed

3 files changed

+24
-33
lines changed

include/swift/Sema/ConstraintLocator.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,22 +1058,6 @@ class LocatorPathElt::ContextualType final : public StoredIntegerElement<1> {
10581058
}
10591059
};
10601060

1061-
class LocatorPathElt::KeyPathType final
1062-
: public StoredPointerElement<TypeBase> {
1063-
public:
1064-
KeyPathType(Type valueType)
1065-
: StoredPointerElement(PathElementKind::KeyPathType,
1066-
valueType.getPointer()) {
1067-
assert(valueType);
1068-
}
1069-
1070-
Type getValueType() const { return getStoredPointer(); }
1071-
1072-
static bool classof(const LocatorPathElt *elt) {
1073-
return elt->getKind() == PathElementKind::KeyPathType;
1074-
}
1075-
};
1076-
10771061
class LocatorPathElt::ConstructorMemberType final
10781062
: public StoredIntegerElement<1> {
10791063
public:

include/swift/Sema/ConstraintLocatorPathElts.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ CUSTOM_LOCATOR_PATH_ELT(KeyPathDynamicMember)
123123
SIMPLE_LOCATOR_PATH_ELT(KeyPathRoot)
124124

125125
/// The type of the key path expression.
126-
CUSTOM_LOCATOR_PATH_ELT(KeyPathType)
126+
SIMPLE_LOCATOR_PATH_ELT(KeyPathType)
127127

128128
/// The value of a key path.
129129
SIMPLE_LOCATOR_PATH_ELT(KeyPathValue)

lib/Sema/CSBindings.cpp

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,27 +1250,34 @@ PotentialBindings::inferFromRelational(Constraint *constraint) {
12501250
return llvm::None;
12511251

12521252
if (TypeVar->getImpl().isKeyPathType()) {
1253-
auto *BGT = type->lookThroughAllOptionalTypes()->getAs<BoundGenericType>();
1254-
if (!BGT || !isKnownKeyPathType(BGT))
1253+
auto objectTy = type->lookThroughAllOptionalTypes();
1254+
if (!isKnownKeyPathType(objectTy))
12551255
return llvm::None;
1256-
1257-
// `PartialKeyPath<T>` represents a type-erased version of `KeyPath<T, V>`.
1256+
1257+
auto &ctx = CS.getASTContext();
1258+
auto *keyPathTypeLoc = TypeVar->getImpl().getLocator();
1259+
auto *keyPath = castToExpr<KeyPathExpr>(keyPathTypeLoc->getAnchor());
1260+
// `AnyKeyPath` and `PartialKeyPath` represent type-erased versions of
1261+
// `KeyPath<T, V>`.
12581262
//
1259-
// In situations where partial key path cannot be used directly i.e.
1260-
// passing an argument to a parameter represented by a partial key path,
1261-
// let's attempt a `KeyPath` binding which would then be converted to a
1262-
// partial key path since there is a subtype relationship between them.
1263-
if (BGT->isPartialKeyPath() && kind == AllowedBindingKind::Subtypes) {
1264-
auto &ctx = CS.getASTContext();
1265-
auto *keyPathLoc = TypeVar->getImpl().getLocator();
1266-
1267-
auto rootTy = BGT->getGenericArgs()[0];
1263+
// In situations where `AnyKeyPath` or `PartialKeyPath` cannot be used
1264+
// directly i.e. passing an argument to a parameter represented by a
1265+
// `AnyKeyPath` or `PartialKeyPath`, let's attempt a `KeyPath` binding which
1266+
// would then be converted to a `AnyKeyPath` or `PartialKeyPath` since there
1267+
// is a subtype relationship between them.
1268+
if (objectTy->isAnyKeyPath()) {
1269+
auto root = CS.getKeyPathRootType(keyPath);
1270+
auto value = CS.getKeyPathValueType(keyPath);
1271+
1272+
type = BoundGenericType::get(ctx.getKeyPathDecl(), Type(),
1273+
{root, value});
1274+
} else if (objectTy->isPartialKeyPath() &&
1275+
kind == AllowedBindingKind::Subtypes) {
1276+
auto rootTy = objectTy->castTo<BoundGenericType>()->getGenericArgs()[0];
12681277
// Since partial key path is an erased version of `KeyPath`, the value
12691278
// type would never be used, which means that binding can use
12701279
// type variable generated for a result of key path expression.
1271-
auto valueTy =
1272-
keyPathLoc->castLastElementTo<LocatorPathElt::KeyPathType>()
1273-
.getValueType();
1280+
auto valueTy = CS.getKeyPathValueType(keyPath);
12741281

12751282
type = BoundGenericType::get(ctx.getKeyPathDecl(), Type(),
12761283
{rootTy, valueTy});

0 commit comments

Comments
 (0)