Skip to content

Commit c444a62

Browse files
committed
[AST] Add 'PackElementExpr' for explicit pack elements spelled with the 'each'
keyword.
1 parent ebdee42 commit c444a62

File tree

9 files changed

+86
-0
lines changed

9 files changed

+86
-0
lines changed

include/swift/AST/Expr.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3515,6 +3515,50 @@ class VarargExpansionExpr : public Expr {
35153515
}
35163516
};
35173517

3518+
/// A pack element expression spelled with the contextual \c each
3519+
/// keyword applied to a pack reference expression.
3520+
///
3521+
/// \code
3522+
/// func zip<T..., U...>(t: (each T)..., u: (each U)...) {
3523+
/// let zipped = (each t, each u)...
3524+
/// }
3525+
/// \endcode
3526+
///
3527+
/// Pack elements can only appear in the pattern expression of a
3528+
/// \c PackExpansionExpr.
3529+
class PackElementExpr final : public Expr {
3530+
SourceLoc EachLoc;
3531+
Expr *PackRefExpr;
3532+
3533+
PackElementExpr(SourceLoc eachLoc, Expr *packRefExpr,
3534+
bool implicit = false, Type type = Type())
3535+
: Expr(ExprKind::PackElement, implicit, type),
3536+
EachLoc(eachLoc), PackRefExpr(packRefExpr) {}
3537+
3538+
public:
3539+
static PackElementExpr *create(ASTContext &ctx, SourceLoc eachLoc,
3540+
Expr *packRefExpr, bool implicit = false,
3541+
Type type = Type());
3542+
3543+
Expr *getPackRefExpr() const { return PackRefExpr; }
3544+
3545+
void setPackRefExpr(Expr *packRefExpr) {
3546+
PackRefExpr = packRefExpr;
3547+
}
3548+
3549+
SourceLoc getStartLoc() const {
3550+
return EachLoc;
3551+
}
3552+
3553+
SourceLoc getEndLoc() const {
3554+
return PackRefExpr->getEndLoc();
3555+
}
3556+
3557+
static bool classof(const Expr *E) {
3558+
return E->getKind() == ExprKind::PackElement;
3559+
}
3560+
};
3561+
35183562
/// A pack expansion expression is a pattern expression followed by
35193563
/// the expansion operator '...'. The pattern expression contains
35203564
/// references to parameter packs of length N, and the expansion

include/swift/AST/ExprNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ ABSTRACT_EXPR(AbstractClosure, Expr)
130130
EXPR(InOut, Expr)
131131
EXPR(VarargExpansion, Expr)
132132
EXPR(PackExpansion, Expr)
133+
EXPR(PackElement, Expr)
133134
EXPR(DynamicType, Expr)
134135
EXPR(RebindSelfInConstructor, Expr)
135136
EXPR(OpaqueValue, Expr)

lib/AST/ASTDumper.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2504,6 +2504,12 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
25042504
PrintWithColorRAII(OS, ParenthesisColor) << ')';
25052505
}
25062506

2507+
void visitPackElementExpr(PackElementExpr *E) {
2508+
printCommon(E, "pack_element_expr") << "\n";
2509+
printRec(E->getPackRefExpr());
2510+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
2511+
}
2512+
25072513
void visitForceTryExpr(ForceTryExpr *E) {
25082514
printCommon(E, "force_try_expr");
25092515
OS << '\n';

lib/AST/ASTPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4858,6 +4858,10 @@ void PrintAST::visitPackExpansionExpr(PackExpansionExpr *expr) {
48584858
visit(expr->getPatternExpr());
48594859
}
48604860

4861+
void PrintAST::visitPackElementExpr(PackElementExpr *expr) {
4862+
visit(expr->getPackRefExpr());
4863+
}
4864+
48614865
void PrintAST::visitArchetypeToSuperExpr(ArchetypeToSuperExpr *expr) {
48624866
}
48634867

lib/AST/ASTWalker.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,14 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
859859
return nullptr;
860860
}
861861

862+
Expr *visitPackElementExpr(PackElementExpr *E) {
863+
if (Expr *pattern = doIt(E->getPackRefExpr())) {
864+
E->setPackRefExpr(pattern);
865+
return E;
866+
}
867+
return nullptr;
868+
}
869+
862870
Expr *visitSequenceExpr(SequenceExpr *E) {
863871
for (unsigned i = 0, e = E->getNumElements(); i != e; ++i)
864872
if (Expr *Elt = doIt(E->getElement(i)))

lib/AST/Expr.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ ConcreteDeclRef Expr::getReferencedDecl(bool stopAtParenExpr) const {
394394

395395
NO_REFERENCE(VarargExpansion);
396396
NO_REFERENCE(PackExpansion);
397+
NO_REFERENCE(PackElement);
397398
NO_REFERENCE(DynamicType);
398399

399400
PASS_THROUGH_REFERENCE(RebindSelfInConstructor, getSubExpr);
@@ -750,6 +751,7 @@ bool Expr::canAppendPostfixExpression(bool appendingPostfixOperator) const {
750751
case ExprKind::MakeTemporarilyEscapable:
751752
case ExprKind::VarargExpansion:
752753
case ExprKind::PackExpansion:
754+
case ExprKind::PackElement:
753755
return false;
754756

755757
case ExprKind::Call:
@@ -927,6 +929,7 @@ bool Expr::isValidParentOfTypeExpr(Expr *typeExpr) const {
927929
case ExprKind::InOut:
928930
case ExprKind::VarargExpansion:
929931
case ExprKind::PackExpansion:
932+
case ExprKind::PackElement:
930933
case ExprKind::DynamicType:
931934
case ExprKind::RebindSelfInConstructor:
932935
case ExprKind::OpaqueValue:
@@ -1258,6 +1261,12 @@ PackExpansionExpr::create(ASTContext &ctx, Expr *patternExpr,
12581261
implicit, type);
12591262
}
12601263

1264+
PackElementExpr *
1265+
PackElementExpr::create(ASTContext &ctx, SourceLoc eachLoc, Expr *packRefExpr,
1266+
bool implicit, Type type) {
1267+
return new (ctx) PackElementExpr(eachLoc, packRefExpr, implicit, type);
1268+
}
1269+
12611270
SequenceExpr *SequenceExpr::create(ASTContext &ctx, ArrayRef<Expr*> elements) {
12621271
assert(elements.size() & 1 && "even number of elements in sequence");
12631272
size_t bytes = totalSizeToAlloc<Expr *>(elements.size());

lib/SILGen/SILGenExpr.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ namespace {
444444
SGFContext C);
445445
RValue visitBridgeToObjCExpr(BridgeToObjCExpr *E, SGFContext C);
446446
RValue visitPackExpansionExpr(PackExpansionExpr *E, SGFContext C);
447+
RValue visitPackElementExpr(PackElementExpr *E, SGFContext C);
447448
RValue visitBridgeFromObjCExpr(BridgeFromObjCExpr *E, SGFContext C);
448449
RValue visitConditionalBridgeFromObjCExpr(ConditionalBridgeFromObjCExpr *E,
449450
SGFContext C);
@@ -1515,6 +1516,11 @@ RValueEmitter::visitPackExpansionExpr(PackExpansionExpr *E,
15151516
llvm_unreachable("not implemented for PackExpansionExpr");
15161517
}
15171518

1519+
RValue
1520+
RValueEmitter::visitPackElementExpr(PackElementExpr *E, SGFContext C) {
1521+
llvm_unreachable("not implemented for PackElementExpr");
1522+
}
1523+
15181524
RValue RValueEmitter::visitArchetypeToSuperExpr(ArchetypeToSuperExpr *E,
15191525
SGFContext C) {
15201526
ManagedValue archetype = SGF.emitRValueAsSingleValue(E->getSubExpr());

lib/Sema/CSApply.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3829,6 +3829,10 @@ namespace {
38293829
return expr;
38303830
}
38313831

3832+
Expr *visitPackElementExpr(PackElementExpr *expr) {
3833+
llvm_unreachable("not implemented for PackElementExpr");
3834+
}
3835+
38323836
Expr *visitDynamicTypeExpr(DynamicTypeExpr *expr) {
38333837
Expr *base = expr->getBase();
38343838
base = cs.coerceToRValue(base);

lib/Sema/CSGen.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2984,6 +2984,10 @@ namespace {
29842984
return PackExpansionType::get(patternTy, shapeTypeVar);
29852985
}
29862986

2987+
Type visitPackElementExpr(PackElementExpr *expr) {
2988+
llvm_unreachable("not implemented for PackElementExpr");
2989+
}
2990+
29872991
Type visitDynamicTypeExpr(DynamicTypeExpr *expr) {
29882992
auto tv = CS.createTypeVariable(CS.getConstraintLocator(expr),
29892993
TVO_CanBindToNoEscape);

0 commit comments

Comments
 (0)