@@ -4282,75 +4282,16 @@ namespace {
4282
4282
component = origComponent;
4283
4283
break ;
4284
4284
}
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);
4294
4285
4295
- auto dc = subscript->getInnermostDeclContext ();
4286
+ ArrayRef<Identifier> subscriptLabels;
4287
+ if (foundDecl->choice .getKind () !=
4288
+ OverloadChoiceKind::DynamicMemberLookup)
4289
+ subscriptLabels = origComponent.getSubscriptLabels ();
4296
4290
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);
4336
4294
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
- {});
4354
4295
// Save a reference to the component so we can do a post-pass to check
4355
4296
// the Hashable conformance of the indexes.
4356
4297
KeyPathSubscriptComponents.push_back ({E, resolvedComponents.size ()});
@@ -4501,6 +4442,65 @@ namespace {
4501
4442
componentLoc);
4502
4443
}
4503
4444
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
+
4504
4504
Expr *visitKeyPathDotExpr (KeyPathDotExpr *E) {
4505
4505
llvm_unreachable (" found KeyPathDotExpr in CSApply" );
4506
4506
}
0 commit comments