@@ -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