Skip to content

Commit ede47ca

Browse files
committed
Partial AST & Sema implementation of TKP
1 parent 5e617b5 commit ede47ca

File tree

13 files changed

+165
-56
lines changed

13 files changed

+165
-56
lines changed

include/swift/AST/Expr.h

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4829,6 +4829,7 @@ class KeyPathExpr : public Expr {
48294829
OptionalChain,
48304830
OptionalWrap,
48314831
Identity,
4832+
TupleElement,
48324833
};
48334834

48344835
private:
@@ -4845,7 +4846,12 @@ class KeyPathExpr : public Expr {
48454846
Expr *SubscriptIndexExpr;
48464847
const Identifier *SubscriptLabelsData;
48474848
const ProtocolConformanceRef *SubscriptHashableConformancesData;
4848-
unsigned SubscriptSize;
4849+
4850+
union {
4851+
unsigned SubscriptSize;
4852+
unsigned FieldNumber;
4853+
} technicated;
4854+
48494855
Kind KindValue;
48504856
Type ComponentType;
48514857
SourceLoc Loc;
@@ -4855,21 +4861,22 @@ class KeyPathExpr : public Expr {
48554861
Expr *indexExpr,
48564862
ArrayRef<Identifier> subscriptLabels,
48574863
ArrayRef<ProtocolConformanceRef> indexHashables,
4864+
unsigned fieldNumber,
48584865
Kind kind,
48594866
Type type,
48604867
SourceLoc loc);
48614868

48624869
public:
48634870
Component()
4864-
: Component(nullptr, {}, nullptr, {}, {}, Kind::Invalid,
4871+
: Component(nullptr, {}, nullptr, {}, {}, 0, Kind::Invalid,
48654872
Type(), SourceLoc())
48664873
{}
48674874

48684875
/// Create an unresolved component for a property.
48694876
static Component forUnresolvedProperty(DeclName UnresolvedName,
48704877
SourceLoc Loc) {
48714878
return Component(nullptr,
4872-
UnresolvedName, nullptr, {}, {},
4879+
UnresolvedName, nullptr, {}, {}, 0,
48734880
Kind::UnresolvedProperty,
48744881
Type(),
48754882
Loc);
@@ -4895,22 +4902,22 @@ class KeyPathExpr : public Expr {
48954902
SourceLoc loc) {
48964903

48974904
return Component(&context,
4898-
{}, index, subscriptLabels, {},
4905+
{}, index, subscriptLabels, {}, 0,
48994906
Kind::UnresolvedSubscript,
49004907
Type(), loc);
49014908
}
49024909

49034910
/// Create an unresolved optional force `!` component.
49044911
static Component forUnresolvedOptionalForce(SourceLoc BangLoc) {
4905-
return Component(nullptr, {}, nullptr, {}, {},
4912+
return Component(nullptr, {}, nullptr, {}, {}, 0,
49064913
Kind::OptionalForce,
49074914
Type(),
49084915
BangLoc);
49094916
}
49104917

49114918
/// Create an unresolved optional chain `?` component.
49124919
static Component forUnresolvedOptionalChain(SourceLoc QuestionLoc) {
4913-
return Component(nullptr, {}, nullptr, {}, {},
4920+
return Component(nullptr, {}, nullptr, {}, {}, 0,
49144921
Kind::OptionalChain,
49154922
Type(),
49164923
QuestionLoc);
@@ -4920,7 +4927,7 @@ class KeyPathExpr : public Expr {
49204927
static Component forProperty(ConcreteDeclRef property,
49214928
Type propertyType,
49224929
SourceLoc loc) {
4923-
return Component(nullptr, property, nullptr, {}, {},
4930+
return Component(nullptr, property, nullptr, {}, {}, 0,
49244931
Kind::Property,
49254932
propertyType,
49264933
loc);
@@ -4949,15 +4956,15 @@ class KeyPathExpr : public Expr {
49494956

49504957
/// Create an optional-forcing `!` component.
49514958
static Component forOptionalForce(Type forcedType, SourceLoc bangLoc) {
4952-
return Component(nullptr, {}, nullptr, {}, {},
4959+
return Component(nullptr, {}, nullptr, {}, {}, 0,
49534960
Kind::OptionalForce, forcedType,
49544961
bangLoc);
49554962
}
49564963

49574964
/// Create an optional-chaining `?` component.
49584965
static Component forOptionalChain(Type unwrappedType,
49594966
SourceLoc questionLoc) {
4960-
return Component(nullptr, {}, nullptr, {}, {},
4967+
return Component(nullptr, {}, nullptr, {}, {}, 0,
49614968
Kind::OptionalChain, unwrappedType,
49624969
questionLoc);
49634970
}
@@ -4966,17 +4973,26 @@ class KeyPathExpr : public Expr {
49664973
/// syntax but may appear when the non-optional result of an optional chain
49674974
/// is implicitly wrapped.
49684975
static Component forOptionalWrap(Type wrappedType) {
4969-
return Component(nullptr, {}, nullptr, {}, {},
4976+
return Component(nullptr, {}, nullptr, {}, {}, 0,
49704977
Kind::OptionalWrap, wrappedType,
49714978
SourceLoc());
49724979
}
49734980

49744981
static Component forIdentity(SourceLoc selfLoc) {
4975-
return Component(nullptr, {}, nullptr, {}, {},
4982+
return Component(nullptr, {}, nullptr, {}, {}, 0,
49764983
Kind::Identity, Type(),
49774984
selfLoc);
49784985
}
49794986

4987+
static Component forTupleElement(unsigned fieldNumber,
4988+
Type elementType,
4989+
SourceLoc loc) {
4990+
return Component(nullptr, {}, nullptr, {}, {}, fieldNumber,
4991+
Kind::TupleElement, elementType,
4992+
loc);
4993+
}
4994+
4995+
49804996
SourceLoc getLoc() const {
49814997
return Loc;
49824998
}
@@ -5000,6 +5016,7 @@ class KeyPathExpr : public Expr {
50005016
case Kind::OptionalForce:
50015017
case Kind::Property:
50025018
case Kind::Identity:
5019+
case Kind::TupleElement:
50035020
return true;
50045021

50055022
case Kind::UnresolvedSubscript:
@@ -5023,6 +5040,7 @@ class KeyPathExpr : public Expr {
50235040
case Kind::UnresolvedProperty:
50245041
case Kind::Property:
50255042
case Kind::Identity:
5043+
case Kind::TupleElement:
50265044
return nullptr;
50275045
}
50285046
llvm_unreachable("unhandled kind");
@@ -5032,7 +5050,7 @@ class KeyPathExpr : public Expr {
50325050
switch (getKind()) {
50335051
case Kind::Subscript:
50345052
case Kind::UnresolvedSubscript:
5035-
return {SubscriptLabelsData, (size_t)SubscriptSize};
5053+
return {SubscriptLabelsData, (size_t)technicated.SubscriptSize};
50365054

50375055
case Kind::Invalid:
50385056
case Kind::OptionalChain:
@@ -5041,6 +5059,7 @@ class KeyPathExpr : public Expr {
50415059
case Kind::UnresolvedProperty:
50425060
case Kind::Property:
50435061
case Kind::Identity:
5062+
case Kind::TupleElement:
50445063
llvm_unreachable("no subscript labels for this kind");
50455064
}
50465065
llvm_unreachable("unhandled kind");
@@ -5052,7 +5071,7 @@ class KeyPathExpr : public Expr {
50525071
case Kind::Subscript:
50535072
if (!SubscriptHashableConformancesData)
50545073
return {};
5055-
return {SubscriptHashableConformancesData, (size_t)SubscriptSize};
5074+
return {SubscriptHashableConformancesData, (size_t)technicated.SubscriptSize};
50565075

50575076
case Kind::UnresolvedSubscript:
50585077
case Kind::Invalid:
@@ -5062,6 +5081,7 @@ class KeyPathExpr : public Expr {
50625081
case Kind::UnresolvedProperty:
50635082
case Kind::Property:
50645083
case Kind::Identity:
5084+
case Kind::TupleElement:
50655085
return {};
50665086
}
50675087
llvm_unreachable("unhandled kind");
@@ -5083,6 +5103,7 @@ class KeyPathExpr : public Expr {
50835103
case Kind::OptionalForce:
50845104
case Kind::Property:
50855105
case Kind::Identity:
5106+
case Kind::TupleElement:
50865107
llvm_unreachable("no unresolved name for this kind");
50875108
}
50885109
llvm_unreachable("unhandled kind");
@@ -5101,10 +5122,30 @@ class KeyPathExpr : public Expr {
51015122
case Kind::OptionalWrap:
51025123
case Kind::OptionalForce:
51035124
case Kind::Identity:
5125+
case Kind::TupleElement:
51045126
llvm_unreachable("no decl ref for this kind");
51055127
}
51065128
llvm_unreachable("unhandled kind");
51075129
}
5130+
5131+
unsigned getFieldNumber() const {
5132+
switch (getKind()) {
5133+
case Kind::TupleElement:
5134+
return technicated.FieldNumber;
5135+
5136+
case Kind::Invalid:
5137+
case Kind::UnresolvedProperty:
5138+
case Kind::UnresolvedSubscript:
5139+
case Kind::OptionalChain:
5140+
case Kind::OptionalWrap:
5141+
case Kind::OptionalForce:
5142+
case Kind::Identity:
5143+
case Kind::Property:
5144+
case Kind::Subscript:
5145+
llvm_unreachable("no field number for this kind");
5146+
}
5147+
llvm_unreachable("unhandled kind");
5148+
}
51085149

51095150
Type getComponentType() const {
51105151
return ComponentType;

lib/AST/ASTDumper.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2618,6 +2618,11 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
26182618
OS << "identity";
26192619
OS << '\n';
26202620
break;
2621+
case KeyPathExpr::Component::Kind::TupleElement:
2622+
OS << "tuple_element ";
2623+
OS << "#" << component.getFieldNumber();
2624+
OS << " ";
2625+
break;
26212626
}
26222627
OS << "type=";
26232628
component.getComponentType().print(OS);

lib/AST/ASTWalker.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,6 +1034,7 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
10341034
case KeyPathExpr::Component::Kind::UnresolvedProperty:
10351035
case KeyPathExpr::Component::Kind::Invalid:
10361036
case KeyPathExpr::Component::Kind::Identity:
1037+
case KeyPathExpr::Component::Kind::TupleElement:
10371038
// No subexpr to visit.
10381039
break;
10391040
}

lib/AST/Expr.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,6 +2185,7 @@ KeyPathExpr::Component::Component(ASTContext *ctxForCopyingLabels,
21852185
Expr *indexExpr,
21862186
ArrayRef<Identifier> subscriptLabels,
21872187
ArrayRef<ProtocolConformanceRef> indexHashables,
2188+
unsigned fieldNumber,
21882189
Kind kind,
21892190
Type type,
21902191
SourceLoc loc)
@@ -2193,10 +2194,16 @@ KeyPathExpr::Component::Component(ASTContext *ctxForCopyingLabels,
21932194
{
21942195
assert(subscriptLabels.size() == indexHashables.size()
21952196
|| indexHashables.empty());
2197+
assert(subscriptLabels.empty() || fieldNumber == 0);
21962198
SubscriptLabelsData = subscriptLabels.data();
21972199
SubscriptHashableConformancesData = indexHashables.empty()
21982200
? nullptr : indexHashables.data();
2199-
SubscriptSize = subscriptLabels.size();
2201+
2202+
if (subscriptLabels.empty()) {
2203+
technicated.FieldNumber = fieldNumber;
2204+
} else {
2205+
technicated.SubscriptSize = subscriptLabels.size();
2206+
}
22002207
}
22012208

22022209
KeyPathExpr::Component
@@ -2205,15 +2212,15 @@ KeyPathExpr::Component::forSubscriptWithPrebuiltIndexExpr(
22052212
Type elementType, SourceLoc loc,
22062213
ArrayRef<ProtocolConformanceRef> indexHashables) {
22072214
return Component(&elementType->getASTContext(),
2208-
subscript, index, labels, indexHashables,
2215+
subscript, index, labels, indexHashables, 0,
22092216
Kind::Subscript, elementType, loc);
22102217
}
22112218

22122219
void KeyPathExpr::Component::setSubscriptIndexHashableConformances(
22132220
ArrayRef<ProtocolConformanceRef> hashables) {
22142221
switch (getKind()) {
22152222
case Kind::Subscript:
2216-
assert(hashables.size() == SubscriptSize);
2223+
assert(hashables.size() == technicated.SubscriptSize);
22172224
SubscriptHashableConformancesData = getComponentType()->getASTContext()
22182225
.AllocateCopy(hashables)
22192226
.data();
@@ -2227,6 +2234,7 @@ void KeyPathExpr::Component::setSubscriptIndexHashableConformances(
22272234
case Kind::UnresolvedProperty:
22282235
case Kind::Property:
22292236
case Kind::Identity:
2237+
case Kind::TupleElement:
22302238
llvm_unreachable("no hashable conformances for this kind");
22312239
}
22322240
}

lib/IDE/SourceEntityWalker.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,11 @@ std::pair<bool, Expr *> SemaAnnotator::walkToExprPre(Expr *E) {
361361
break;
362362
}
363363

364+
case KeyPathExpr::Component::Kind::TupleElement: {
365+
llvm_unreachable("[technicated]");
366+
break;
367+
}
368+
364369
case KeyPathExpr::Component::Kind::Invalid:
365370
case KeyPathExpr::Component::Kind::UnresolvedProperty:
366371
case KeyPathExpr::Component::Kind::UnresolvedSubscript:

lib/SILGen/SILGen.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
359359
CanType baseTy,
360360
bool forPropertyDescriptor);
361361

362+
KeyPathPatternComponent
363+
emitKeyPathComponentForTupleElement();
364+
362365
/// Known functions for bridging.
363366
SILDeclRef getStringToNSStringFn();
364367
SILDeclRef getNSStringToStringFn();

lib/SILGen/SILGenExpr.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3574,6 +3574,11 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
35743574
llvm_unreachable("unknown kind of storage");
35753575
}
35763576

3577+
KeyPathPatternComponent
3578+
SILGenModule::emitKeyPathComponentForTupleElement() {
3579+
llvm_unreachable("technicated");
3580+
}
3581+
35773582
RValue RValueEmitter::visitKeyPathExpr(KeyPathExpr *E, SGFContext C) {
35783583
if (E->isObjC()) {
35793584
return visit(E->getObjCStringLiteralExpr(), C);
@@ -3643,7 +3648,16 @@ RValue RValueEmitter::visitKeyPathExpr(KeyPathExpr *E, SGFContext C) {
36433648

36443649
break;
36453650
}
3646-
3651+
3652+
case KeyPathExpr::Component::Kind::TupleElement: {
3653+
loweredComponents.push_back(
3654+
SGF.SGM.emitKeyPathComponentForTupleElement());
3655+
3656+
baseTy = loweredComponents.back().getComponentType();
3657+
3658+
break;
3659+
}
3660+
36473661
case KeyPathExpr::Component::Kind::OptionalChain:
36483662
case KeyPathExpr::Component::Kind::OptionalForce:
36493663
case KeyPathExpr::Component::Kind::OptionalWrap: {

0 commit comments

Comments
 (0)