Skip to content

Commit ab0ae73

Browse files
authored
Merge pull request #19816 from rudkx/extend-operator-designated-type
Add support for multiple designated types for an operator declaration.
2 parents b1c8013 + 5e0cb19 commit ab0ae73

File tree

14 files changed

+288
-186
lines changed

14 files changed

+288
-186
lines changed

include/swift/AST/Decl.h

Lines changed: 42 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6380,45 +6380,44 @@ class OperatorDecl : public Decl {
63806380

63816381
Identifier name;
63826382

6383-
Identifier DesignatedNominalTypeName;
6384-
SourceLoc DesignatedNominalTypeNameLoc;
6385-
NominalTypeDecl *DesignatedNominalType = nullptr;
6383+
ArrayRef<Identifier> Identifiers;
6384+
ArrayRef<SourceLoc> IdentifierLocs;
6385+
ArrayRef<NominalTypeDecl *> DesignatedNominalTypes;
63866386

63876387
public:
63886388
OperatorDecl(DeclKind kind, DeclContext *DC, SourceLoc OperatorLoc,
63896389
Identifier Name, SourceLoc NameLoc,
6390-
Identifier DesignatedNominalTypeName = Identifier(),
6391-
SourceLoc DesignatedNominalTypeNameLoc = SourceLoc())
6390+
ArrayRef<Identifier> Identifiers,
6391+
ArrayRef<SourceLoc> IdentifierLocs)
63926392
: Decl(kind, DC), OperatorLoc(OperatorLoc), NameLoc(NameLoc), name(Name),
6393-
DesignatedNominalTypeName(DesignatedNominalTypeName),
6394-
DesignatedNominalTypeNameLoc(DesignatedNominalTypeNameLoc) {}
6393+
Identifiers(Identifiers), IdentifierLocs(IdentifierLocs) {}
63956394

63966395
OperatorDecl(DeclKind kind, DeclContext *DC, SourceLoc OperatorLoc,
63976396
Identifier Name, SourceLoc NameLoc,
6398-
NominalTypeDecl *DesignatedNominalType)
6397+
ArrayRef<NominalTypeDecl *> DesignatedNominalTypes)
63996398
: Decl(kind, DC), OperatorLoc(OperatorLoc), NameLoc(NameLoc), name(Name),
6400-
DesignatedNominalType(DesignatedNominalType) {}
6399+
DesignatedNominalTypes(DesignatedNominalTypes) {}
64016400

64026401
SourceLoc getLoc() const { return NameLoc; }
64036402

64046403
SourceLoc getOperatorLoc() const { return OperatorLoc; }
64056404
SourceLoc getNameLoc() const { return NameLoc; }
64066405
Identifier getName() const { return name; }
64076406

6408-
Identifier getDesignatedNominalTypeName() const {
6409-
return DesignatedNominalTypeName;
6407+
ArrayRef<Identifier> getIdentifiers() const {
6408+
return Identifiers;
64106409
}
64116410

6412-
SourceLoc getDesignatedNominalTypeNameLoc() const {
6413-
return DesignatedNominalTypeNameLoc;
6411+
ArrayRef<SourceLoc> getIdentifierLocs() const {
6412+
return IdentifierLocs;
64146413
}
64156414

6416-
NominalTypeDecl *getDesignatedNominalType() const {
6417-
return DesignatedNominalType;
6415+
ArrayRef<NominalTypeDecl *> getDesignatedNominalTypes() const {
6416+
return DesignatedNominalTypes;
64186417
}
64196418

6420-
void setDesignatedNominalType(NominalTypeDecl *nominal) {
6421-
DesignatedNominalType = nominal;
6419+
void setDesignatedNominalTypes(ArrayRef<NominalTypeDecl *> nominalTypes) {
6420+
DesignatedNominalTypes = nominalTypes;
64226421
}
64236422

64246423
static bool classof(const Decl *D) {
@@ -6436,46 +6435,39 @@ class OperatorDecl : public Decl {
64366435
/// infix operator /+/ : AdditionPrecedence, Numeric
64376436
/// \endcode
64386437
class InfixOperatorDecl : public OperatorDecl {
6439-
SourceLoc ColonLoc, FirstIdentifierLoc, SecondIdentifierLoc;
6440-
Identifier FirstIdentifier, SecondIdentifier;
6438+
SourceLoc ColonLoc;
64416439
PrecedenceGroupDecl *PrecedenceGroup = nullptr;
64426440

64436441
public:
64446442
InfixOperatorDecl(DeclContext *DC, SourceLoc operatorLoc, Identifier name,
64456443
SourceLoc nameLoc, SourceLoc colonLoc,
6446-
Identifier firstIdentifier, SourceLoc firstIdentifierLoc,
6447-
Identifier secondIdentifier = Identifier(),
6448-
SourceLoc secondIdentifierLoc = SourceLoc())
6449-
: OperatorDecl(DeclKind::InfixOperator, DC, operatorLoc, name, nameLoc),
6450-
ColonLoc(colonLoc), FirstIdentifierLoc(firstIdentifierLoc),
6451-
SecondIdentifierLoc(secondIdentifierLoc),
6452-
FirstIdentifier(firstIdentifier), SecondIdentifier(secondIdentifier) {}
6444+
ArrayRef<Identifier> identifiers,
6445+
ArrayRef<SourceLoc> identifierLocs)
6446+
: OperatorDecl(DeclKind::InfixOperator, DC, operatorLoc, name, nameLoc,
6447+
identifiers, identifierLocs),
6448+
ColonLoc(colonLoc) {}
64536449

64546450
InfixOperatorDecl(DeclContext *DC, SourceLoc operatorLoc, Identifier name,
64556451
SourceLoc nameLoc, SourceLoc colonLoc,
64566452
PrecedenceGroupDecl *precedenceGroup,
6457-
NominalTypeDecl *designatedNominalType)
6453+
ArrayRef<NominalTypeDecl *> designatedNominalTypes)
64586454
: OperatorDecl(DeclKind::InfixOperator, DC, operatorLoc, name, nameLoc,
6459-
designatedNominalType),
6455+
designatedNominalTypes),
64606456
ColonLoc(colonLoc), PrecedenceGroup(precedenceGroup) {}
64616457

64626458
SourceLoc getEndLoc() const {
6463-
if (!SecondIdentifier.empty())
6464-
return SecondIdentifierLoc;
6465-
if (!FirstIdentifier.empty())
6466-
return FirstIdentifierLoc;
6467-
return getNameLoc();
6459+
auto identifierLocs = getIdentifierLocs();
6460+
if (identifierLocs.empty())
6461+
return getNameLoc();
6462+
6463+
return identifierLocs.back();
64686464
}
6465+
64696466
SourceRange getSourceRange() const {
64706467
return { getOperatorLoc(), getEndLoc() };
64716468
}
64726469

64736470
SourceLoc getColonLoc() const { return ColonLoc; }
6474-
SourceLoc getFirstIdentifierLoc() const { return FirstIdentifierLoc; }
6475-
SourceLoc getSecondIdentifierLoc() const { return SecondIdentifierLoc; }
6476-
6477-
Identifier getFirstIdentifier() const { return FirstIdentifier; }
6478-
Identifier getSecondIdentifier() const { return SecondIdentifier; }
64796471

64806472
PrecedenceGroupDecl *getPrecedenceGroup() const { return PrecedenceGroup; }
64816473
void setPrecedenceGroup(PrecedenceGroupDecl *PGD) {
@@ -6502,15 +6494,16 @@ class PrefixOperatorDecl : public OperatorDecl {
65026494
public:
65036495
PrefixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, Identifier Name,
65046496
SourceLoc NameLoc,
6505-
Identifier DesignatedNominalTypeName = Identifier(),
6506-
SourceLoc DesignatedNominalTypeNameLoc = SourceLoc())
6497+
ArrayRef<Identifier> Identifiers,
6498+
ArrayRef<SourceLoc> IdentifierLocs)
65076499
: OperatorDecl(DeclKind::PrefixOperator, DC, OperatorLoc, Name, NameLoc,
6508-
DesignatedNominalTypeName, DesignatedNominalTypeNameLoc) {}
6500+
Identifiers, IdentifierLocs) {}
65096501

65106502
PrefixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, Identifier Name,
6511-
SourceLoc NameLoc, NominalTypeDecl *DesignatedNominalType)
6503+
SourceLoc NameLoc,
6504+
ArrayRef<NominalTypeDecl *> designatedNominalTypes)
65126505
: OperatorDecl(DeclKind::PrefixOperator, DC, OperatorLoc, Name, NameLoc,
6513-
DesignatedNominalType) {}
6506+
designatedNominalTypes) {}
65146507

65156508
SourceRange getSourceRange() const {
65166509
return { getOperatorLoc(), getNameLoc() };
@@ -6536,15 +6529,16 @@ class PostfixOperatorDecl : public OperatorDecl {
65366529
public:
65376530
PostfixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, Identifier Name,
65386531
SourceLoc NameLoc,
6539-
Identifier DesignatedNominalTypeName = Identifier(),
6540-
SourceLoc DesignatedNominalTypeNameLoc = SourceLoc())
6532+
ArrayRef<Identifier> Identifiers,
6533+
ArrayRef<SourceLoc> IdentifierLocs)
65416534
: OperatorDecl(DeclKind::PostfixOperator, DC, OperatorLoc, Name, NameLoc,
6542-
DesignatedNominalTypeName, DesignatedNominalTypeNameLoc) {}
6535+
Identifiers, IdentifierLocs) {}
65436536

65446537
PostfixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, Identifier Name,
6545-
SourceLoc NameLoc, NominalTypeDecl *DesignatedNominalType)
6538+
SourceLoc NameLoc,
6539+
ArrayRef<NominalTypeDecl *> designatedNominalTypes)
65466540
: OperatorDecl(DeclKind::PostfixOperator, DC, OperatorLoc, Name, NameLoc,
6547-
DesignatedNominalType) {}
6541+
designatedNominalTypes) {}
65486542

65496543
SourceRange getSourceRange() const {
65506544
return { getOperatorLoc(), getNameLoc() };

include/swift/AST/DiagnosticsParse.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
//===--- DiagnosticsParse.def - Diagnostics Text ----------------*- C++ -*-===//
23
//
34
// This source file is part of the Swift.org open source project
@@ -431,8 +432,10 @@ ERROR(deprecated_operator_body_use_group,PointsToFirstBadToken,
431432
ERROR(operator_decl_no_fixity,none,
432433
"operator must be declared as 'prefix', 'postfix', or 'infix'", ())
433434

434-
ERROR(operator_decl_trailing_comma,none,
435+
ERROR(operator_decl_expected_type,none,
435436
"expected designated type in operator declaration", ())
437+
ERROR(operator_decl_trailing_comma,none,
438+
"trailing comma in operator declaration", ())
436439

437440
// PrecedenceGroup
438441
ERROR(precedencegroup_not_infix,none,

include/swift/Serialization/ModuleFormat.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const uint16_t VERSION_MAJOR = 0;
5555
/// describe what change you made. The content of this comment isn't important;
5656
/// it just ensures a conflict if two people change the module format.
5757
/// Don't worry about adhering to the 80-column limit for this line.
58-
const uint16_t VERSION_MINOR = 453; // Last change: borrow always
58+
const uint16_t VERSION_MINOR = 454; // Last change: multiple nominal types for operators
5959

6060
using DeclIDField = BCFixed<31>;
6161

@@ -1099,7 +1099,7 @@ namespace decls_block {
10991099
Code, // ID field
11001100
IdentifierIDField, // name
11011101
DeclContextIDField, // context decl
1102-
DeclIDField // protocol
1102+
BCArray<DeclIDField> // designated types
11031103
>;
11041104

11051105
using PrefixOperatorLayout = UnaryOperatorLayout<PREFIX_OPERATOR_DECL>;
@@ -1110,7 +1110,7 @@ namespace decls_block {
11101110
IdentifierIDField, // name
11111111
DeclContextIDField,// context decl
11121112
DeclIDField, // precedence group
1113-
DeclIDField // protocol
1113+
BCArray<DeclIDField> // designated types
11141114
>;
11151115

11161116
using PrecedenceGroupLayout = BCRecordLayout<

lib/AST/ASTDumper.cpp

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,30 +1169,43 @@ namespace {
11691169
PrintWithColorRAII(OS, ParenthesisColor) << ')';
11701170
}
11711171

1172+
void printOperatorIdentifiers(OperatorDecl *OD) {
1173+
auto identifiers = OD->getIdentifiers();
1174+
for (auto index : indices(identifiers)) {
1175+
OS.indent(Indent + 2);
1176+
OS << "identifier #" << index << " " << identifiers[index];
1177+
if (index != identifiers.size() - 1)
1178+
OS << "\n";
1179+
}
1180+
}
1181+
11721182
void visitInfixOperatorDecl(InfixOperatorDecl *IOD) {
1173-
printCommon(IOD, "infix_operator_decl ");
1174-
OS << IOD->getName() << "\n";
1175-
OS.indent(Indent+2);
1176-
if (!IOD->getFirstIdentifier().empty())
1177-
OS << "first identifier " << IOD->getFirstIdentifier();
1178-
else
1179-
OS << "first identifier <null>";
1180-
if (!IOD->getSecondIdentifier().empty())
1181-
OS << "second identifier " << IOD->getSecondIdentifier();
1182-
else
1183-
OS << "second identifier <null>";
1183+
printCommon(IOD, "infix_operator_decl");
1184+
OS << " " << IOD->getName();
1185+
if (!IOD->getIdentifiers().empty()) {
1186+
OS << "\n";
1187+
printOperatorIdentifiers(IOD);
1188+
}
11841189
PrintWithColorRAII(OS, ParenthesisColor) << ')';
11851190
}
11861191

11871192
void visitPrefixOperatorDecl(PrefixOperatorDecl *POD) {
1188-
printCommon(POD, "prefix_operator_decl ");
1189-
OS << POD->getName();
1193+
printCommon(POD, "prefix_operator_decl");
1194+
OS << " " << POD->getName();
1195+
if (!POD->getIdentifiers().empty()) {
1196+
OS << "\n";
1197+
printOperatorIdentifiers(POD);
1198+
}
11901199
PrintWithColorRAII(OS, ParenthesisColor) << ')';
11911200
}
11921201

11931202
void visitPostfixOperatorDecl(PostfixOperatorDecl *POD) {
1194-
printCommon(POD, "postfix_operator_decl ");
1195-
OS << POD->getName();
1203+
printCommon(POD, "postfix_operator_decl");
1204+
OS << " " << POD->getName();
1205+
if (!POD->getIdentifiers().empty()) {
1206+
OS << "\n";
1207+
printOperatorIdentifiers(POD);
1208+
}
11961209
PrintWithColorRAII(OS, ParenthesisColor) << ')';
11971210
}
11981211

lib/AST/ASTPrinter.cpp

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2875,8 +2875,15 @@ void PrintAST::visitInfixOperatorDecl(InfixOperatorDecl *decl) {
28752875
});
28762876
if (auto *group = decl->getPrecedenceGroup())
28772877
Printer << " : " << group->getName();
2878-
if (!decl->getSecondIdentifier().empty())
2879-
Printer << ", " << decl->getSecondIdentifier();
2878+
auto designatedNominalTypes = decl->getDesignatedNominalTypes();
2879+
auto first = true;
2880+
for (auto typeDecl : designatedNominalTypes) {
2881+
if (first && !decl->getPrecedenceGroup())
2882+
Printer << " : " << typeDecl->getName();
2883+
else
2884+
Printer << ", " << typeDecl->getName();
2885+
first = false;
2886+
}
28802887
}
28812888

28822889
void PrintAST::visitPrecedenceGroupDecl(PrecedenceGroupDecl *decl) {
@@ -2949,8 +2956,15 @@ void PrintAST::visitPrefixOperatorDecl(PrefixOperatorDecl *decl) {
29492956
[&]{
29502957
Printer.printName(decl->getName());
29512958
});
2952-
if (!decl->getDesignatedNominalTypeName().empty())
2953-
Printer << " : " << decl->getDesignatedNominalTypeName();
2959+
auto designatedNominalTypes = decl->getDesignatedNominalTypes();
2960+
auto first = true;
2961+
for (auto typeDecl : designatedNominalTypes) {
2962+
if (first)
2963+
Printer << " : " << typeDecl->getName();
2964+
else
2965+
Printer << ", " << typeDecl->getName();
2966+
first = false;
2967+
}
29542968
}
29552969

29562970
void PrintAST::visitPostfixOperatorDecl(PostfixOperatorDecl *decl) {
@@ -2960,8 +2974,15 @@ void PrintAST::visitPostfixOperatorDecl(PostfixOperatorDecl *decl) {
29602974
[&]{
29612975
Printer.printName(decl->getName());
29622976
});
2963-
if (!decl->getDesignatedNominalTypeName().empty())
2964-
Printer << " : " << decl->getDesignatedNominalTypeName();
2977+
auto designatedNominalTypes = decl->getDesignatedNominalTypes();
2978+
auto first = true;
2979+
for (auto typeDecl : designatedNominalTypes) {
2980+
if (first)
2981+
Printer << " : " << typeDecl->getName();
2982+
else
2983+
Printer << ", " << typeDecl->getName();
2984+
first = false;
2985+
}
29652986
}
29662987

29672988
void PrintAST::visitModuleDecl(ModuleDecl *decl) { }

0 commit comments

Comments
 (0)