@@ -1535,32 +1535,52 @@ namespace {
15351535 SourceLoc dotLoc,
15361536 ConstraintLocator *memberLoc) {
15371537 auto &ctx = cs.getASTContext ();
1538+ auto *anchor = memberLoc->getAnchor ();
15381539
15391540 KeyPathExpr::Component component;
1540- auto *componentExpr = memberLoc->getAnchor ();
15411541
1542- simplifyExprType (componentExpr);
1543- componentExpr->setType (cs.getType (componentExpr));
1544-
1545- // Now, let's create a KeyPath expression itself.
1542+ // Let's create a KeyPath expression and fill in "parsed path"
1543+ // after component is built.
15461544 auto *keyPath = new (ctx) KeyPathExpr (/* backslashLoc=*/ dotLoc,
15471545 /* parsedRoot=*/ nullptr ,
1548- /* parsedPath=*/ componentExpr ,
1546+ /* parsedPath=*/ anchor ,
15491547 /* isImplicit=*/ true );
15501548
15511549 auto *componentLoc = cs.getConstraintLocator (
15521550 memberLoc,
15531551 LocatorPathElt::getKeyPathDynamicMember (keyPathTy->getAnyNominal ()));
15541552 auto overload = solution.getOverloadChoice (componentLoc);
15551553
1556- // Let's re-use existing expression, but switch its base
1557- // to keypath special "dot" expression.
1558- if (auto *UDE = dyn_cast<UnresolvedDotExpr>(componentExpr)) {
1559- UDE->setBase (new (ctx) KeyPathDotExpr (dotLoc));
1554+ // We can't reuse existing expression because type-check
1555+ // based diagnostics could hold the reference to original AST.
1556+ Expr *componentExpr = nullptr ;
1557+ auto *dotExpr = new (ctx) KeyPathDotExpr (dotLoc);
1558+ if (auto *UDE = dyn_cast<UnresolvedDotExpr>(anchor)) {
1559+ componentExpr = new (ctx) UnresolvedDotExpr (
1560+ dotExpr, dotLoc, UDE->getName (), UDE->getNameLoc (),
1561+ /* Implicit=*/ true );
1562+
15601563 component = buildKeyPathPropertyComponent (overload, UDE->getLoc (),
15611564 componentLoc);
1562- } else if (auto *SE = dyn_cast<SubscriptExpr>(componentExpr)) {
1563- SE->setBase (new (ctx) KeyPathDotExpr (dotLoc));
1565+ } else if (auto *SE = dyn_cast<SubscriptExpr>(anchor)) {
1566+ SmallVector<Expr *, 4 > arguments;
1567+ if (auto *TE = dyn_cast<TupleExpr>(SE->getIndex ())) {
1568+ auto args = TE->getElements ();
1569+ arguments.append (args.begin (), args.end ());
1570+ } else {
1571+ arguments.push_back (SE->getIndex ()->getSemanticsProvidingExpr ());
1572+ }
1573+
1574+ Expr *trailingClosure = nullptr ;
1575+ if (SE->hasTrailingClosure ())
1576+ trailingClosure = arguments.pop_back_val ();
1577+
1578+ componentExpr = SubscriptExpr::create (
1579+ ctx, dotExpr, SE->getStartLoc (), arguments, SE->getArgumentLabels (),
1580+ SE->getArgumentLabelLocs (), SE->getEndLoc (), trailingClosure,
1581+ SE->hasDecl () ? SE->getDecl () : ConcreteDeclRef (),
1582+ /* implicit=*/ true , SE->getAccessSemantics ());
1583+
15641584 component = buildKeyPathSubscriptComponent (
15651585 overload, SE->getLoc (), SE->getIndex (), SE->getArgumentLabels (),
15661586 componentLoc);
@@ -1571,6 +1591,11 @@ namespace {
15711591 return nullptr ;
15721592 }
15731593
1594+ assert (componentExpr);
1595+ componentExpr->setType (simplifyType (cs.getType (anchor)));
1596+ cs.cacheType (componentExpr);
1597+
1598+ keyPath->setParsedPath (componentExpr);
15741599 keyPath->resolveComponents (ctx, {component});
15751600 keyPath->setType (keyPathTy);
15761601 cs.cacheType (keyPath);
@@ -2760,7 +2785,8 @@ namespace {
27602785 paramTy->castTo <BoundGenericType>(), dotLoc, memberLocator);
27612786 }
27622787
2763- assert (argExpr);
2788+ if (!argExpr)
2789+ return nullptr ;
27642790
27652791 // Build a tuple so that the argument has a label.
27662792 auto tupleTy =
0 commit comments