Skip to content

Commit 68ceda4

Browse files
authored
Merge pull request #62766 from hborla/pack-expansion-syntax
[Variadic Generics] Change pack expansion types and expressions to use the `repeat` syntax.
2 parents 18789aa + 6e28f99 commit 68ceda4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+578
-506
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/Expr.h

Lines changed: 13 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -350,11 +350,6 @@ class alignas(8) Expr : public ASTAllocated<Expr> {
350350
IsObjC : 1
351351
);
352352

353-
SWIFT_INLINE_BITFIELD_FULL(PackExpansionExpr, Expr, 32,
354-
: NumPadBits,
355-
NumBindings : 32
356-
);
357-
358353
SWIFT_INLINE_BITFIELD_FULL(SequenceExpr, Expr, 32,
359354
: NumPadBits,
360355
NumElements : 32
@@ -3599,39 +3594,23 @@ class PackElementExpr final : public Expr {
35993594
/// that naturally accept a comma-separated list of values, including
36003595
/// call argument lists, the elements of a tuple value, and the source
36013596
/// of a for-in loop.
3602-
class PackExpansionExpr final : public Expr,
3603-
private llvm::TrailingObjects<PackExpansionExpr, PackElementExpr *> {
3604-
friend TrailingObjects;
3605-
3597+
class PackExpansionExpr final : public Expr {
3598+
SourceLoc RepeatLoc;
36063599
Expr *PatternExpr;
3607-
SourceLoc DotsLoc;
36083600
GenericEnvironment *Environment;
36093601

3610-
PackExpansionExpr(Expr *patternExpr,
3611-
ArrayRef<PackElementExpr *> packElements,
3612-
SourceLoc dotsLoc,
3602+
PackExpansionExpr(SourceLoc repeatLoc,
3603+
Expr *patternExpr,
36133604
GenericEnvironment *environment,
36143605
bool implicit, Type type)
36153606
: Expr(ExprKind::PackExpansion, implicit, type),
3616-
PatternExpr(patternExpr), DotsLoc(dotsLoc), Environment(environment) {
3617-
Bits.PackExpansionExpr.NumBindings = packElements.size();
3618-
std::uninitialized_copy(packElements.begin(), packElements.end(),
3619-
getTrailingObjects<PackElementExpr *>());
3620-
}
3621-
3622-
size_t numTrailingObjects(OverloadToken<PackElementExpr *>) const {
3623-
return getNumBindings();
3624-
}
3625-
3626-
MutableArrayRef<PackElementExpr *> getMutableBindings() {
3627-
return {getTrailingObjects<PackElementExpr *>(), getNumBindings()};
3628-
}
3607+
RepeatLoc(repeatLoc), PatternExpr(patternExpr),
3608+
Environment(environment) {}
36293609

36303610
public:
36313611
static PackExpansionExpr *create(ASTContext &ctx,
3612+
SourceLoc repeatLoc,
36323613
Expr *patternExpr,
3633-
ArrayRef<PackElementExpr *> packElements,
3634-
SourceLoc dotsLoc,
36353614
GenericEnvironment *environment,
36363615
bool implicit = false,
36373616
Type type = Type());
@@ -3642,26 +3621,22 @@ class PackExpansionExpr final : public Expr,
36423621
PatternExpr = patternExpr;
36433622
}
36443623

3645-
unsigned getNumBindings() const {
3646-
return Bits.PackExpansionExpr.NumBindings;
3647-
}
3648-
3649-
ArrayRef<PackElementExpr *> getPackElements() {
3650-
return {getTrailingObjects<PackElementExpr *>(), getNumBindings()};
3651-
}
3652-
36533624
void getExpandedPacks(SmallVectorImpl<ASTNode> &packs);
36543625

36553626
GenericEnvironment *getGenericEnvironment() {
36563627
return Environment;
36573628
}
36583629

3630+
void setGenericEnvironment(GenericEnvironment *env) {
3631+
Environment = env;
3632+
}
3633+
36593634
SourceLoc getStartLoc() const {
3660-
return PatternExpr->getStartLoc();
3635+
return RepeatLoc;
36613636
}
36623637

36633638
SourceLoc getEndLoc() const {
3664-
return DotsLoc;
3639+
return PatternExpr->getEndLoc();
36653640
}
36663641

36673642
static bool classof(const Expr *E) {

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)

include/swift/Sema/ConstraintLocator.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -690,21 +690,6 @@ class LocatorPathElt::PackElement final : public StoredIntegerElement<1> {
690690
}
691691
};
692692

693-
class LocatorPathElt::OpenedPackElement final
694-
: public StoredPointerElement<GenericEnvironment> {
695-
public:
696-
OpenedPackElement(GenericEnvironment *env)
697-
: StoredPointerElement(PathElementKind::OpenedPackElement, env) {}
698-
699-
GenericEnvironment *getGenericEnvironment() const {
700-
return getStoredPointer();
701-
}
702-
703-
static bool classof(const LocatorPathElt *elt) {
704-
return elt->getKind() == PathElementKind::OpenedPackElement;
705-
}
706-
};
707-
708693
class LocatorPathElt::KeyPathComponent final : public StoredIntegerElement<1> {
709694
public:
710695
KeyPathComponent(unsigned index)

include/swift/Sema/ConstraintLocatorPathElts.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,6 @@ CUSTOM_LOCATOR_PATH_ELT(PackType)
195195
/// An element of a pack type - the T in <T, U, V, ...>
196196
CUSTOM_LOCATOR_PATH_ELT(PackElement)
197197

198-
/// Stores the generic environment for an opened pack element.
199-
CUSTOM_LOCATOR_PATH_ELT(OpenedPackElement)
200-
201198
/// The shape of a parameter pack.
202199
SIMPLE_LOCATOR_PATH_ELT(PackShape)
203200

include/swift/Sema/ConstraintSystem.h

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,6 +1494,10 @@ class Solution {
14941494
llvm::DenseMap<ConstraintLocator *, OpenedArchetypeType *>
14951495
OpenedExistentialTypes;
14961496

1497+
/// The pack expansion environment that can open pack elements for
1498+
/// a given locator.
1499+
llvm::DenseMap<ConstraintLocator *, UUID> PackExpansionEnvironments;
1500+
14971501
/// The locators of \c Defaultable constraints whose defaults were used.
14981502
llvm::SmallPtrSet<ConstraintLocator *, 2> DefaultedConstraints;
14991503

@@ -3021,6 +3025,8 @@ class ConstraintSystem {
30213025
llvm::SmallMapVector<ConstraintLocator *, OpenedArchetypeType *, 4>
30223026
OpenedExistentialTypes;
30233027

3028+
llvm::SmallMapVector<ConstraintLocator *, UUID, 4> PackExpansionEnvironments;
3029+
30243030
/// The set of functions that have been transformed by a result builder.
30253031
llvm::MapVector<AnyFunctionRef, AppliedBuilderTransform>
30263032
resultBuilderTransformed;
@@ -3496,6 +3502,9 @@ class ConstraintSystem {
34963502
/// The length of \c OpenedExistentialTypes.
34973503
unsigned numOpenedExistentialTypes;
34983504

3505+
/// The length of \c PackExpansionEnvironments.
3506+
unsigned numPackExpansionEnvironments;
3507+
34993508
/// The length of \c DefaultedConstraints.
35003509
unsigned numDefaultedConstraints;
35013510

@@ -3974,6 +3983,12 @@ class ConstraintSystem {
39743983
std::pair<Type, OpenedArchetypeType *> openExistentialType(
39753984
Type type, ConstraintLocator *locator);
39763985

3986+
/// Add the given pack expansion as an opened pack element environment.
3987+
void addPackElementEnvironment(PackExpansionExpr *expr);
3988+
3989+
/// Get the opened element generic environment for the given locator.
3990+
GenericEnvironment *getPackElementEnvironment(ConstraintLocator *locator);
3991+
39773992
/// Retrieve the constraint locator for the given anchor and
39783993
/// path, uniqued and automatically infer the summary flags
39793994
ConstraintLocator *
@@ -6124,12 +6139,12 @@ class HandlePlaceholderType {
61246139
class OpenPackElementType {
61256140
ConstraintSystem &cs;
61266141
ConstraintLocator *locator;
6127-
GenericEnvironment *elementEnv;
6142+
PackExpansionExpr *elementEnv;
61286143

61296144
public:
61306145
explicit OpenPackElementType(ConstraintSystem &cs,
61316146
const ConstraintLocatorBuilder &locator,
6132-
GenericEnvironment *elementEnv)
6147+
PackExpansionExpr *elementEnv)
61336148
: cs(cs), elementEnv(elementEnv) {
61346149
this->locator = cs.getConstraintLocator(locator);
61356150
}
@@ -6141,9 +6156,9 @@ class OpenPackElementType {
61416156
// element.
61426157
assert(elementEnv);
61436158

6144-
auto *elementType = cs.createTypeVariable(locator, TVO_CanBindToHole);
6145-
auto elementLoc = cs.getConstraintLocator(locator,
6146-
LocatorPathElt::OpenedPackElement(elementEnv));
6159+
auto *elementType = cs.createTypeVariable(locator,
6160+
TVO_CanBindToHole |
6161+
TVO_CanBindToNoEscape);
61476162

61486163
// If we're opening a pack element from an explicit type repr,
61496164
// set the type repr types in the constraint system for generating
@@ -6154,7 +6169,7 @@ class OpenPackElementType {
61546169
}
61556170

61566171
cs.addConstraint(ConstraintKind::PackElementOf, elementType,
6157-
packType, elementLoc);
6172+
packType, cs.getConstraintLocator(elementEnv));
61586173
return elementType;
61596174
}
61606175
};

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/ASTVerifier.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -839,13 +839,10 @@ class Verifier : public ASTWalker {
839839
return true;
840840
}
841841

842-
void verifyCheckedAlways(PackExpansionExpr *E) {
843-
// Remove the element generic environment before verifying
844-
// the pack expansion type, which contains pack archetypes.
842+
void cleanup(PackExpansionExpr *E) {
845843
assert(Generics.back().get<GenericEnvironment *>() ==
846844
E->getGenericEnvironment());
847845
Generics.pop_back();
848-
verifyCheckedAlwaysBase(E);
849846
}
850847

851848
bool shouldVerify(MakeTemporarilyEscapableExpr *expr) {

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/Expr.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,16 +1250,11 @@ VarargExpansionExpr *VarargExpansionExpr::createArrayExpansion(ASTContext &ctx,
12501250
}
12511251

12521252
PackExpansionExpr *
1253-
PackExpansionExpr::create(ASTContext &ctx, Expr *patternExpr,
1254-
ArrayRef<PackElementExpr *> packElements,
1255-
SourceLoc dotsLoc, GenericEnvironment *environment,
1253+
PackExpansionExpr::create(ASTContext &ctx, SourceLoc repeatLoc,
1254+
Expr *patternExpr, GenericEnvironment *environment,
12561255
bool implicit, Type type) {
1257-
size_t size =
1258-
totalSizeToAlloc<PackElementExpr *>(packElements.size());
1259-
void *mem = ctx.Allocate(size, alignof(PackExpansionExpr));
1260-
return ::new (mem) PackExpansionExpr(patternExpr, packElements,
1261-
dotsLoc, environment,
1262-
implicit, type);
1256+
return new (ctx) PackExpansionExpr(repeatLoc, patternExpr, environment,
1257+
implicit, type);
12631258
}
12641259

12651260
void PackExpansionExpr::getExpandedPacks(SmallVectorImpl<ASTNode> &packs) {

0 commit comments

Comments
 (0)