Skip to content

Commit 028594b

Browse files
committed
[Parse] Move standalone_dollar_identifier diagnosis to Parser. Resolves SR-13092.
1 parent f72afc8 commit 028594b

File tree

4 files changed

+27
-13
lines changed

4 files changed

+27
-13
lines changed

include/swift/Parse/Parser.h

+16-5
Original file line numberDiff line numberDiff line change
@@ -567,8 +567,8 @@ class Parser {
567567
if (Result)
568568
*Result = Context.getIdentifier(Tok.getText());
569569

570-
if (Tok.getText()[0] == '$' && !allowDollarIdentifier)
571-
diagnoseDollarIdentifier(Tok);
570+
if (Tok.getText()[0] == '$')
571+
diagnoseDollarIdentifier(Tok, allowDollarIdentifier);
572572

573573
return consumeToken();
574574
}
@@ -588,11 +588,22 @@ class Parser {
588588

589589
/// When we have a token that is an identifier starting with '$',
590590
/// diagnose it if not permitted in this mode.
591-
void diagnoseDollarIdentifier(const Token &tok) {
591+
void diagnoseDollarIdentifier(const Token &tok,
592+
bool allowDollarIdentifier = false) {
592593
assert(tok.getText()[0] == '$');
593594

594-
if (tok.getText().size() == 1 ||
595-
Context.LangOpts.EnableDollarIdentifiers ||
595+
// If '$' is not guarded by backticks, offer
596+
// to replace it with '`$`'.
597+
if (Tok.getRawText() == "$") {
598+
diagnose(Tok.getLoc(), diag::standalone_dollar_identifier)
599+
.fixItReplace(Tok.getLoc(), "`$`");
600+
return;
601+
}
602+
603+
if (allowDollarIdentifier)
604+
return;
605+
606+
if (tok.getText().size() == 1 || Context.LangOpts.EnableDollarIdentifiers ||
596607
isInSILMode() || L->isSwiftInterface())
597608
return;
598609

lib/Parse/Lexer.cpp

+1-3
Original file line numberDiff line numberDiff line change
@@ -932,10 +932,8 @@ void Lexer::lexDollarIdent() {
932932
break;
933933
}
934934

935+
// If there is a standalone '$', treat it like an identifier.
935936
if (CurPtr == tokStart + 1) {
936-
// It is an error to see a standalone '$'. Offer to replace '$' with '`$`'.
937-
diagnose(tokStart, diag::standalone_dollar_identifier)
938-
.fixItReplaceChars(getSourceLoc(tokStart), getSourceLoc(CurPtr), "`$`");
939937
return formToken(tok::identifier, tokStart);
940938
}
941939

lib/Parse/ParseDecl.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -7719,11 +7719,13 @@ Parser::parseDeclOperator(ParseDeclOptions Flags, DeclAttributes &Attributes) {
77197719
bool AllowTopLevel = Flags.contains(PD_AllowTopLevel);
77207720

77217721
const auto maybeDiagnoseInvalidCharInOperatorName = [this](const Token &Tk) {
7722-
if (Tk.is(tok::identifier) &&
7723-
DeclAttribute::getAttrKindFromString(Tk.getText()) ==
7724-
DeclAttrKind::DAK_Count) {
7725-
diagnose(Tk, diag::identifier_within_operator_name, Tk.getText());
7726-
return true;
7722+
if (Tk.is(tok::identifier)) {
7723+
if (Tk.getText().equals("$") ||
7724+
DeclAttribute::getAttrKindFromString(Tk.getText()) ==
7725+
DeclAttrKind::DAK_Count) {
7726+
diagnose(Tk, diag::identifier_within_operator_name, Tk.getText());
7727+
return true;
7728+
}
77277729
} else if (Tk.isNot(tok::colon, tok::l_brace, tok::semi) &&
77287730
Tk.isPunctuation()) {
77297731
diagnose(Tk, diag::operator_name_invalid_char,

test/Parse/dollar_identifier.swift

+3
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,6 @@ struct S {
8383
}
8484

8585
let _ = S().$café // Okay
86+
87+
infix operator $ // expected-error{{'$' is considered an identifier and must not appear within an operator name}} // SR-13092
88+
infix operator `$` // expected-error{{'$' is considered an identifier and must not appear within an operator name}} // SR-13092

0 commit comments

Comments
 (0)