Skip to content

Commit db4b4c9

Browse files
committed
AST: Introduce PackExpansionTypeRepr
1 parent 4893965 commit db4b4c9

File tree

8 files changed

+106
-0
lines changed

8 files changed

+106
-0
lines changed

include/swift/AST/TypeRepr.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,45 @@ struct TupleTypeReprElement {
708708
TupleTypeReprElement(TypeRepr *Type): Type(Type) {}
709709
};
710710

711+
/// A pack expansion 'T...' with a pattern 'T'.
712+
///
713+
/// Can appear in the following positions:
714+
/// - The type of a parameter declaration in a function declaration
715+
/// - The type of a parameter in a function type
716+
/// - The element of a tuple
717+
///
718+
/// In the first two cases, it also spells an old-style variadic parameter
719+
/// desugaring to an array type. The two meanings are distinguished by the
720+
/// presence of at least one pack type parameter in the pack expansion
721+
/// pattern.
722+
///
723+
/// In the third case, tuples cannot contain an old-style variadic element,
724+
/// so the pack expansion must be a real variadic pack expansion.
725+
class PackExpansionTypeRepr final : public TypeRepr {
726+
TypeRepr *Pattern;
727+
SourceLoc EllipsisLoc;
728+
729+
public:
730+
PackExpansionTypeRepr(TypeRepr *Pattern, SourceLoc EllipsisLoc)
731+
: TypeRepr(TypeReprKind::PackExpansion), Pattern(Pattern),
732+
EllipsisLoc(EllipsisLoc) {}
733+
734+
TypeRepr *getPatternType() const { return Pattern; }
735+
SourceLoc getEllipsisLoc() const { return EllipsisLoc; }
736+
737+
static bool classof(const TypeRepr *T) {
738+
return T->getKind() == TypeReprKind::PackExpansion;
739+
}
740+
static bool classof(const PackExpansionTypeRepr *T) { return true; }
741+
742+
private:
743+
SourceLoc getStartLocImpl() const { return Pattern->getStartLoc(); }
744+
SourceLoc getEndLocImpl() const { return EllipsisLoc; }
745+
SourceLoc getLocImpl() const { return EllipsisLoc; }
746+
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
747+
friend class TypeRepr;
748+
};
749+
711750
/// A tuple type.
712751
/// \code
713752
/// (Foo, Bar)
@@ -1339,6 +1378,7 @@ inline bool TypeRepr::isSimple() const {
13391378
case TypeReprKind::Dictionary:
13401379
case TypeReprKind::Optional:
13411380
case TypeReprKind::ImplicitlyUnwrappedOptional:
1381+
case TypeReprKind::PackExpansion:
13421382
case TypeReprKind::Tuple:
13431383
case TypeReprKind::Fixed:
13441384
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)

lib/AST/ASTDumper.cpp

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

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

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

Lines changed: 7 additions & 0 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:

lib/AST/TypeRepr.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,12 @@ SourceLoc SILBoxTypeRepr::getLocImpl() const {
439439
return LBraceLoc;
440440
}
441441

442+
void PackExpansionTypeRepr::printImpl(ASTPrinter &Printer,
443+
const PrintOptions &Opts) const {
444+
printTypeRepr(Pattern, Printer, Opts);
445+
Printer << "...";
446+
}
447+
442448
void TupleTypeRepr::printImpl(ASTPrinter &Printer,
443449
const PrintOptions &Opts) const {
444450
Printer.callPrintStructurePre(PrintStructureKind::TupleType);

lib/Parse/SyntaxParsingContext.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ void SyntaxParsingContext::createNodeInPlace(SyntaxKind Kind,
277277
case SyntaxKind::TernaryExpr:
278278
case SyntaxKind::AvailabilityLabeledArgument:
279279
case SyntaxKind::MetatypeType:
280+
case SyntaxKind::PackExpansionType:
280281
case SyntaxKind::OptionalType:
281282
case SyntaxKind::ImplicitlyUnwrappedOptionalType:
282283
case SyntaxKind::TypeExpr: {

lib/Sema/TypeCheckType.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,6 +2047,11 @@ namespace {
20472047
NeverNullType resolveImplicitlyUnwrappedOptionalType(
20482048
ImplicitlyUnwrappedOptionalTypeRepr *repr,
20492049
TypeResolutionOptions options, bool isDirect);
2050+
std::pair<Type, Type>
2051+
maybeResolvePackExpansionType(PackExpansionTypeRepr *repr,
2052+
TypeResolutionOptions options);
2053+
NeverNullType resolvePackExpansionType(PackExpansionTypeRepr *repr,
2054+
TypeResolutionOptions options);
20502055
NeverNullType resolveTupleType(TupleTypeRepr *repr,
20512056
TypeResolutionOptions options);
20522057
NeverNullType resolveCompositionType(CompositionTypeRepr *repr,
@@ -2215,6 +2220,9 @@ NeverNullType TypeResolver::resolveType(TypeRepr *repr,
22152220
return resolveImplicitlyUnwrappedOptionalType(iuoRepr, options, isDirect);
22162221
}
22172222

2223+
case TypeReprKind::PackExpansion:
2224+
return resolvePackExpansionType(cast<PackExpansionTypeRepr>(repr), options);
2225+
22182226
case TypeReprKind::Tuple:
22192227
return resolveTupleType(cast<TupleTypeRepr>(repr), options);
22202228

@@ -4008,6 +4016,39 @@ NeverNullType TypeResolver::resolveImplicitlyUnwrappedOptionalType(
40084016
return uncheckedOptionalTy;
40094017
}
40104018

4019+
std::pair<Type, Type>
4020+
TypeResolver::maybeResolvePackExpansionType(PackExpansionTypeRepr *repr,
4021+
TypeResolutionOptions options) {
4022+
auto elementOptions = options;
4023+
auto patternTy = resolveType(repr->getPatternType(), elementOptions);
4024+
if (patternTy->hasError())
4025+
return std::make_pair(ErrorType::get(getASTContext()), Type());
4026+
4027+
// Find the first type sequence parameter and use that as the count type.
4028+
SmallVector<Type, 1> rootTypeSequenceParams;
4029+
patternTy->getTypeSequenceParameters(rootTypeSequenceParams);
4030+
4031+
if (rootTypeSequenceParams.empty())
4032+
return std::make_pair(patternTy, Type());
4033+
4034+
return std::make_pair(patternTy, rootTypeSequenceParams[0]);
4035+
}
4036+
4037+
NeverNullType TypeResolver::resolvePackExpansionType(PackExpansionTypeRepr *repr,
4038+
TypeResolutionOptions options) {
4039+
auto pair = maybeResolvePackExpansionType(repr, options);
4040+
4041+
// If there's no reference to a variadic generic parameter, complain
4042+
// - the pack won't actually expand to anything meaningful.
4043+
if (!pair.first->hasError() && !pair.second) {
4044+
diagnose(repr->getLoc(), diag::expansion_not_variadic, pair.first)
4045+
.highlight(repr->getSourceRange());
4046+
return ErrorType::get(getASTContext());
4047+
}
4048+
4049+
return PackExpansionType::get(pair.first, pair.second);
4050+
}
4051+
40114052
NeverNullType TypeResolver::resolveTupleType(TupleTypeRepr *repr,
40124053
TypeResolutionOptions options) {
40134054
SmallVector<TupleTypeElt, 8> elements;
@@ -4530,6 +4571,7 @@ class ExistentialTypeVisitor
45304571
case TypeReprKind::Isolated:
45314572
case TypeReprKind::Placeholder:
45324573
case TypeReprKind::CompileTimeConst:
4574+
case TypeReprKind::PackExpansion:
45334575
return false;
45344576
}
45354577
}

0 commit comments

Comments
 (0)