Skip to content

Commit 04c82d2

Browse files
authored
Merge pull request swiftlang#40024 from CodaFi/parsifal
2 parents 06ef8f9 + f807dfe commit 04c82d2

File tree

10 files changed

+95
-2
lines changed

10 files changed

+95
-2
lines changed

include/swift/AST/Attr.def

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ TYPE_ATTR(noDerivative)
5656
TYPE_ATTR(async)
5757
TYPE_ATTR(Sendable)
5858
TYPE_ATTR(unchecked)
59+
TYPE_ATTR(_typeSequence)
5960

6061
// SIL-specific attributes
6162
TYPE_ATTR(block_storage)
@@ -426,7 +427,12 @@ DECL_ATTR(_restatedObjCConformance, RestatedObjCConformance,
426427
NotSerialized |
427428
ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
428429
70)
429-
// NOTE: 71 is unused
430+
DECL_ATTR(_typeSequence, TypeSequence,
431+
OnGenericTypeParam |
432+
UserInaccessible |
433+
NotSerialized |
434+
ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove,
435+
71)
430436
// NOTE: 72 is unused
431437
DECL_ATTR(_optimize, Optimize,
432438
OnAbstractFunction | OnSubscript | OnVar |

include/swift/AST/Attr.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2061,6 +2061,20 @@ class NonSendableAttr : public DeclAttribute {
20612061
}
20622062
};
20632063

2064+
/// The @_typeSequence attribute, which treats a generic param decl as a variadic
2065+
/// sequence of value/type pairs.
2066+
class TypeSequenceAttr : public DeclAttribute {
2067+
TypeSequenceAttr(SourceLoc atLoc, SourceRange Range);
2068+
2069+
public:
2070+
static TypeSequenceAttr *create(ASTContext &Ctx, SourceLoc atLoc,
2071+
SourceRange Range);
2072+
2073+
static bool classof(const DeclAttribute *DA) {
2074+
return DA->getKind() == DAK_TypeSequence;
2075+
}
2076+
};
2077+
20642078
/// Attributes that may be applied to declarations.
20652079
class DeclAttributes {
20662080
/// Linked list of declaration attributes.

include/swift/AST/DiagnosticsSema.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6054,5 +6054,13 @@ ERROR(noimplicitcopy_attr_valid_only_on_local_let_params,
60546054
ERROR(noimplicitcopy_attr_invalid_in_generic_context,
60556055
none, "'@_noImplicitCopy' attribute cannot be applied to entities in generic contexts", ())
60566056

6057+
//------------------------------------------------------------------------------
6058+
// MARK: variadics
6059+
//------------------------------------------------------------------------------
6060+
6061+
ERROR(type_sequence_on_non_generic_param, none,
6062+
"'@_typeSequence' must appear on a generic parameter",
6063+
())
6064+
60576065
#define UNDEFINE_DIAGNOSTIC_MACROS
60586066
#include "DefineDiagnosticMacros.h"

lib/AST/Attr.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,11 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
11441144
break;
11451145
}
11461146

1147+
case DAK_TypeSequence: {
1148+
Printer.printAttrName("@_typeSequence");
1149+
break;
1150+
}
1151+
11471152
case DAK_Count:
11481153
llvm_unreachable("exceed declaration attribute kinds");
11491154

@@ -1295,6 +1300,8 @@ StringRef DeclAttribute::getAttrName() const {
12951300
return "derivative";
12961301
case DAK_Transpose:
12971302
return "transpose";
1303+
case DAK_TypeSequence:
1304+
return "_typeSequence";
12981305
}
12991306
llvm_unreachable("bad DeclAttrKind");
13001307
}
@@ -2080,6 +2087,15 @@ bool CustomAttr::isArgUnsafe() const {
20802087
return isArgUnsafeBit;
20812088
}
20822089

2090+
TypeSequenceAttr::TypeSequenceAttr(SourceLoc atLoc, SourceRange range)
2091+
: DeclAttribute(DAK_TypeSequence, atLoc, range, /*Implicit=*/false) {}
2092+
2093+
TypeSequenceAttr *TypeSequenceAttr::create(ASTContext &Ctx, SourceLoc atLoc,
2094+
SourceRange range) {
2095+
void *mem = Ctx.Allocate(sizeof(TypeSequenceAttr), alignof(TypeSequenceAttr));
2096+
return new (mem) TypeSequenceAttr(atLoc, range);
2097+
}
2098+
20832099
void swift::simple_display(llvm::raw_ostream &out, const DeclAttribute *attr) {
20842100
if (attr)
20852101
attr->print(out);

lib/Parse/ParseDecl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2744,6 +2744,11 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
27442744
name, AtLoc, range, /*implicit*/ false));
27452745
break;
27462746
}
2747+
case DAK_TypeSequence: {
2748+
auto range = SourceRange(Loc, Tok.getRange().getStart());
2749+
Attributes.add(TypeSequenceAttr::create(Context, AtLoc, range));
2750+
break;
2751+
}
27472752
}
27482753

27492754
if (DuplicateAttribute) {

lib/Sema/TypeCheckAttr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
244244
void visitDynamicReplacementAttr(DynamicReplacementAttr *attr);
245245
void visitTypeEraserAttr(TypeEraserAttr *attr);
246246
void visitImplementsAttr(ImplementsAttr *attr);
247+
void visitTypeSequenceAttr(TypeSequenceAttr *attr);
247248

248249
void visitFrozenAttr(FrozenAttr *attr);
249250

@@ -3289,6 +3290,13 @@ AttributeChecker::visitImplementationOnlyAttr(ImplementationOnlyAttr *attr) {
32893290
// it won't necessarily be able to say why.
32903291
}
32913292

3293+
void AttributeChecker::visitTypeSequenceAttr(TypeSequenceAttr *attr) {
3294+
if (!isa<GenericTypeParamDecl>(D)) {
3295+
attr->setInvalid();
3296+
diagnoseAndRemoveAttr(attr, diag::type_sequence_on_non_generic_param);
3297+
}
3298+
}
3299+
32923300
void AttributeChecker::visitNonEphemeralAttr(NonEphemeralAttr *attr) {
32933301
auto *param = cast<ParamDecl>(D);
32943302
auto type = param->getInterfaceType()->lookThroughSingleOptionalType();

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,6 +1560,8 @@ namespace {
15601560
UNINTERESTING_ATTR(InheritActorContext)
15611561
UNINTERESTING_ATTR(Isolated)
15621562
UNINTERESTING_ATTR(NoImplicitCopy)
1563+
1564+
UNINTERESTING_ATTR(TypeSequence)
15631565
#undef UNINTERESTING_ATTR
15641566

15651567
void visitAvailableAttr(AvailableAttr *attr) {

lib/Serialization/ModuleFormat.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5656
/// describe what change you made. The content of this comment isn't important;
5757
/// it just ensures a conflict if two people change the module format.
5858
/// Don't worry about adhering to the 80-column limit for this line.
59-
const uint16_t SWIFTMODULE_VERSION_MINOR = 639; // @_noImplicitCopy param
59+
const uint16_t SWIFTMODULE_VERSION_MINOR = 640; // @_typeSequence
6060

6161
/// A standard hash seed used for all string hashes in a serialized module.
6262
///
@@ -1977,6 +1977,8 @@ namespace decls_block {
19771977
BCArray<BCFixed<1>> // Transposed parameter indices' bitvector.
19781978
>;
19791979

1980+
using TypeSequenceDeclAttrLayout = BCRecordLayout<TypeSequence_DECL_ATTR>;
1981+
19801982
#define SIMPLE_DECL_ATTR(X, CLASS, ...) \
19811983
using CLASS##DeclAttrLayout = BCRecordLayout< \
19821984
CLASS##_DECL_ATTR, \

lib/Serialization/Serialization.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2740,6 +2740,12 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
27402740
origDeclID, paramIndicesVector);
27412741
return;
27422742
}
2743+
2744+
case DAK_TypeSequence: {
2745+
auto abbrCode = S.DeclTypeAbbrCodes[TypeSequenceDeclAttrLayout::Code];
2746+
TypeSequenceDeclAttrLayout::emitRecord(S.Out, S.ScratchRecord, abbrCode);
2747+
return;
2748+
}
27432749
}
27442750
}
27452751

test/Parse/type_sequence.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
struct TupleStruct<First, @_typeSequence Rest> {
4+
var first: First
5+
var rest: Rest
6+
}
7+
8+
func debugPrint<@_typeSequence T>(_ items: T...)
9+
where T: CustomDebugStringConvertible
10+
{
11+
/*for (item: T) in items {
12+
stdout.write(item.debugDescription)
13+
}*/
14+
}
15+
16+
func max<@_typeSequence T>(_ values: T...) -> T?
17+
where T: Comparable
18+
{
19+
return nil
20+
}
21+
22+
func min<@_typeSequence T: Comparable>(_ values: T...) -> T? {
23+
return nil
24+
}
25+
26+
func badParameter<T>(_ : @_typeSequence T) {} // expected-error {{attribute does not apply to type}}

0 commit comments

Comments
 (0)