Skip to content

Commit 7d32605

Browse files
committed
[ConstraintSystem] Handle @dynamicMemberLookup subscripts with existential parameters
The parameter should still have a key path type as its superclass bound (i.e. `KeyPath<...> & Sendable`), this would be verified by the attribute checker.
1 parent 144ede7 commit 7d32605

File tree

2 files changed

+18
-11
lines changed

2 files changed

+18
-11
lines changed

lib/Sema/CSApply.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2350,11 +2350,10 @@ namespace {
23502350
/// Build an implicit argument for keypath based dynamic lookup,
23512351
/// which consists of KeyPath expression and a single component.
23522352
///
2353-
/// \param keyPathTy The type of the keypath argument.
2353+
/// \param argType The type of the keypath subscript argument.
23542354
/// \param dotLoc The location of the '.' preceding member name.
23552355
/// \param memberLoc The locator to be associated with new argument.
2356-
Expr *buildKeyPathDynamicMemberArgExpr(BoundGenericType *keyPathTy,
2357-
SourceLoc dotLoc,
2356+
Expr *buildKeyPathDynamicMemberArgExpr(Type argType, SourceLoc dotLoc,
23582357
ConstraintLocator *memberLoc) {
23592358
using Component = KeyPathExpr::Component;
23602359
auto &ctx = cs.getASTContext();
@@ -2363,7 +2362,7 @@ namespace {
23632362
auto makeKeyPath = [&](ArrayRef<Component> components) -> Expr * {
23642363
auto *kp = KeyPathExpr::createImplicit(ctx, /*backslashLoc*/ dotLoc,
23652364
components, anchor->getEndLoc());
2366-
kp->setType(keyPathTy);
2365+
kp->setType(argType);
23672366
cs.cacheExprTypes(kp);
23682367

23692368
// See whether there's an equivalent ObjC key path string we can produce
@@ -2372,6 +2371,10 @@ namespace {
23722371
return kp;
23732372
};
23742373

2374+
Type keyPathTy = argType;
2375+
if (auto *existential = keyPathTy->getAs<ExistentialType>())
2376+
keyPathTy = existential->getExistentialLayout().explicitSuperclass;
2377+
23752378
SmallVector<Component, 2> components;
23762379
auto *componentLoc = cs.getConstraintLocator(
23772380
memberLoc,
@@ -3482,8 +3485,8 @@ namespace {
34823485
auto fieldName = overload.choice.getName().getBaseIdentifier().str();
34833486
argExpr = buildDynamicMemberLookupArgExpr(fieldName, nameLoc, paramTy);
34843487
} else {
3485-
argExpr = buildKeyPathDynamicMemberArgExpr(
3486-
paramTy->castTo<BoundGenericType>(), dotLoc, memberLocator);
3488+
argExpr =
3489+
buildKeyPathDynamicMemberArgExpr(paramTy, dotLoc, memberLocator);
34873490
}
34883491

34893492
if (!argExpr)

lib/Sema/ConstraintSystem.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "TypeCheckMacros.h"
2323
#include "TypeCheckType.h"
2424
#include "TypeChecker.h"
25+
#include "swift/AST/ExistentialLayout.h"
2526
#include "swift/AST/GenericEnvironment.h"
2627
#include "swift/AST/Initializer.h"
2728
#include "swift/AST/ParameterList.h"
@@ -3484,8 +3485,12 @@ void ConstraintSystem::bindOverloadType(
34843485
"subscript always has one argument");
34853486
// Parameter type is KeyPath<T, U> where `T` is a root type
34863487
// and U is a leaf type (aka member type).
3487-
auto keyPathTy =
3488-
fnType->getParams()[0].getPlainType()->castTo<BoundGenericType>();
3488+
auto paramTy = fnType->getParams()[0].getPlainType();
3489+
3490+
if (auto *existential = paramTy->getAs<ExistentialType>())
3491+
paramTy = existential->getExistentialLayout().explicitSuperclass;
3492+
3493+
auto keyPathTy = paramTy->castTo<BoundGenericType>();
34893494

34903495
auto *keyPathDecl = keyPathTy->getAnyNominal();
34913496
assert(isKnownKeyPathType(keyPathTy) &&
@@ -3576,7 +3581,7 @@ void ConstraintSystem::bindOverloadType(
35763581
addConstraint(ConstraintKind::Equal, subscriptResultTy, leafTy,
35773582
keyPathLoc);
35783583

3579-
addDynamicMemberSubscriptConstraints(/*argTy*/ keyPathTy,
3584+
addDynamicMemberSubscriptConstraints(/*argTy*/ paramTy,
35803585
originalCallerTy->getResult());
35813586

35823587
// Bind the overload type to the opened type as usual to match the fact
@@ -3592,8 +3597,7 @@ void ConstraintSystem::bindOverloadType(
35923597
// Form constraints for a x[dynamicMember:] subscript with a key path
35933598
// argument, where the overload type is bound to the result to model the
35943599
// fact that this a property access in the source.
3595-
addDynamicMemberSubscriptConstraints(/*argTy*/ keyPathTy,
3596-
boundType);
3600+
addDynamicMemberSubscriptConstraints(/*argTy*/ paramTy, boundType);
35973601
}
35983602
return;
35993603
}

0 commit comments

Comments
 (0)