@@ -1535,32 +1535,52 @@ namespace {
1535
1535
SourceLoc dotLoc,
1536
1536
ConstraintLocator *memberLoc) {
1537
1537
auto &ctx = cs.getASTContext ();
1538
+ auto *anchor = memberLoc->getAnchor ();
1538
1539
1539
1540
KeyPathExpr::Component component;
1540
- auto *componentExpr = memberLoc->getAnchor ();
1541
1541
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.
1546
1544
auto *keyPath = new (ctx) KeyPathExpr (/* backslashLoc=*/ dotLoc,
1547
1545
/* parsedRoot=*/ nullptr ,
1548
- /* parsedPath=*/ componentExpr ,
1546
+ /* parsedPath=*/ anchor ,
1549
1547
/* isImplicit=*/ true );
1550
1548
1551
1549
auto *componentLoc = cs.getConstraintLocator (
1552
1550
memberLoc,
1553
1551
LocatorPathElt::getKeyPathDynamicMember (keyPathTy->getAnyNominal ()));
1554
1552
auto overload = solution.getOverloadChoice (componentLoc);
1555
1553
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
+
1560
1563
component = buildKeyPathPropertyComponent (overload, UDE->getLoc (),
1561
1564
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
+
1564
1584
component = buildKeyPathSubscriptComponent (
1565
1585
overload, SE->getLoc (), SE->getIndex (), SE->getArgumentLabels (),
1566
1586
componentLoc);
@@ -1571,6 +1591,11 @@ namespace {
1571
1591
return nullptr ;
1572
1592
}
1573
1593
1594
+ assert (componentExpr);
1595
+ componentExpr->setType (simplifyType (cs.getType (anchor)));
1596
+ cs.cacheType (componentExpr);
1597
+
1598
+ keyPath->setParsedPath (componentExpr);
1574
1599
keyPath->resolveComponents (ctx, {component});
1575
1600
keyPath->setType (keyPathTy);
1576
1601
cs.cacheType (keyPath);
@@ -2760,7 +2785,8 @@ namespace {
2760
2785
paramTy->castTo <BoundGenericType>(), dotLoc, memberLocator);
2761
2786
}
2762
2787
2763
- assert (argExpr);
2788
+ if (!argExpr)
2789
+ return nullptr ;
2764
2790
2765
2791
// Build a tuple so that the argument has a label.
2766
2792
auto tupleTy =
0 commit comments