@@ -3274,6 +3274,38 @@ namespace {
3274
3274
expr = sanitizeArgumentList (expr);
3275
3275
}
3276
3276
3277
+ // If this expression represents keypath based dynamic member
3278
+ // lookup, let's convert it back to the original form of
3279
+ // member or subscript reference.
3280
+ if (auto *SE = dyn_cast<SubscriptExpr>(expr)) {
3281
+ if (auto *TE = dyn_cast<TupleExpr>(SE->getIndex ())) {
3282
+ auto isImplicitKeyPathExpr = [](Expr *argExpr) -> bool {
3283
+ if (auto *KP = dyn_cast<KeyPathExpr>(argExpr))
3284
+ return KP->isImplicit ();
3285
+ return false ;
3286
+ };
3287
+
3288
+ if (TE->isImplicit () && TE->getNumElements () == 1 &&
3289
+ TE->getElementName (0 ) == TC.Context .Id_dynamicMember &&
3290
+ isImplicitKeyPathExpr (TE->getElement (0 ))) {
3291
+ auto *keyPathExpr = cast<KeyPathExpr>(TE->getElement (0 ));
3292
+ auto *componentExpr = keyPathExpr->getParsedPath ();
3293
+
3294
+ if (auto *UDE = dyn_cast<UnresolvedDotExpr>(componentExpr)) {
3295
+ UDE->setBase (SE->getBase ());
3296
+ return {true , UDE};
3297
+ }
3298
+
3299
+ if (auto *subscript = dyn_cast<SubscriptExpr>(componentExpr)) {
3300
+ subscript->setBase (SE->getBase ());
3301
+ return {true , subscript};
3302
+ }
3303
+
3304
+ llvm_unreachable (" unknown keypath component type" );
3305
+ }
3306
+ }
3307
+ }
3308
+
3277
3309
// Now, we're ready to walk into sub expressions.
3278
3310
return {true , expr};
3279
3311
}
@@ -3898,4 +3930,4 @@ swift::getOriginalArgumentList(Expr *expr) {
3898
3930
}
3899
3931
3900
3932
return result;
3901
- }
3933
+ }
0 commit comments