Skip to content

Commit 4c7cd16

Browse files
author
Nathan Hawes
authored
Merge pull request swiftlang#33245 from nathawes/index-key-paths
[Sema/Index] Resolve #keyPath components so they get handled by indexing, semantic highlighting, etc.
2 parents 6714cef + 1d78fe1 commit 4c7cd16

16 files changed

+160
-25
lines changed

include/swift/AST/Expr.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5259,6 +5259,7 @@ class KeyPathExpr : public Expr {
52595259
OptionalWrap,
52605260
Identity,
52615261
TupleElement,
5262+
DictionaryKey,
52625263
};
52635264

52645265
private:
@@ -5367,6 +5368,16 @@ class KeyPathExpr : public Expr {
53675368
propertyType,
53685369
loc);
53695370
}
5371+
5372+
/// Create a component for a dictionary key (#keyPath only).
5373+
static Component forDictionaryKey(DeclNameRef UnresolvedName,
5374+
Type valueType,
5375+
SourceLoc loc) {
5376+
return Component(nullptr, UnresolvedName, nullptr, {}, {},
5377+
Kind::DictionaryKey,
5378+
valueType,
5379+
loc);
5380+
}
53705381

53715382
/// Create a component for a subscript.
53725383
static Component forSubscript(ASTContext &ctx,
@@ -5457,6 +5468,7 @@ class KeyPathExpr : public Expr {
54575468
case Kind::Property:
54585469
case Kind::Identity:
54595470
case Kind::TupleElement:
5471+
case Kind::DictionaryKey:
54605472
return true;
54615473

54625474
case Kind::UnresolvedSubscript:
@@ -5481,6 +5493,7 @@ class KeyPathExpr : public Expr {
54815493
case Kind::Property:
54825494
case Kind::Identity:
54835495
case Kind::TupleElement:
5496+
case Kind::DictionaryKey:
54845497
return nullptr;
54855498
}
54865499
llvm_unreachable("unhandled kind");
@@ -5500,6 +5513,7 @@ class KeyPathExpr : public Expr {
55005513
case Kind::Property:
55015514
case Kind::Identity:
55025515
case Kind::TupleElement:
5516+
case Kind::DictionaryKey:
55035517
llvm_unreachable("no subscript labels for this kind");
55045518
}
55055519
llvm_unreachable("unhandled kind");
@@ -5522,6 +5536,7 @@ class KeyPathExpr : public Expr {
55225536
case Kind::Property:
55235537
case Kind::Identity:
55245538
case Kind::TupleElement:
5539+
case Kind::DictionaryKey:
55255540
return {};
55265541
}
55275542
llvm_unreachable("unhandled kind");
@@ -5533,6 +5548,7 @@ class KeyPathExpr : public Expr {
55335548
DeclNameRef getUnresolvedDeclName() const {
55345549
switch (getKind()) {
55355550
case Kind::UnresolvedProperty:
5551+
case Kind::DictionaryKey:
55365552
return Decl.UnresolvedName;
55375553

55385554
case Kind::Invalid:
@@ -5563,6 +5579,7 @@ class KeyPathExpr : public Expr {
55635579
case Kind::OptionalForce:
55645580
case Kind::Identity:
55655581
case Kind::TupleElement:
5582+
case Kind::DictionaryKey:
55665583
llvm_unreachable("no decl ref for this kind");
55675584
}
55685585
llvm_unreachable("unhandled kind");
@@ -5582,6 +5599,7 @@ class KeyPathExpr : public Expr {
55825599
case Kind::Identity:
55835600
case Kind::Property:
55845601
case Kind::Subscript:
5602+
case Kind::DictionaryKey:
55855603
llvm_unreachable("no field number for this kind");
55865604
}
55875605
llvm_unreachable("unhandled kind");

lib/AST/ASTDumper.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2829,6 +2829,11 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
28292829
PrintWithColorRAII(OS, DiscriminatorColor)
28302830
<< "#" << component.getTupleIndex();
28312831
break;
2832+
case KeyPathExpr::Component::Kind::DictionaryKey:
2833+
PrintWithColorRAII(OS, ASTNodeColor) << "dict_key";
2834+
PrintWithColorRAII(OS, IdentifierColor)
2835+
<< " key='" << component.getUnresolvedDeclName() << "'";
2836+
break;
28322837
}
28332838
PrintWithColorRAII(OS, TypeColor)
28342839
<< " type='" << GetTypeOfKeyPathComponent(E, i) << "'";

lib/AST/ASTWalker.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,6 +1127,7 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
11271127
case KeyPathExpr::Component::Kind::Invalid:
11281128
case KeyPathExpr::Component::Kind::Identity:
11291129
case KeyPathExpr::Component::Kind::TupleElement:
1130+
case KeyPathExpr::Component::Kind::DictionaryKey:
11301131
// No subexpr to visit.
11311132
break;
11321133
}

lib/AST/Expr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2386,6 +2386,7 @@ void KeyPathExpr::Component::setSubscriptIndexHashableConformances(
23862386
case Kind::Property:
23872387
case Kind::Identity:
23882388
case Kind::TupleElement:
2389+
case Kind::DictionaryKey:
23892390
llvm_unreachable("no hashable conformances for this kind");
23902391
}
23912392
}

lib/IDE/SourceEntityWalker.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ std::pair<bool, Expr *> SemaAnnotator::walkToExprPre(Expr *E) {
412412
case KeyPathExpr::Component::Kind::OptionalWrap:
413413
case KeyPathExpr::Component::Kind::OptionalForce:
414414
case KeyPathExpr::Component::Kind::Identity:
415+
case KeyPathExpr::Component::Kind::DictionaryKey:
415416
break;
416417
}
417418
}

lib/SILGen/SILGenExpr.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3734,6 +3734,11 @@ RValue RValueEmitter::visitKeyPathExpr(KeyPathExpr *E, SGFContext C) {
37343734
case KeyPathExpr::Component::Kind::UnresolvedProperty:
37353735
case KeyPathExpr::Component::Kind::UnresolvedSubscript:
37363736
llvm_unreachable("not resolved");
3737+
break;
3738+
3739+
case KeyPathExpr::Component::Kind::DictionaryKey:
3740+
llvm_unreachable("DictionaryKey only valid in #keyPath");
3741+
break;
37373742
}
37383743
}
37393744

lib/Sema/CSApply.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,9 @@ static bool buildObjCKeyPathString(KeyPathExpr *E,
237237
// Don't bother building the key path string if the key path didn't even
238238
// resolve.
239239
return false;
240+
case KeyPathExpr::Component::Kind::DictionaryKey:
241+
llvm_unreachable("DictionaryKey only valid in #keyPath expressions.");
242+
return false;
240243
}
241244
}
242245

@@ -4690,6 +4693,10 @@ namespace {
46904693
case KeyPathExpr::Component::Kind::OptionalWrap:
46914694
case KeyPathExpr::Component::Kind::TupleElement:
46924695
llvm_unreachable("already resolved");
4696+
break;
4697+
case KeyPathExpr::Component::Kind::DictionaryKey:
4698+
llvm_unreachable("DictionaryKey only valid in #keyPath");
4699+
break;
46934700
}
46944701

46954702
// Update "componentTy" with the result type of the last component.
@@ -7743,9 +7750,8 @@ namespace {
77437750
componentType = solution.simplifyType(cs.getType(kp, i));
77447751
assert(!componentType->hasTypeVariable() &&
77457752
"Should not write type variable into key-path component");
7753+
kp->getMutableComponents()[i].setComponentType(componentType);
77467754
}
7747-
7748-
kp->getMutableComponents()[i].setComponentType(componentType);
77497755
}
77507756
}
77517757

lib/Sema/CSGen.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3485,6 +3485,9 @@ namespace {
34853485
}
34863486
case KeyPathExpr::Component::Kind::Identity:
34873487
continue;
3488+
case KeyPathExpr::Component::Kind::DictionaryKey:
3489+
llvm_unreachable("DictionaryKey only valid in #keyPath");
3490+
break;
34883491
}
34893492

34903493
// By now, `base` is the result type of this component. Set it in the

lib/Sema/CSSimplify.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8230,6 +8230,9 @@ ConstraintSystem::simplifyKeyPathConstraint(
82308230
case KeyPathExpr::Component::Kind::TupleElement:
82318231
llvm_unreachable("not implemented");
82328232
break;
8233+
case KeyPathExpr::Component::Kind::DictionaryKey:
8234+
llvm_unreachable("DictionaryKey only valid in #keyPath");
8235+
break;
82338236
}
82348237
}
82358238

lib/Sema/ConstraintSystem.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ ConstraintLocator *ConstraintSystem::getCalleeLocator(
493493
case ComponentKind::OptionalChain:
494494
case ComponentKind::OptionalWrap:
495495
case ComponentKind::Identity:
496+
case ComponentKind::DictionaryKey:
496497
// These components don't have any callee associated, so just continue.
497498
break;
498499
}

0 commit comments

Comments
 (0)