Skip to content

Commit 1d78fe1

Browse files
author
Nathan Hawes
committed
[Sema/Index] Resolve #keyPath components so they can be indexed
Unlike \keypath expressions, only the property components of #keypath expressions were being resolved, so index wouldn't pick up references for their qualifying types. Also fixes a code completion bug where it was reporting members from the Swift rather than ObjC side of bridged types. Resolves rdar://problem/61573935
1 parent 5300dc2 commit 1d78fe1

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
@@ -5209,6 +5209,7 @@ class KeyPathExpr : public Expr {
52095209
OptionalWrap,
52105210
Identity,
52115211
TupleElement,
5212+
DictionaryKey,
52125213
};
52135214

52145215
private:
@@ -5317,6 +5318,16 @@ class KeyPathExpr : public Expr {
53175318
propertyType,
53185319
loc);
53195320
}
5321+
5322+
/// Create a component for a dictionary key (#keyPath only).
5323+
static Component forDictionaryKey(DeclNameRef UnresolvedName,
5324+
Type valueType,
5325+
SourceLoc loc) {
5326+
return Component(nullptr, UnresolvedName, nullptr, {}, {},
5327+
Kind::DictionaryKey,
5328+
valueType,
5329+
loc);
5330+
}
53205331

53215332
/// Create a component for a subscript.
53225333
static Component forSubscript(ASTContext &ctx,
@@ -5407,6 +5418,7 @@ class KeyPathExpr : public Expr {
54075418
case Kind::Property:
54085419
case Kind::Identity:
54095420
case Kind::TupleElement:
5421+
case Kind::DictionaryKey:
54105422
return true;
54115423

54125424
case Kind::UnresolvedSubscript:
@@ -5431,6 +5443,7 @@ class KeyPathExpr : public Expr {
54315443
case Kind::Property:
54325444
case Kind::Identity:
54335445
case Kind::TupleElement:
5446+
case Kind::DictionaryKey:
54345447
return nullptr;
54355448
}
54365449
llvm_unreachable("unhandled kind");
@@ -5450,6 +5463,7 @@ class KeyPathExpr : public Expr {
54505463
case Kind::Property:
54515464
case Kind::Identity:
54525465
case Kind::TupleElement:
5466+
case Kind::DictionaryKey:
54535467
llvm_unreachable("no subscript labels for this kind");
54545468
}
54555469
llvm_unreachable("unhandled kind");
@@ -5472,6 +5486,7 @@ class KeyPathExpr : public Expr {
54725486
case Kind::Property:
54735487
case Kind::Identity:
54745488
case Kind::TupleElement:
5489+
case Kind::DictionaryKey:
54755490
return {};
54765491
}
54775492
llvm_unreachable("unhandled kind");
@@ -5483,6 +5498,7 @@ class KeyPathExpr : public Expr {
54835498
DeclNameRef getUnresolvedDeclName() const {
54845499
switch (getKind()) {
54855500
case Kind::UnresolvedProperty:
5501+
case Kind::DictionaryKey:
54865502
return Decl.UnresolvedName;
54875503

54885504
case Kind::Invalid:
@@ -5513,6 +5529,7 @@ class KeyPathExpr : public Expr {
55135529
case Kind::OptionalForce:
55145530
case Kind::Identity:
55155531
case Kind::TupleElement:
5532+
case Kind::DictionaryKey:
55165533
llvm_unreachable("no decl ref for this kind");
55175534
}
55185535
llvm_unreachable("unhandled kind");
@@ -5532,6 +5549,7 @@ class KeyPathExpr : public Expr {
55325549
case Kind::Identity:
55335550
case Kind::Property:
55345551
case Kind::Subscript:
5552+
case Kind::DictionaryKey:
55355553
llvm_unreachable("no field number for this kind");
55365554
}
55375555
llvm_unreachable("unhandled kind");

lib/AST/ASTDumper.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2821,6 +2821,11 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
28212821
PrintWithColorRAII(OS, DiscriminatorColor)
28222822
<< "#" << component.getTupleIndex();
28232823
break;
2824+
case KeyPathExpr::Component::Kind::DictionaryKey:
2825+
PrintWithColorRAII(OS, ASTNodeColor) << "dict_key";
2826+
PrintWithColorRAII(OS, IdentifierColor)
2827+
<< " key='" << component.getUnresolvedDeclName() << "'";
2828+
break;
28242829
}
28252830
PrintWithColorRAII(OS, TypeColor)
28262831
<< " type='" << GetTypeOfKeyPathComponent(E, i) << "'";

lib/AST/ASTWalker.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,7 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
11201120
case KeyPathExpr::Component::Kind::Invalid:
11211121
case KeyPathExpr::Component::Kind::Identity:
11221122
case KeyPathExpr::Component::Kind::TupleElement:
1123+
case KeyPathExpr::Component::Kind::DictionaryKey:
11231124
// No subexpr to visit.
11241125
break;
11251126
}

lib/AST/Expr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2367,6 +2367,7 @@ void KeyPathExpr::Component::setSubscriptIndexHashableConformances(
23672367
case Kind::Property:
23682368
case Kind::Identity:
23692369
case Kind::TupleElement:
2370+
case Kind::DictionaryKey:
23702371
llvm_unreachable("no hashable conformances for this kind");
23712372
}
23722373
}

lib/IDE/SourceEntityWalker.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ std::pair<bool, Expr *> SemaAnnotator::walkToExprPre(Expr *E) {
415415
case KeyPathExpr::Component::Kind::OptionalWrap:
416416
case KeyPathExpr::Component::Kind::OptionalForce:
417417
case KeyPathExpr::Component::Kind::Identity:
418+
case KeyPathExpr::Component::Kind::DictionaryKey:
418419
break;
419420
}
420421
}

lib/SILGen/SILGenExpr.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3724,6 +3724,11 @@ RValue RValueEmitter::visitKeyPathExpr(KeyPathExpr *E, SGFContext C) {
37243724
case KeyPathExpr::Component::Kind::UnresolvedProperty:
37253725
case KeyPathExpr::Component::Kind::UnresolvedSubscript:
37263726
llvm_unreachable("not resolved");
3727+
break;
3728+
3729+
case KeyPathExpr::Component::Kind::DictionaryKey:
3730+
llvm_unreachable("DictionaryKey only valid in #keyPath");
3731+
break;
37273732
}
37283733
}
37293734

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

@@ -4680,6 +4683,10 @@ namespace {
46804683
case KeyPathExpr::Component::Kind::OptionalWrap:
46814684
case KeyPathExpr::Component::Kind::TupleElement:
46824685
llvm_unreachable("already resolved");
4686+
break;
4687+
case KeyPathExpr::Component::Kind::DictionaryKey:
4688+
llvm_unreachable("DictionaryKey only valid in #keyPath");
4689+
break;
46834690
}
46844691

46854692
// Update "componentTy" with the result type of the last component.
@@ -7593,9 +7600,8 @@ namespace {
75937600
componentType = solution.simplifyType(cs.getType(kp, i));
75947601
assert(!componentType->hasTypeVariable() &&
75957602
"Should not write type variable into key-path component");
7603+
kp->getMutableComponents()[i].setComponentType(componentType);
75967604
}
7597-
7598-
kp->getMutableComponents()[i].setComponentType(componentType);
75997605
}
76007606
}
76017607

lib/Sema/CSGen.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3527,6 +3527,9 @@ namespace {
35273527
}
35283528
case KeyPathExpr::Component::Kind::Identity:
35293529
continue;
3530+
case KeyPathExpr::Component::Kind::DictionaryKey:
3531+
llvm_unreachable("DictionaryKey only valid in #keyPath");
3532+
break;
35303533
}
35313534

35323535
// 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
@@ -8051,6 +8051,9 @@ ConstraintSystem::simplifyKeyPathConstraint(
80518051
case KeyPathExpr::Component::Kind::TupleElement:
80528052
llvm_unreachable("not implemented");
80538053
break;
8054+
case KeyPathExpr::Component::Kind::DictionaryKey:
8055+
llvm_unreachable("DictionaryKey only valid in #keyPath");
8056+
break;
80548057
}
80558058
}
80568059

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)