Skip to content

Commit 74bf2f3

Browse files
committed
[AST] Introduce a syntactic distinction betweek vararg type reprs and
pack expansion type reprs. Classic variadic parameters still use the postfix ellipsis syntax, and pack expansion types now use a prefix 'repeat' keyword.
1 parent 89fa17d commit 74bf2f3

17 files changed

+158
-76
lines changed

include/swift/AST/CASTBridging.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ void *ImplicitlyUnwrappedOptionalTypeRepr_create(void *ctx, void *base,
239239
void *exclamationLoc);
240240
void *MetatypeTypeRepr_create(void *ctx, void *baseType, void *typeLoc);
241241
void *ProtocolTypeRepr_create(void *ctx, void *baseType, void *protoLoc);
242-
void *PackExpansionTypeRepr_create(void *ctx, void *base, void *ellipsisLoc);
242+
void *PackExpansionTypeRepr_create(void *ctx, void *base, void *repeatLoc);
243243
void *TupleTypeRepr_create(void *ctx, BridgedArrayRef elements, void *lParenLoc,
244244
void *rParenLoc);
245245
void *DeclRefTypeRepr_create(void *ctx, BridgedArrayRef bridgedComponents);

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5163,6 +5163,9 @@ ERROR(dot_protocol_on_non_existential,none,
51635163
"cannot use 'Protocol' with non-protocol type %0", (Type))
51645164
ERROR(tuple_single_element,none,
51655165
"cannot create a single-element tuple with an element label", ())
5166+
ERROR(vararg_not_allowed,none,
5167+
"variadic parameter cannot appear outside of a function parameter list",
5168+
())
51665169
ERROR(expansion_not_allowed,none,
51675170
"variadic expansion %0 cannot appear outside of a function parameter list, "
51685171
"function result, tuple element or generic argument list", (Type))

include/swift/AST/TypeRepr.h

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,32 @@ struct TupleTypeReprElement {
693693
TupleTypeReprElement(TypeRepr *Type): Type(Type) {}
694694
};
695695

696+
/// A vararg type 'T...' with element type 'T'.
697+
class VarargTypeRepr final : public TypeRepr {
698+
TypeRepr *Element;
699+
SourceLoc EllipsisLoc;
700+
701+
public:
702+
VarargTypeRepr(TypeRepr *Element, SourceLoc EllipsisLoc)
703+
: TypeRepr(TypeReprKind::Vararg), Element(Element),
704+
EllipsisLoc(EllipsisLoc) {}
705+
706+
TypeRepr *getElementType() const { return Element; }
707+
SourceLoc getEllipsisLoc() const { return EllipsisLoc; }
708+
709+
static bool classof(const TypeRepr *T) {
710+
return T->getKind() == TypeReprKind::Vararg;
711+
}
712+
static bool classof(const VarargTypeRepr *T) { return true; }
713+
714+
private:
715+
SourceLoc getStartLocImpl() const { return Element->getEndLoc(); }
716+
SourceLoc getEndLocImpl() const { return EllipsisLoc; }
717+
SourceLoc getLocImpl() const { return EllipsisLoc; }
718+
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
719+
friend class TypeRepr;
720+
};
721+
696722
/// A pack expansion 'T...' with a pattern 'T'.
697723
///
698724
/// Can appear in the following positions:
@@ -708,26 +734,26 @@ struct TupleTypeReprElement {
708734
/// In the third case, tuples cannot contain an old-style variadic element,
709735
/// so the pack expansion must be a real variadic pack expansion.
710736
class PackExpansionTypeRepr final : public TypeRepr {
737+
SourceLoc RepeatLoc;
711738
TypeRepr *Pattern;
712-
SourceLoc EllipsisLoc;
713739

714740
public:
715-
PackExpansionTypeRepr(TypeRepr *Pattern, SourceLoc EllipsisLoc)
716-
: TypeRepr(TypeReprKind::PackExpansion), Pattern(Pattern),
717-
EllipsisLoc(EllipsisLoc) {}
741+
PackExpansionTypeRepr(SourceLoc RepeatLoc, TypeRepr *Pattern)
742+
: TypeRepr(TypeReprKind::PackExpansion), RepeatLoc(RepeatLoc),
743+
Pattern(Pattern) {}
718744

745+
SourceLoc getRepeatLoc() const { return RepeatLoc; }
719746
TypeRepr *getPatternType() const { return Pattern; }
720-
SourceLoc getEllipsisLoc() const { return EllipsisLoc; }
721747

722748
static bool classof(const TypeRepr *T) {
723749
return T->getKind() == TypeReprKind::PackExpansion;
724750
}
725751
static bool classof(const PackExpansionTypeRepr *T) { return true; }
726752

727753
private:
728-
SourceLoc getStartLocImpl() const { return Pattern->getStartLoc(); }
729-
SourceLoc getEndLocImpl() const { return EllipsisLoc; }
730-
SourceLoc getLocImpl() const { return EllipsisLoc; }
754+
SourceLoc getStartLocImpl() const { return RepeatLoc; }
755+
SourceLoc getEndLocImpl() const { return Pattern->getEndLoc(); }
756+
SourceLoc getLocImpl() const { return RepeatLoc; }
731757
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
732758
friend class TypeRepr;
733759
};
@@ -1370,6 +1396,7 @@ inline bool TypeRepr::isSimple() const {
13701396
case TypeReprKind::Dictionary:
13711397
case TypeReprKind::Optional:
13721398
case TypeReprKind::ImplicitlyUnwrappedOptional:
1399+
case TypeReprKind::Vararg:
13731400
case TypeReprKind::PackExpansion:
13741401
case TypeReprKind::Tuple:
13751402
case TypeReprKind::Fixed:

include/swift/AST/TypeReprNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ TYPEREPR(ImplicitlyUnwrappedOptional, TypeRepr)
5959
TYPEREPR(Tuple, TypeRepr)
6060
TYPEREPR(Composition, TypeRepr)
6161
TYPEREPR(Metatype, TypeRepr)
62+
TYPEREPR(Vararg, TypeRepr)
6263
TYPEREPR(PackExpansion, TypeRepr)
6364
TYPEREPR(Protocol, TypeRepr)
6465
TYPEREPR(OpaqueReturn, TypeRepr)

lib/AST/ASTDumper.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3168,6 +3168,12 @@ class PrintTypeRepr : public TypeReprVisitor<PrintTypeRepr> {
31683168
PrintWithColorRAII(OS, ParenthesisColor) << ')';
31693169
}
31703170

3171+
void visitVarargTypeRepr(VarargTypeRepr *T) {
3172+
printCommon("vararg") << '\n';
3173+
printRec(T->getElementType());
3174+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
3175+
}
3176+
31713177
void visitPackExpansionTypeRepr(PackExpansionTypeRepr *T) {
31723178
printCommon("pack_expansion") << '\n';
31733179
printRec(T->getPatternType());

lib/AST/ASTWalker.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,6 +2002,11 @@ bool Traversal::visitOptionalTypeRepr(OptionalTypeRepr *T) {
20022002
bool Traversal::visitImplicitlyUnwrappedOptionalTypeRepr(ImplicitlyUnwrappedOptionalTypeRepr *T) {
20032003
return doIt(T->getBase());
20042004
}
2005+
2006+
bool Traversal::visitVarargTypeRepr(VarargTypeRepr *T) {
2007+
return doIt(T->getElementType());
2008+
}
2009+
20052010
bool Traversal::visitPackExpansionTypeRepr(PackExpansionTypeRepr *T) {
20062011
return doIt(T->getPatternType());
20072012
}

lib/AST/CASTBridging.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,10 +466,10 @@ void *ProtocolTypeRepr_create(void *ctx, void *baseType, void *protoLoc) {
466466
return new (Context) ProtocolTypeRepr((TypeRepr *)baseType, protocolLoc);
467467
}
468468

469-
void *PackExpansionTypeRepr_create(void *ctx, void *base, void *ellipsisLoc) {
469+
void *PackExpansionTypeRepr_create(void *ctx, void *base, void *repeatLoc) {
470470
ASTContext &Context = *static_cast<ASTContext *>(ctx);
471471
return new (Context) PackExpansionTypeRepr(
472-
(TypeRepr *)base, getSourceLocFromPointer(ellipsisLoc));
472+
getSourceLocFromPointer(repeatLoc), (TypeRepr *)base);
473473
}
474474

475475
void *TupleTypeRepr_create(void *ctx, BridgedArrayRef elements, void *lParenLoc,

lib/AST/NameLookup.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2520,6 +2520,13 @@ directReferencesForTypeRepr(Evaluator &evaluator,
25202520
return { };
25212521
}
25222522

2523+
case TypeReprKind::Vararg: {
2524+
auto packExpansionRepr = cast<VarargTypeRepr>(typeRepr);
2525+
return directReferencesForTypeRepr(evaluator, ctx,
2526+
packExpansionRepr->getElementType(), dc,
2527+
allowUsableFromInline);
2528+
}
2529+
25232530
case TypeReprKind::PackExpansion: {
25242531
auto packExpansionRepr = cast<PackExpansionTypeRepr>(typeRepr);
25252532
return directReferencesForTypeRepr(evaluator, ctx,
@@ -2824,7 +2831,7 @@ CollectedOpaqueReprs swift::collectOpaqueReturnTypeReprs(TypeRepr *r, ASTContext
28242831
PreWalkAction walkToTypeReprPre(TypeRepr *repr) override {
28252832

28262833
// Don't allow variadic opaque parameter or return types.
2827-
if (isa<PackExpansionTypeRepr>(repr))
2834+
if (isa<PackExpansionTypeRepr>(repr) || isa<VarargTypeRepr>(repr))
28282835
return Action::SkipChildren();
28292836

28302837
if (auto opaqueRepr = dyn_cast<OpaqueReturnTypeRepr>(repr)) {

lib/AST/TypeRepr.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,10 +428,16 @@ SourceLoc SILBoxTypeRepr::getLocImpl() const {
428428
return LBraceLoc;
429429
}
430430

431+
void VarargTypeRepr::printImpl(ASTPrinter &Printer,
432+
const PrintOptions &Opts) const {
433+
printTypeRepr(Element, Printer, Opts);
434+
Printer << "...";
435+
}
436+
431437
void PackExpansionTypeRepr::printImpl(ASTPrinter &Printer,
432438
const PrintOptions &Opts) const {
439+
Printer.printKeyword("repeat", Opts, /*Suffix=*/" ");
433440
printTypeRepr(Pattern, Printer, Opts);
434-
Printer << "...";
435441
}
436442

437443
void PackReferenceTypeRepr::printImpl(ASTPrinter &Printer,

lib/ASTGen/Sources/ASTGen/Types.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ extension ASTGenVisitor {
118118

119119
public func visit(_ node: PackExpansionTypeSyntax) -> ASTNode {
120120
let base = visit(node.patternType).rawValue
121-
let ellipsisLoc = self.base.advanced(by: node.ellipsis.position.utf8Offset).raw
122-
return .type(PackExpansionTypeRepr_create(self.ctx, base, ellipsisLoc))
121+
let repeatLoc = self.base.advanced(by: node.repeatKeyword.position.utf8Offset).raw
122+
return .type(PackExpansionTypeRepr_create(self.ctx, base, repeatLoc))
123123
}
124124

125125
public func visit(_ node: TupleTypeSyntax) -> ASTNode {

0 commit comments

Comments
 (0)