Skip to content

Commit 6964a7d

Browse files
authored
Merge pull request #38728 from beccadax/designated-survivor
2 parents 3701c0e + ec05421 commit 6964a7d

15 files changed

+163
-353
lines changed

include/swift/AST/Decl.h

Lines changed: 21 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -7276,22 +7276,13 @@ class OperatorDecl : public Decl {
72767276

72777277
Identifier name;
72787278

7279-
ArrayRef<Located<Identifier>> Identifiers;
7280-
ArrayRef<NominalTypeDecl *> DesignatedNominalTypes;
72817279
SourceLoc getLocFromSource() const { return NameLoc; }
72827280
friend class Decl;
72837281
public:
72847282
OperatorDecl(DeclKind kind, DeclContext *DC, SourceLoc OperatorLoc,
7285-
Identifier Name, SourceLoc NameLoc,
7286-
ArrayRef<Located<Identifier>> Identifiers)
7287-
: Decl(kind, DC), OperatorLoc(OperatorLoc), NameLoc(NameLoc), name(Name),
7288-
Identifiers(Identifiers) {}
7289-
7290-
OperatorDecl(DeclKind kind, DeclContext *DC, SourceLoc OperatorLoc,
7291-
Identifier Name, SourceLoc NameLoc,
7292-
ArrayRef<NominalTypeDecl *> DesignatedNominalTypes)
7293-
: Decl(kind, DC), OperatorLoc(OperatorLoc), NameLoc(NameLoc), name(Name),
7294-
DesignatedNominalTypes(DesignatedNominalTypes) {}
7283+
Identifier Name, SourceLoc NameLoc)
7284+
: Decl(kind, DC), OperatorLoc(OperatorLoc), NameLoc(NameLoc), name(Name)
7285+
{}
72957286

72967287
/// Retrieve the operator's fixity, corresponding to the concrete subclass
72977288
/// of the OperatorDecl.
@@ -7318,25 +7309,6 @@ class OperatorDecl : public Decl {
73187309
// OperatorDecls.
73197310
DeclBaseName getBaseName() const { return name; }
73207311

7321-
/// Get the list of identifiers after the colon in the operator declaration.
7322-
///
7323-
/// This list includes the names of designated types. For infix operators, the
7324-
/// first item in the list is a precedence group instead.
7325-
///
7326-
/// \todo These two purposes really ought to be in separate properties and the
7327-
/// designated type list should be of TypeReprs instead of Identifiers.
7328-
ArrayRef<Located<Identifier>> getIdentifiers() const {
7329-
return Identifiers;
7330-
}
7331-
7332-
ArrayRef<NominalTypeDecl *> getDesignatedNominalTypes() const {
7333-
return DesignatedNominalTypes;
7334-
}
7335-
7336-
void setDesignatedNominalTypes(ArrayRef<NominalTypeDecl *> nominalTypes) {
7337-
DesignatedNominalTypes = nominalTypes;
7338-
}
7339-
73407312
static bool classof(const Decl *D) {
73417313
// Workaround: http://llvm.org/PR35906
73427314
if (DeclKind::Last_Decl == DeclKind::Last_OperatorDecl)
@@ -7352,22 +7324,23 @@ class OperatorDecl : public Decl {
73527324
/// infix operator /+/ : AdditionPrecedence, Numeric
73537325
/// \endcode
73547326
class InfixOperatorDecl : public OperatorDecl {
7355-
SourceLoc ColonLoc;
7327+
SourceLoc ColonLoc, PrecedenceGroupLoc;
7328+
Identifier PrecedenceGroupName;
73567329

73577330
public:
73587331
InfixOperatorDecl(DeclContext *DC, SourceLoc operatorLoc, Identifier name,
73597332
SourceLoc nameLoc, SourceLoc colonLoc,
7360-
ArrayRef<Located<Identifier>> identifiers)
7361-
: OperatorDecl(DeclKind::InfixOperator, DC, operatorLoc, name, nameLoc,
7362-
identifiers),
7363-
ColonLoc(colonLoc) {}
7333+
Identifier precedenceGroupName,
7334+
SourceLoc precedenceGroupLoc)
7335+
: OperatorDecl(DeclKind::InfixOperator, DC, operatorLoc, name, nameLoc),
7336+
ColonLoc(colonLoc), PrecedenceGroupLoc(precedenceGroupLoc),
7337+
PrecedenceGroupName(precedenceGroupName) {}
73647338

73657339
SourceLoc getEndLoc() const {
7366-
auto identifiers = getIdentifiers();
7367-
if (identifiers.empty())
7368-
return getNameLoc();
7340+
if (getPrecedenceGroupLoc().isValid())
7341+
return getPrecedenceGroupLoc();
73697342

7370-
return identifiers.back().Loc;
7343+
return getNameLoc();
73717344
}
73727345

73737346
SourceRange getSourceRange() const {
@@ -7376,6 +7349,8 @@ class InfixOperatorDecl : public OperatorDecl {
73767349

73777350
SourceLoc getColonLoc() const { return ColonLoc; }
73787351

7352+
Identifier getPrecedenceGroupName() const { return PrecedenceGroupName; }
7353+
SourceLoc getPrecedenceGroupLoc() const { return PrecedenceGroupLoc; }
73797354
PrecedenceGroupDecl *getPrecedenceGroup() const;
73807355

73817356
static bool classof(const Decl *D) {
@@ -7391,16 +7366,9 @@ class InfixOperatorDecl : public OperatorDecl {
73917366
class PrefixOperatorDecl : public OperatorDecl {
73927367
public:
73937368
PrefixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, Identifier Name,
7394-
SourceLoc NameLoc,
7395-
ArrayRef<Located<Identifier>> Identifiers)
7396-
: OperatorDecl(DeclKind::PrefixOperator, DC, OperatorLoc, Name, NameLoc,
7397-
Identifiers) {}
7398-
7399-
PrefixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, Identifier Name,
7400-
SourceLoc NameLoc,
7401-
ArrayRef<NominalTypeDecl *> designatedNominalTypes)
7402-
: OperatorDecl(DeclKind::PrefixOperator, DC, OperatorLoc, Name, NameLoc,
7403-
designatedNominalTypes) {}
7369+
SourceLoc NameLoc)
7370+
: OperatorDecl(DeclKind::PrefixOperator, DC, OperatorLoc, Name, NameLoc)
7371+
{}
74047372

74057373
SourceRange getSourceRange() const {
74067374
return { getOperatorLoc(), getNameLoc() };
@@ -7419,16 +7387,9 @@ class PrefixOperatorDecl : public OperatorDecl {
74197387
class PostfixOperatorDecl : public OperatorDecl {
74207388
public:
74217389
PostfixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, Identifier Name,
7422-
SourceLoc NameLoc,
7423-
ArrayRef<Located<Identifier>> Identifiers)
7424-
: OperatorDecl(DeclKind::PostfixOperator, DC, OperatorLoc, Name, NameLoc,
7425-
Identifiers) {}
7426-
7427-
PostfixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, Identifier Name,
7428-
SourceLoc NameLoc,
7429-
ArrayRef<NominalTypeDecl *> designatedNominalTypes)
7430-
: OperatorDecl(DeclKind::PostfixOperator, DC, OperatorLoc, Name, NameLoc,
7431-
designatedNominalTypes) {}
7390+
SourceLoc NameLoc)
7391+
: OperatorDecl(DeclKind::PostfixOperator, DC, OperatorLoc, Name, NameLoc)
7392+
{}
74327393

74337394
SourceRange getSourceRange() const {
74347395
return { getOperatorLoc(), getNameLoc() };

include/swift/AST/DiagnosticsParse.def

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -435,11 +435,12 @@ ERROR(deprecated_operator_body_use_group,PointsToFirstBadToken,
435435
"use a precedence group instead", ())
436436
ERROR(operator_decl_no_fixity,none,
437437
"operator must be declared as 'prefix', 'postfix', or 'infix'", ())
438+
ERROR(operator_decl_expected_precedencegroup, none,
439+
"expected precedence group name after ':' in operator declaration", ())
438440

439-
ERROR(operator_decl_expected_type,none,
440-
"expected designated type in operator declaration", ())
441-
ERROR(operator_decl_trailing_comma,none,
442-
"trailing comma in operator declaration", ())
441+
WARNING(operator_decl_remove_designated_types,none,
442+
"designated types are no longer used by the compiler; please remove "
443+
"the designated type list from this operator declaration", ())
443444

444445
// PrecedenceGroup
445446
ERROR(precedencegroup_not_infix,none,

lib/AST/ASTDumper.cpp

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,43 +1145,23 @@ namespace {
11451145
PrintWithColorRAII(OS, ParenthesisColor) << ')';
11461146
}
11471147

1148-
void printOperatorIdentifiers(OperatorDecl *OD) {
1149-
auto identifiers = OD->getIdentifiers();
1150-
for (auto index : indices(identifiers)) {
1151-
OS.indent(Indent + 2);
1152-
OS << "identifier #" << index << " " << identifiers[index].Item;
1153-
if (index != identifiers.size() - 1)
1154-
OS << "\n";
1155-
}
1156-
}
1157-
11581148
void visitInfixOperatorDecl(InfixOperatorDecl *IOD) {
11591149
printCommon(IOD, "infix_operator_decl");
11601150
OS << " " << IOD->getName();
1161-
if (!IOD->getIdentifiers().empty()) {
1162-
OS << "\n";
1163-
printOperatorIdentifiers(IOD);
1164-
}
1151+
if (!IOD->getPrecedenceGroupName().empty())
1152+
OS << " precedence_group_name=" << IOD->getPrecedenceGroupName();
11651153
PrintWithColorRAII(OS, ParenthesisColor) << ')';
11661154
}
11671155

11681156
void visitPrefixOperatorDecl(PrefixOperatorDecl *POD) {
11691157
printCommon(POD, "prefix_operator_decl");
11701158
OS << " " << POD->getName();
1171-
if (!POD->getIdentifiers().empty()) {
1172-
OS << "\n";
1173-
printOperatorIdentifiers(POD);
1174-
}
11751159
PrintWithColorRAII(OS, ParenthesisColor) << ')';
11761160
}
11771161

11781162
void visitPostfixOperatorDecl(PostfixOperatorDecl *POD) {
11791163
printCommon(POD, "postfix_operator_decl");
11801164
OS << " " << POD->getName();
1181-
if (!POD->getIdentifiers().empty()) {
1182-
OS << "\n";
1183-
printOperatorIdentifiers(POD);
1184-
}
11851165
PrintWithColorRAII(OS, ParenthesisColor) << ')';
11861166
}
11871167

lib/AST/ASTPrinter.cpp

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3776,15 +3776,6 @@ void PrintAST::visitInfixOperatorDecl(InfixOperatorDecl *decl) {
37763776
});
37773777
if (auto *group = decl->getPrecedenceGroup())
37783778
Printer << " : " << group->getName();
3779-
auto designatedNominalTypes = decl->getDesignatedNominalTypes();
3780-
auto first = true;
3781-
for (auto typeDecl : designatedNominalTypes) {
3782-
if (first && !decl->getPrecedenceGroup())
3783-
Printer << " : " << typeDecl->getName();
3784-
else
3785-
Printer << ", " << typeDecl->getName();
3786-
first = false;
3787-
}
37883779
}
37893780

37903781
void PrintAST::visitPrecedenceGroupDecl(PrecedenceGroupDecl *decl) {
@@ -3853,15 +3844,6 @@ void PrintAST::visitPrefixOperatorDecl(PrefixOperatorDecl *decl) {
38533844
[&]{
38543845
Printer.printName(decl->getName());
38553846
});
3856-
auto designatedNominalTypes = decl->getDesignatedNominalTypes();
3857-
auto first = true;
3858-
for (auto typeDecl : designatedNominalTypes) {
3859-
if (first)
3860-
Printer << " : " << typeDecl->getName();
3861-
else
3862-
Printer << ", " << typeDecl->getName();
3863-
first = false;
3864-
}
38653847
}
38663848

38673849
void PrintAST::visitPostfixOperatorDecl(PostfixOperatorDecl *decl) {
@@ -3871,15 +3853,6 @@ void PrintAST::visitPostfixOperatorDecl(PostfixOperatorDecl *decl) {
38713853
[&]{
38723854
Printer.printName(decl->getName());
38733855
});
3874-
auto designatedNominalTypes = decl->getDesignatedNominalTypes();
3875-
auto first = true;
3876-
for (auto typeDecl : designatedNominalTypes) {
3877-
if (first)
3878-
Printer << " : " << typeDecl->getName();
3879-
else
3880-
Printer << ", " << typeDecl->getName();
3881-
first = false;
3882-
}
38833856
}
38843857

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

lib/Parse/ParseDecl.cpp

Lines changed: 34 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8115,8 +8115,8 @@ Parser::parseDeclOperatorImpl(SourceLoc OperatorLoc, Identifier Name,
81158115
// designated protocol. These both look like identifiers, so we
81168116
// parse them both as identifiers here and sort it out in type
81178117
// checking.
8118-
SourceLoc colonLoc;
8119-
SmallVector<Located<Identifier>, 4> identifiers;
8118+
SourceLoc colonLoc, groupLoc;
8119+
Identifier groupName;
81208120
if (Tok.is(tok::colon)) {
81218121
SyntaxParsingContext GroupCtxt(SyntaxContext,
81228122
SyntaxKind::OperatorPrecedenceAndTypes);
@@ -8131,43 +8131,40 @@ Parser::parseDeclOperatorImpl(SourceLoc OperatorLoc, Identifier Name,
81318131
return makeParserCodeCompletionResult<OperatorDecl>();
81328132
}
81338133

8134-
if (Context.TypeCheckerOpts.EnableOperatorDesignatedTypes) {
8135-
if (Tok.is(tok::identifier)) {
8136-
SyntaxParsingContext GroupCtxt(SyntaxContext,
8137-
SyntaxKind::IdentifierList);
8134+
SyntaxParsingContext ListCtxt(SyntaxContext, SyntaxKind::IdentifierList);
81388135

8139-
Identifier name;
8140-
auto loc = consumeIdentifier(name, /*diagnoseDollarPrefix=*/false);
8141-
identifiers.emplace_back(name, loc);
8136+
(void)parseIdentifier(groupName, groupLoc,
8137+
diag::operator_decl_expected_precedencegroup,
8138+
/*diagnoseDollarPrefix=*/false);
81428139

8143-
while (Tok.is(tok::comma)) {
8144-
auto comma = consumeToken();
8140+
if (Context.TypeCheckerOpts.EnableOperatorDesignatedTypes) {
8141+
// Designated types have been removed; consume the list (mainly for source
8142+
// compatibility with old swiftinterfaces) and emit a warning.
81458143

8146-
if (Tok.is(tok::identifier)) {
8147-
Identifier name;
8148-
auto loc = consumeIdentifier(name, /*diagnoseDollarPrefix=*/false);
8149-
identifiers.emplace_back(name, loc);
8150-
} else {
8151-
if (Tok.isNot(tok::eof)) {
8152-
auto otherTokLoc = consumeToken();
8153-
diagnose(otherTokLoc, diag::operator_decl_expected_type);
8154-
} else {
8155-
diagnose(comma, diag::operator_decl_trailing_comma);
8156-
}
8157-
}
8158-
}
8144+
// These SourceLocs point to the ends of the designated type list. If
8145+
// `typesEndLoc` never becomes valid, we didn't find any designated types.
8146+
SourceLoc typesStartLoc = Tok.getLoc();
8147+
SourceLoc typesEndLoc;
8148+
8149+
if (isPrefix || isPostfix) {
8150+
// These have no precedence group, so we already parsed the first entry
8151+
// in the designated types list. Retroactively include it in the range.
8152+
typesStartLoc = colonLoc;
8153+
typesEndLoc = groupLoc;
81598154
}
8160-
} else if (Tok.is(tok::identifier)) {
8161-
SyntaxParsingContext GroupCtxt(SyntaxContext,
8162-
SyntaxKind::IdentifierList);
81638155

8164-
Identifier name;
8165-
auto nameLoc = consumeIdentifier(name, /*diagnoseDollarPrefix=*/false);
8166-
identifiers.emplace_back(name, nameLoc);
8156+
while (consumeIf(tok::comma, typesEndLoc)) {
8157+
if (Tok.isNot(tok::eof))
8158+
typesEndLoc = consumeToken();
8159+
}
81678160

8161+
if (typesEndLoc.isValid())
8162+
diagnose(typesStartLoc, diag::operator_decl_remove_designated_types)
8163+
.fixItRemove({typesStartLoc, typesEndLoc});
8164+
} else {
81688165
if (isPrefix || isPostfix) {
81698166
diagnose(colonLoc, diag::precedencegroup_not_infix)
8170-
.fixItRemove({colonLoc, nameLoc});
8167+
.fixItRemove({colonLoc, groupLoc});
81718168
}
81728169
// Nothing to complete here, simply consume the token.
81738170
if (Tok.is(tok::code_complete))
@@ -8183,10 +8180,7 @@ Parser::parseDeclOperatorImpl(SourceLoc OperatorLoc, Identifier Name,
81838180
} else {
81848181
auto Diag = diagnose(lBraceLoc, diag::deprecated_operator_body);
81858182
if (Tok.is(tok::r_brace)) {
8186-
SourceLoc lastGoodLoc =
8187-
!identifiers.empty() ? identifiers.back().Loc : SourceLoc();
8188-
if (lastGoodLoc.isInvalid())
8189-
lastGoodLoc = NameLoc;
8183+
SourceLoc lastGoodLoc = groupLoc.isValid() ? groupLoc : NameLoc;
81908184
SourceLoc lastGoodLocEnd = Lexer::getLocForEndOfToken(SourceMgr,
81918185
lastGoodLoc);
81928186
SourceLoc rBraceEnd = Lexer::getLocForEndOfToken(SourceMgr, Tok.getLoc());
@@ -8199,18 +8193,16 @@ Parser::parseDeclOperatorImpl(SourceLoc OperatorLoc, Identifier Name,
81998193
}
82008194

82018195
OperatorDecl *res;
8202-
if (Attributes.hasAttribute<PrefixAttr>())
8196+
if (isPrefix)
82038197
res = new (Context)
8204-
PrefixOperatorDecl(CurDeclContext, OperatorLoc, Name, NameLoc,
8205-
Context.AllocateCopy(identifiers));
8206-
else if (Attributes.hasAttribute<PostfixAttr>())
8198+
PrefixOperatorDecl(CurDeclContext, OperatorLoc, Name, NameLoc);
8199+
else if (isPostfix)
82078200
res = new (Context)
8208-
PostfixOperatorDecl(CurDeclContext, OperatorLoc, Name, NameLoc,
8209-
Context.AllocateCopy(identifiers));
8201+
PostfixOperatorDecl(CurDeclContext, OperatorLoc, Name, NameLoc);
82108202
else
82118203
res = new (Context)
82128204
InfixOperatorDecl(CurDeclContext, OperatorLoc, Name, NameLoc, colonLoc,
8213-
Context.AllocateCopy(identifiers));
8205+
groupName, groupLoc);
82148206

82158207
diagnoseOperatorFixityAttributes(*this, Attributes, res);
82168208

lib/Sema/TypeCheckAccess.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1874,12 +1874,10 @@ class DeclAvailabilityChecker : public DeclVisitor<DeclAvailabilityChecker> {
18741874
}
18751875

18761876
void visitInfixOperatorDecl(InfixOperatorDecl *IOD) {
1877-
// FIXME: Handle operator designated types (which also applies to prefix
1878-
// and postfix operators).
18791877
if (auto *precedenceGroup = IOD->getPrecedenceGroup()) {
1880-
if (!IOD->getIdentifiers().empty()) {
1878+
if (!IOD->getPrecedenceGroupName().empty()) {
18811879
checkPrecedenceGroup(precedenceGroup, IOD, IOD->getLoc(),
1882-
IOD->getIdentifiers().front().Loc);
1880+
IOD->getPrecedenceGroupLoc());
18831881
}
18841882
}
18851883
}

0 commit comments

Comments
 (0)