Skip to content

Commit 7bf6803

Browse files
authored
Merge pull request #60923 from slavapestov/pack-expansion-type-repr
Introduce PackExpansionTypeRepr
2 parents f366263 + 78b337e commit 7bf6803

35 files changed

+494
-337
lines changed

include/swift/AST/Decl.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5904,10 +5904,8 @@ class ParamDecl : public VarDecl {
59045904

59055905
void setDefaultValueStringRepresentation(StringRef stringRepresentation);
59065906

5907-
/// Whether or not this parameter is varargs.
5908-
bool isVariadic() const {
5909-
return DefaultValueAndFlags.getInt().contains(Flags::IsVariadic);
5910-
}
5907+
/// Whether or not this parameter is old-style variadic.
5908+
bool isVariadic() const;
59115909
void setVariadic(bool value = true) {
59125910
auto flags = DefaultValueAndFlags.getInt();
59135911
DefaultValueAndFlags.setInt(value ? flags | Flags::IsVariadic

include/swift/AST/DiagnosticsParse.def

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -852,8 +852,6 @@ NOTE(subscript_array_element_fix_it_remove_space, none,
852852
// Tuple Types
853853
ERROR(expected_rparen_tuple_type_list,none,
854854
"expected ')' at end of tuple list", ())
855-
ERROR(multiple_ellipsis_in_tuple,none,
856-
"only a single element can be variadic", ())
857855
ERROR(tuple_type_init,none,
858856
"default argument not permitted in a tuple type", ())
859857
ERROR(protocol_method_argument_init,none,
@@ -959,8 +957,6 @@ ERROR(expected_parameter_colon,PointsToFirstBadToken,
959957
"expected ':' following argument label and parameter name", ())
960958
ERROR(expected_assignment_instead_of_comparison_operator,none,
961959
"expected '=' instead of '==' to assign default value for parameter", ())
962-
ERROR(parameter_vararg_default,none,
963-
"variadic parameter cannot have a default value", ())
964960
ERROR(parameter_specifier_as_attr_disallowed,none,
965961
"'%0' before a parameter name is not allowed, place it before the parameter type instead",
966962
(StringRef))
@@ -995,11 +991,6 @@ ERROR(false_available_is_called_unavailable,none,
995991
ERROR(initializer_as_typed_pattern,none,
996992
"unexpected initializer in pattern; did you mean to use '='?", ())
997993

998-
ERROR(unlabeled_parameter_following_variadic_parameter,none,
999-
"a parameter following a variadic parameter requires a label", ())
1000-
ERROR(closure_unlabeled_parameter_following_variadic_parameter,none,
1001-
"no parameters may follow a variadic parameter in a closure", ())
1002-
1003994
ERROR(enum_element_empty_arglist,none,
1004995
"enum element with associated values must have at least one "
1005996
"associated value", ())

include/swift/AST/DiagnosticsSema.def

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5014,14 +5014,25 @@ ERROR(dot_protocol_on_non_existential,none,
50145014
"cannot use 'Protocol' with non-protocol type %0", (Type))
50155015
ERROR(tuple_single_element,none,
50165016
"cannot create a single-element tuple with an element label", ())
5017-
ERROR(tuple_ellipsis,none,
5018-
"cannot create a variadic tuple", ())
5017+
ERROR(expansion_not_allowed,none,
5018+
"variadic expansion %0 cannot appear outside of a function parameter list, "
5019+
"function result, tuple element or generic argument list", (Type))
50195020
ERROR(expansion_not_variadic,none,
5020-
"cannot create expansion with non-variadic type %0", (Type))
5021+
"variadic expansion %0 must contain at least one variadic generic parameter", (Type))
50215022
ERROR(tuple_duplicate_label,none,
50225023
"cannot create a tuple with a duplicate element label", ())
5024+
ERROR(multiple_ellipsis_in_tuple,none,
5025+
"only a single element can be variadic", ())
5026+
50235027
ERROR(enum_element_ellipsis,none,
50245028
"variadic enum cases are not supported", ())
5029+
ERROR(unlabeled_parameter_following_variadic_parameter,none,
5030+
"a parameter following a variadic parameter requires a label", ())
5031+
ERROR(closure_unlabeled_parameter_following_variadic_parameter,none,
5032+
"no parameters may follow a variadic parameter in a closure", ())
5033+
5034+
ERROR(parameter_vararg_default,none,
5035+
"variadic parameter cannot have a default value", ())
50255036

50265037
WARNING(implicitly_unwrapped_optional_in_illegal_position_interpreted_as_optional,none,
50275038
"using '!' is not allowed here; treating this as '?' instead", ())
@@ -5142,8 +5153,6 @@ ERROR(opened_bad_constraint_type,none,
51425153
"@opened constraint type %0 is not a protocol or protocol composition", (Type))
51435154
ERROR(opened_bad_interface_type,none,
51445155
"@opened interface type %0 is not a type parameter", (Type))
5145-
ERROR(sil_function_ellipsis,PointsToFirstBadToken,
5146-
"SIL function types cannot be variadic", ())
51475156
ERROR(sil_function_input_label,PointsToFirstBadToken,
51485157
"SIL function types cannot have labeled inputs", ())
51495158
ERROR(sil_function_output_label,PointsToFirstBadToken,

include/swift/AST/TypeRepr.h

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,7 @@ class alignas(1 << TypeReprAlignInBits) TypeRepr
7373
Warned : 1
7474
);
7575

76-
SWIFT_INLINE_BITFIELD_FULL(TupleTypeRepr, TypeRepr, 1+32,
77-
/// Whether this tuple has '...' and its position.
78-
HasEllipsis : 1,
79-
: NumPadBits,
76+
SWIFT_INLINE_BITFIELD_FULL(TupleTypeRepr, TypeRepr, 32,
8077
/// The number of elements contained.
8178
NumElements : 32
8279
);
@@ -708,26 +705,62 @@ struct TupleTypeReprElement {
708705
TupleTypeReprElement(TypeRepr *Type): Type(Type) {}
709706
};
710707

708+
/// A pack expansion 'T...' with a pattern 'T'.
709+
///
710+
/// Can appear in the following positions:
711+
/// - The type of a parameter declaration in a function declaration
712+
/// - The type of a parameter in a function type
713+
/// - The element of a tuple
714+
///
715+
/// In the first two cases, it also spells an old-style variadic parameter
716+
/// desugaring to an array type. The two meanings are distinguished by the
717+
/// presence of at least one pack type parameter in the pack expansion
718+
/// pattern.
719+
///
720+
/// In the third case, tuples cannot contain an old-style variadic element,
721+
/// so the pack expansion must be a real variadic pack expansion.
722+
class PackExpansionTypeRepr final : public TypeRepr {
723+
TypeRepr *Pattern;
724+
SourceLoc EllipsisLoc;
725+
726+
public:
727+
PackExpansionTypeRepr(TypeRepr *Pattern, SourceLoc EllipsisLoc)
728+
: TypeRepr(TypeReprKind::PackExpansion), Pattern(Pattern),
729+
EllipsisLoc(EllipsisLoc) {}
730+
731+
TypeRepr *getPatternType() const { return Pattern; }
732+
SourceLoc getEllipsisLoc() const { return EllipsisLoc; }
733+
734+
static bool classof(const TypeRepr *T) {
735+
return T->getKind() == TypeReprKind::PackExpansion;
736+
}
737+
static bool classof(const PackExpansionTypeRepr *T) { return true; }
738+
739+
private:
740+
SourceLoc getStartLocImpl() const { return Pattern->getStartLoc(); }
741+
SourceLoc getEndLocImpl() const { return EllipsisLoc; }
742+
SourceLoc getLocImpl() const { return EllipsisLoc; }
743+
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
744+
friend class TypeRepr;
745+
};
746+
711747
/// A tuple type.
712748
/// \code
713749
/// (Foo, Bar)
714750
/// (x: Foo)
715751
/// (_ x: Foo)
716752
/// \endcode
717753
class TupleTypeRepr final : public TypeRepr,
718-
private llvm::TrailingObjects<TupleTypeRepr, TupleTypeReprElement,
719-
Located<unsigned>> {
754+
private llvm::TrailingObjects<TupleTypeRepr, TupleTypeReprElement> {
720755
friend TrailingObjects;
721-
typedef Located<unsigned> SourceLocAndIdx;
722756

723757
SourceRange Parens;
724758

725759
size_t numTrailingObjects(OverloadToken<TupleTypeReprElement>) const {
726760
return Bits.TupleTypeRepr.NumElements;
727761
}
728762

729-
TupleTypeRepr(ArrayRef<TupleTypeReprElement> Elements,
730-
SourceRange Parens, SourceLoc Ellipsis, unsigned EllipsisIdx);
763+
TupleTypeRepr(ArrayRef<TupleTypeReprElement> Elements, SourceRange Parens);
731764

732765
public:
733766
unsigned getNumElements() const { return Bits.TupleTypeRepr.NumElements; }
@@ -783,47 +816,15 @@ class TupleTypeRepr final : public TypeRepr,
783816

784817
SourceRange getParens() const { return Parens; }
785818

786-
bool hasEllipsis() const {
787-
return Bits.TupleTypeRepr.HasEllipsis;
788-
}
789-
790-
SourceLoc getEllipsisLoc() const {
791-
return hasEllipsis() ?
792-
getTrailingObjects<SourceLocAndIdx>()[0].Loc : SourceLoc();
793-
}
794-
795-
unsigned getEllipsisIndex() const {
796-
return hasEllipsis() ?
797-
getTrailingObjects<SourceLocAndIdx>()[0].Item :
798-
Bits.TupleTypeRepr.NumElements;
799-
}
800-
801-
void removeEllipsis() {
802-
if (hasEllipsis()) {
803-
Bits.TupleTypeRepr.HasEllipsis = false;
804-
getTrailingObjects<SourceLocAndIdx>()[0] = {
805-
getNumElements(),
806-
SourceLoc()
807-
};
808-
}
809-
}
810-
811819
bool isParenType() const {
812820
return Bits.TupleTypeRepr.NumElements == 1 &&
813821
getElementNameLoc(0).isInvalid() &&
814-
!hasEllipsis();
822+
!isa<PackExpansionTypeRepr>(getElementType(0));
815823
}
816824

817825
static TupleTypeRepr *create(const ASTContext &C,
818826
ArrayRef<TupleTypeReprElement> Elements,
819-
SourceRange Parens,
820-
SourceLoc Ellipsis, unsigned EllipsisIdx);
821-
static TupleTypeRepr *create(const ASTContext &C,
822-
ArrayRef<TupleTypeReprElement> Elements,
823-
SourceRange Parens) {
824-
return create(C, Elements, Parens,
825-
SourceLoc(), Elements.size());
826-
}
827+
SourceRange Parens);
827828
static TupleTypeRepr *createEmpty(const ASTContext &C, SourceRange Parens);
828829

829830
static bool classof(const TypeRepr *T) {
@@ -1339,6 +1340,7 @@ inline bool TypeRepr::isSimple() const {
13391340
case TypeReprKind::Dictionary:
13401341
case TypeReprKind::Optional:
13411342
case TypeReprKind::ImplicitlyUnwrappedOptional:
1343+
case TypeReprKind::PackExpansion:
13421344
case TypeReprKind::Tuple:
13431345
case TypeReprKind::Fixed:
13441346
case TypeReprKind::Array:

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(PackExpansion, TypeRepr)
6263
TYPEREPR(Protocol, TypeRepr)
6364
TYPEREPR(OpaqueReturn, TypeRepr)
6465
TYPEREPR(NamedOpaqueReturn, TypeRepr)

include/swift/Parse/Parser.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,10 @@ class Parser {
13161316
CustomAttribute,
13171317
};
13181318

1319+
ParserResult<TypeRepr> parseTypeScalar(
1320+
Diag<> MessageID,
1321+
ParseTypeReason reason);
1322+
13191323
ParserResult<TypeRepr> parseType();
13201324
ParserResult<TypeRepr> parseType(
13211325
Diag<> MessageID,
@@ -1433,9 +1437,6 @@ class Parser {
14331437
/// \p SecondName is the name.
14341438
SourceLoc SecondNameLoc;
14351439

1436-
/// The location of the '...', if present.
1437-
SourceLoc EllipsisLoc;
1438-
14391440
/// The first name.
14401441
Identifier FirstName;
14411442

lib/AST/ASTDumper.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -960,8 +960,9 @@ namespace {
960960
}
961961
}
962962

963-
if (P->isVariadic())
964-
OS << " variadic";
963+
if (P->hasInterfaceType())
964+
if (P->isVariadic())
965+
OS << " variadic";
965966

966967
if (P->isAutoClosure())
967968
OS << " autoclosure";
@@ -3088,6 +3089,12 @@ class PrintTypeRepr : public TypeReprVisitor<PrintTypeRepr> {
30883089
PrintWithColorRAII(OS, ParenthesisColor) << ')';
30893090
}
30903091

3092+
void visitPackExpansionTypeRepr(PackExpansionTypeRepr *T) {
3093+
printCommon("pack_expansion") << '\n';
3094+
printRec(T->getPatternType());
3095+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
3096+
}
3097+
30913098
void visitTupleTypeRepr(TupleTypeRepr *T) {
30923099
printCommon("type_tuple");
30933100

lib/AST/ASTPrinter.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3832,13 +3832,6 @@ void PrintAST::printOneParameter(const ParamDecl *param,
38323832
TheTypeLoc = TypeLoc::withoutLoc(param->getInterfaceType());
38333833
}
38343834

3835-
// If the parameter is variadic, we will print the "..." after it, but we have
3836-
// to strip off the added array type.
3837-
if (param->isVariadic() && TheTypeLoc.getType()) {
3838-
if (auto *BGT = TheTypeLoc.getType()->getAs<BoundGenericType>())
3839-
TheTypeLoc.setType(BGT->getGenericArgs()[0]);
3840-
}
3841-
38423835
{
38433836
Printer.printStructurePre(PrintStructureKind::FunctionParameterType);
38443837
SWIFT_DEFER {
@@ -3853,9 +3846,6 @@ void PrintAST::printOneParameter(const ParamDecl *param,
38533846

38543847
printTypeLocForImplicitlyUnwrappedOptional(
38553848
TheTypeLoc, param->isImplicitlyUnwrappedOptional());
3856-
3857-
if (param->isVariadic())
3858-
Printer << "...";
38593849
}
38603850

38613851
if (param->isDefaultArgument() && Options.PrintDefaultArgumentValue) {

lib/AST/ASTWalker.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,9 @@ bool Traversal::visitOptionalTypeRepr(OptionalTypeRepr *T) {
18791879
bool Traversal::visitImplicitlyUnwrappedOptionalTypeRepr(ImplicitlyUnwrappedOptionalTypeRepr *T) {
18801880
return doIt(T->getBase());
18811881
}
1882+
bool Traversal::visitPackExpansionTypeRepr(PackExpansionTypeRepr *T) {
1883+
return doIt(T->getPatternType());
1884+
}
18821885

18831886
bool Traversal::visitTupleTypeRepr(TupleTypeRepr *T) {
18841887
for (auto &elem : T->getElements()) {

lib/AST/Decl.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,10 +1873,6 @@ static bool isDefaultInitializable(const TypeRepr *typeRepr, ASTContext &ctx) {
18731873
// Tuple types are default-initializable if all of their element
18741874
// types are.
18751875
if (const auto tuple = dyn_cast<TupleTypeRepr>(typeRepr)) {
1876-
// ... but not variadic ones.
1877-
if (tuple->hasEllipsis())
1878-
return false;
1879-
18801876
for (const auto &elt : tuple->getElements()) {
18811877
if (!isDefaultInitializable(elt.Type, ctx))
18821878
return false;
@@ -6530,6 +6526,12 @@ bool ParamDecl::isAnonClosureParam() const {
65306526
return nameStr[0] == '$';
65316527
}
65326528

6529+
bool ParamDecl::isVariadic() const {
6530+
(void) getInterfaceType();
6531+
6532+
return DefaultValueAndFlags.getInt().contains(Flags::IsVariadic);
6533+
}
6534+
65336535
ParamDecl::Specifier ParamDecl::getSpecifier() const {
65346536
auto &ctx = getASTContext();
65356537

lib/AST/NameLookup.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2532,6 +2532,13 @@ directReferencesForTypeRepr(Evaluator &evaluator,
25322532
return { };
25332533
}
25342534

2535+
case TypeReprKind::PackExpansion: {
2536+
auto packExpansionRepr = cast<PackExpansionTypeRepr>(typeRepr);
2537+
return directReferencesForTypeRepr(evaluator, ctx,
2538+
packExpansionRepr->getPatternType(), dc,
2539+
allowUsableFromInline);
2540+
}
2541+
25352542
case TypeReprKind::Error:
25362543
case TypeReprKind::Function:
25372544
case TypeReprKind::InOut:
@@ -2804,10 +2811,6 @@ createOpaqueParameterGenericParams(
28042811
SmallVector<GenericTypeParamDecl *, 2> implicitGenericParams;
28052812
auto dc = value->getInnermostDeclContext();
28062813
for (auto param : *params) {
2807-
// Don't permit variadic parameters.
2808-
if (param->isVariadic())
2809-
continue;
2810-
28112814
auto typeRepr = param->getTypeRepr();
28122815
if (!typeRepr)
28132816
continue;

lib/AST/Type.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,8 +1315,7 @@ ParameterListInfo::ParameterListInfo(
13151315
inheritActorContext.set(i);
13161316
}
13171317

1318-
if (param->isVariadic() &&
1319-
param->getVarargBaseTy()->hasTypeSequence()) {
1318+
if (param->getInterfaceType()->is<PackExpansionType>()) {
13201319
variadicGenerics.set(i);
13211320
}
13221321
}

0 commit comments

Comments
 (0)