Skip to content

Commit a920ba2

Browse files
authored
Merge pull request swiftlang#38787 from CodaFi/the-nth-degree
Add Sugar for Variadics
2 parents 88e090b + d5953ea commit a920ba2

19 files changed

+108
-32
lines changed

include/swift/AST/TypeNodes.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ ABSTRACT_SUGARED_TYPE(Sugar, Type)
171171
ABSTRACT_SUGARED_TYPE(UnarySyntaxSugar, SyntaxSugarType)
172172
SUGARED_TYPE(ArraySlice, UnarySyntaxSugarType)
173173
SUGARED_TYPE(Optional, UnarySyntaxSugarType)
174-
TYPE_RANGE(UnarySyntaxSugar, ArraySlice, Optional)
174+
SUGARED_TYPE(VariadicSequence, UnarySyntaxSugarType)
175+
TYPE_RANGE(UnarySyntaxSugar, ArraySlice, VariadicSequence)
175176
SUGARED_TYPE(Dictionary, SyntaxSugarType)
176177
TYPE_RANGE(SyntaxSugar, ArraySlice, Dictionary)
177178
TYPE_RANGE(Sugar, Paren, Dictionary)

include/swift/AST/Types.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5045,6 +5045,21 @@ class DictionaryType : public SyntaxSugarType {
50455045
}
50465046
};
50475047

5048+
/// The type T..., which is sugar for a sequence of argument values.
5049+
class VariadicSequenceType : public UnarySyntaxSugarType {
5050+
VariadicSequenceType(const ASTContext &ctx, Type base,
5051+
RecursiveTypeProperties properties)
5052+
: UnarySyntaxSugarType(TypeKind::VariadicSequence, ctx, base, properties) {}
5053+
5054+
public:
5055+
/// Return a uniqued variadic sequence type with the specified base type.
5056+
static VariadicSequenceType *get(Type baseTy);
5057+
5058+
static bool classof(const TypeBase *T) {
5059+
return T->getKind() == TypeKind::VariadicSequence;
5060+
}
5061+
};
5062+
50485063
/// ProtocolType - A protocol type describes an abstract interface implemented
50495064
/// by another type.
50505065
class ProtocolType : public NominalType {
@@ -6239,7 +6254,7 @@ inline bool CanType::isActuallyCanonicalOrNull() const {
62396254

62406255
inline Type TupleTypeElt::getVarargBaseTy() const {
62416256
TypeBase *T = getType().getPointer();
6242-
if (auto *AT = dyn_cast<ArraySliceType>(T))
6257+
if (auto *AT = dyn_cast<VariadicSequenceType>(T))
62436258
return AT->getBaseType();
62446259
if (auto *BGT = dyn_cast<BoundGenericType>(T)) {
62456260
// It's the stdlib Array<T>.

lib/AST/ASTContext.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ struct ASTContext::Implementation {
394394
llvm::DenseMap<llvm::PointerIntPair<TypeBase*, 3, unsigned>,
395395
ExistentialMetatypeType*> ExistentialMetatypeTypes;
396396
llvm::DenseMap<Type, ArraySliceType*> ArraySliceTypes;
397+
llvm::DenseMap<Type, VariadicSequenceType*> VariadicSequenceTypes;
397398
llvm::DenseMap<std::pair<Type, Type>, DictionaryType *> DictionaryTypes;
398399
llvm::DenseMap<Type, OptionalType*> OptionalTypes;
399400
llvm::DenseMap<Type, ParenType*> SimpleParenTypes; // Most are simple
@@ -2569,6 +2570,7 @@ size_t ASTContext::Implementation::Arena::getTotalMemory() const {
25692570
llvm::capacity_in_bytes(ArraySliceTypes) +
25702571
llvm::capacity_in_bytes(DictionaryTypes) +
25712572
llvm::capacity_in_bytes(OptionalTypes) +
2573+
llvm::capacity_in_bytes(VariadicSequenceTypes) +
25722574
llvm::capacity_in_bytes(SimpleParenTypes) +
25732575
llvm::capacity_in_bytes(ParenTypes) +
25742576
llvm::capacity_in_bytes(ReferenceStorageTypes) +
@@ -3452,7 +3454,7 @@ Type AnyFunctionType::Param::getParameterType(bool forCanonical,
34523454
else if (forCanonical)
34533455
type = BoundGenericType::get(arrayDecl, Type(), {type});
34543456
else
3455-
type = ArraySliceType::get(type);
3457+
type = VariadicSequenceType::get(type);
34563458
}
34573459
return type;
34583460
}
@@ -4024,6 +4026,18 @@ ArraySliceType *ArraySliceType::get(Type base) {
40244026
return entry = new (C, arena) ArraySliceType(C, base, properties);
40254027
}
40264028

4029+
VariadicSequenceType *VariadicSequenceType::get(Type base) {
4030+
auto properties = base->getRecursiveProperties();
4031+
auto arena = getArena(properties);
4032+
4033+
const ASTContext &C = base->getASTContext();
4034+
4035+
VariadicSequenceType *&entry = C.getImpl().getArena(arena).VariadicSequenceTypes[base];
4036+
if (entry) return entry;
4037+
4038+
return entry = new (C, arena) VariadicSequenceType(C, base, properties);
4039+
}
4040+
40274041
DictionaryType *DictionaryType::get(Type keyType, Type valueType) {
40284042
auto properties = keyType->getRecursiveProperties()
40294043
| valueType->getRecursiveProperties();

lib/AST/ASTDumper.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3840,6 +3840,12 @@ namespace {
38403840
PrintWithColorRAII(OS, ParenthesisColor) << ')';
38413841
}
38423842

3843+
void visitVariadicSequenceType(VariadicSequenceType *T, StringRef label) {
3844+
printCommon(label, "variadic_sequence_type");
3845+
printRec(T->getBaseType());
3846+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
3847+
}
3848+
38433849
void visitProtocolCompositionType(ProtocolCompositionType *T,
38443850
StringRef label) {
38453851
printCommon(label, "protocol_composition_type");

lib/AST/ASTMangler.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,12 @@ void ASTMangler::appendType(Type type, const ValueDecl *forDecl) {
11321132
appendOperator("XSa");
11331133
return;
11341134

1135+
case TypeKind::VariadicSequence:
1136+
assert(DWARFMangling && "sugared types are only legal for the debugger");
1137+
appendType(cast<VariadicSequenceType>(tybase)->getBaseType());
1138+
appendOperator("XSa");
1139+
return;
1140+
11351141
case TypeKind::Optional:
11361142
assert(DWARFMangling && "sugared types are only legal for the debugger");
11371143
appendType(cast<OptionalType>(tybase)->getBaseType());

lib/AST/ASTPrinter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5128,6 +5128,11 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
51285128
Printer << "?";
51295129
}
51305130

5131+
void visitVariadicSequenceType(VariadicSequenceType *T) {
5132+
visit(T->getBaseType());
5133+
Printer << "...";
5134+
}
5135+
51315136
void visitProtocolType(ProtocolType *T) {
51325137
printQualifiedType(T);
51335138
}

lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6528,7 +6528,7 @@ void ParamDecl::setNonEphemeralIfPossible() {
65286528

65296529
Type ParamDecl::getVarargBaseTy(Type VarArgT) {
65306530
TypeBase *T = VarArgT.getPointer();
6531-
if (auto *AT = dyn_cast<ArraySliceType>(T))
6531+
if (auto *AT = dyn_cast<VariadicSequenceType>(T))
65326532
return AT->getBaseType();
65336533
if (auto *BGT = dyn_cast<BoundGenericType>(T)) {
65346534
// It's the stdlib Array<T>.

lib/AST/Type.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,6 +1561,7 @@ Type SugarType::getSinglyDesugaredTypeSlow() {
15611561
case TypeKind::TypeAlias:
15621562
llvm_unreachable("bound type alias types always have an underlying type");
15631563
case TypeKind::ArraySlice:
1564+
case TypeKind::VariadicSequence:
15641565
implDecl = Context->getArrayDecl();
15651566
break;
15661567
case TypeKind::Optional:
@@ -4974,6 +4975,18 @@ case TypeKind::Id:
49744975
return OptionalType::get(baseTy);
49754976
}
49764977

4978+
case TypeKind::VariadicSequence: {
4979+
auto seq = cast<VariadicSequenceType>(base);
4980+
auto baseTy = seq->getBaseType().transformRec(fn);
4981+
if (!baseTy)
4982+
return Type();
4983+
4984+
if (baseTy.getPointer() == seq->getBaseType().getPointer())
4985+
return *this;
4986+
4987+
return VariadicSequenceType::get(baseTy);
4988+
}
4989+
49774990
case TypeKind::Dictionary: {
49784991
auto dict = cast<DictionaryType>(base);
49794992
auto keyTy = dict->getKeyType().transformRec(fn);

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1629,7 +1629,8 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
16291629
// SyntaxSugarType derivations.
16301630
case TypeKind::Dictionary:
16311631
case TypeKind::ArraySlice:
1632-
case TypeKind::Optional: {
1632+
case TypeKind::Optional:
1633+
case TypeKind::VariadicSequence: {
16331634
auto *SyntaxSugarTy = cast<SyntaxSugarType>(BaseTy);
16341635
auto *CanTy = SyntaxSugarTy->getSinglyDesugaredType();
16351636
return getOrCreateDesugaredType(CanTy, DbgTy);

lib/Sema/CSGen.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2623,14 +2623,13 @@ namespace {
26232623

26242624
// Try to build the appropriate type for a variadic argument list of
26252625
// the fresh element type. If that failed, just bail out.
2626-
auto array = TypeChecker::getArraySliceType(expr->getLoc(), element);
2627-
if (array->hasError()) return element;
2626+
auto variadicSeq = VariadicSequenceType::get(element);
26282627

26292628
// Require the operand to be convertible to the array type.
26302629
CS.addConstraint(ConstraintKind::Conversion,
2631-
CS.getType(expr->getSubExpr()), array,
2630+
CS.getType(expr->getSubExpr()), variadicSeq,
26322631
CS.getConstraintLocator(expr));
2633-
return array;
2632+
return variadicSeq;
26342633
}
26352634

26362635
Type visitDynamicTypeExpr(DynamicTypeExpr *expr) {

0 commit comments

Comments
 (0)