Skip to content

Commit 4d225c7

Browse files
committed
[CSApply] Extract keypath subscript resolution logic
1 parent 32e0c80 commit 4d225c7

File tree

1 file changed

+66
-66
lines changed

1 file changed

+66
-66
lines changed

lib/Sema/CSApply.cpp

Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -4282,75 +4282,16 @@ namespace {
42824282
component = origComponent;
42834283
break;
42844284
}
4285-
4286-
auto subscript = cast<SubscriptDecl>(foundDecl->choice.getDecl());
4287-
if (subscript->isGetterMutating()) {
4288-
cs.TC.diagnose(origComponent.getLoc(),
4289-
diag::expr_keypath_mutating_getter,
4290-
subscript->getFullName());
4291-
}
4292-
4293-
cs.TC.requestMemberLayout(subscript);
42944285

4295-
auto dc = subscript->getInnermostDeclContext();
4286+
ArrayRef<Identifier> subscriptLabels;
4287+
if (foundDecl->choice.getKind() !=
4288+
OverloadChoiceKind::DynamicMemberLookup)
4289+
subscriptLabels = origComponent.getSubscriptLabels();
42964290

4297-
auto indexType = AnyFunctionType::composeInput(
4298-
cs.TC.Context,
4299-
subscript->getInterfaceType()
4300-
->castTo<AnyFunctionType>()
4301-
->getParams(),
4302-
/*canonicalVararg=*/false);
4303-
4304-
SubstitutionMap subs;
4305-
if (auto sig = dc->getGenericSignatureOfContext()) {
4306-
// Compute substitutions to refer to the member.
4307-
subs = solution.computeSubstitutions(sig, locator);
4308-
indexType = indexType.subst(subs);
4309-
}
4310-
4311-
// If this is a @dynamicMemberLookup reference to resolve a property
4312-
// through the subscript(dynamicMember:) member, restore the
4313-
// openedType and origComponent to its full reference as if the user
4314-
// wrote out the subscript manually.
4315-
if (foundDecl->choice.getKind() ==
4316-
OverloadChoiceKind::DynamicMemberLookup) {
4317-
foundDecl->openedType = foundDecl->openedFullType
4318-
->castTo<AnyFunctionType>()->getResult();
4319-
4320-
auto &ctx = cs.TC.Context;
4321-
auto loc = origComponent.getLoc();
4322-
auto fieldName =
4323-
foundDecl->choice.getName().getBaseIdentifier().str();
4324-
4325-
Expr *nameExpr = new (ctx) StringLiteralExpr(fieldName, loc,
4326-
/*implicit*/true);
4327-
(void)cs.TC.typeCheckExpression(nameExpr, dc);
4328-
cs.cacheExprTypes(nameExpr);
4329-
4330-
origComponent = KeyPathExpr::Component::
4331-
forUnresolvedSubscript(ctx, loc,
4332-
{nameExpr}, {ctx.Id_dynamicMember}, {loc},
4333-
loc, /*trailingClosure*/nullptr);
4334-
cs.setType(origComponent.getIndexExpr(), indexType);
4335-
}
4291+
component = buildKeyPathSubscriptComponent(
4292+
*foundDecl, origComponent.getLoc(), origComponent.getIndexExpr(),
4293+
subscriptLabels, locator);
43364294

4337-
auto subscriptType =
4338-
simplifyType(foundDecl->openedType)->castTo<AnyFunctionType>();
4339-
auto resolvedTy = subscriptType->getResult();
4340-
auto ref = ConcreteDeclRef(subscript, subs);
4341-
4342-
// Coerce the indices to the type the subscript expects.
4343-
auto indexExpr = coerceCallArguments(
4344-
origComponent.getIndexExpr(), subscriptType,
4345-
/*applyExpr*/ nullptr, origComponent.getSubscriptLabels(),
4346-
/* hasTrailingClosure */ false, locator);
4347-
4348-
component = KeyPathExpr::Component
4349-
::forSubscriptWithPrebuiltIndexExpr(ref, indexExpr,
4350-
origComponent.getSubscriptLabels(),
4351-
resolvedTy,
4352-
origComponent.getLoc(),
4353-
{});
43544295
// Save a reference to the component so we can do a post-pass to check
43554296
// the Hashable conformance of the indexes.
43564297
KeyPathSubscriptComponents.push_back({E, resolvedComponents.size()});
@@ -4501,6 +4442,65 @@ namespace {
45014442
componentLoc);
45024443
}
45034444

4445+
KeyPathExpr::Component buildKeyPathSubscriptComponent(
4446+
SelectedOverload &overload, SourceLoc componentLoc, Expr *indexExpr,
4447+
ArrayRef<Identifier> labels, ConstraintLocator *locator) {
4448+
auto subscript = cast<SubscriptDecl>(overload.choice.getDecl());
4449+
if (subscript->isGetterMutating()) {
4450+
cs.TC.diagnose(componentLoc, diag::expr_keypath_mutating_getter,
4451+
subscript->getFullName());
4452+
}
4453+
4454+
cs.TC.requestMemberLayout(subscript);
4455+
4456+
auto dc = subscript->getInnermostDeclContext();
4457+
4458+
auto indexType = AnyFunctionType::composeInput(
4459+
cs.TC.Context,
4460+
subscript->getInterfaceType()->castTo<AnyFunctionType>()->getParams(),
4461+
/*canonicalVararg=*/false);
4462+
4463+
SubstitutionMap subs;
4464+
if (auto sig = dc->getGenericSignatureOfContext()) {
4465+
// Compute substitutions to refer to the member.
4466+
subs = solution.computeSubstitutions(sig, locator);
4467+
indexType = indexType.subst(subs);
4468+
}
4469+
4470+
// If this is a @dynamicMemberLookup reference to resolve a property
4471+
// through the subscript(dynamicMember:) member, restore the
4472+
// openedType and origComponent to its full reference as if the user
4473+
// wrote out the subscript manually.
4474+
if (overload.choice.getKind() ==
4475+
OverloadChoiceKind::DynamicMemberLookup) {
4476+
overload.openedType =
4477+
overload.openedFullType->castTo<AnyFunctionType>()->getResult();
4478+
4479+
auto &ctx = cs.TC.Context;
4480+
auto fieldName = overload.choice.getName().getBaseIdentifier().str();
4481+
4482+
labels = ctx.Id_dynamicMember;
4483+
indexExpr = new (ctx) StringLiteralExpr(fieldName, componentLoc,
4484+
/*implicit*/ true);
4485+
(void)cs.TC.typeCheckExpression(indexExpr, dc);
4486+
cs.cacheExprTypes(indexExpr);
4487+
}
4488+
4489+
auto subscriptType =
4490+
simplifyType(overload.openedType)->castTo<AnyFunctionType>();
4491+
auto resolvedTy = subscriptType->getResult();
4492+
auto ref = ConcreteDeclRef(subscript, subs);
4493+
4494+
// Coerce the indices to the type the subscript expects.
4495+
auto *newIndexExpr =
4496+
coerceCallArguments(indexExpr, subscriptType,
4497+
/*applyExpr*/ nullptr, labels,
4498+
/*hasTrailingClosure*/ false, locator);
4499+
4500+
return KeyPathExpr::Component::forSubscriptWithPrebuiltIndexExpr(
4501+
ref, newIndexExpr, labels, resolvedTy, componentLoc, {});
4502+
}
4503+
45044504
Expr *visitKeyPathDotExpr(KeyPathDotExpr *E) {
45054505
llvm_unreachable("found KeyPathDotExpr in CSApply");
45064506
}

0 commit comments

Comments
 (0)