Skip to content

Commit 627ecbd

Browse files
committed
Rip designated types out of the AST
Designated types were removed from the constraint solver in #34315, but they are currently still represented in the AST and fully checked. This change removes them as completely as possible without breaking source compatibility (mainly with old swiftinterfaces) or changing the SwiftSyntax tree. Designated types are still parsed, but they are dropped immediately and a warning is diagnosed. During decl checking we also still check if the precedence group is really a designated type, but only so that we can diagnose a warning and fall back to DefaultPrecedence. This change also fixes an apparent bug in the parser where we did not diagnose operator declarations that contained a `:` followed by a non-identifier token.
1 parent 700b11d commit 627ecbd

15 files changed

+170
-343
lines changed

include/swift/AST/Decl.h

+21-60
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

+5-4
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

+2-22
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

-27
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

+34-42
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

+2-4
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)