Skip to content

Commit 5b8e514

Browse files
authored
Merge pull request #34534 from mininny/fix-dollar-identifier
[Parse] Move standalone_dollar_identifier diagnosis to Parser.
2 parents 824e4d0 + 028594b commit 5b8e514

File tree

4 files changed

+27
-13
lines changed

4 files changed

+27
-13
lines changed

include/swift/Parse/Parser.h

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -566,8 +566,8 @@ class Parser {
566566
if (Result)
567567
*Result = Context.getIdentifier(Tok.getText());
568568

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

572572
return consumeToken();
573573
}
@@ -587,11 +587,22 @@ class Parser {
587587

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

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

lib/Parse/Lexer.cpp

Lines changed: 1 addition & 3 deletions
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

Lines changed: 7 additions & 5 deletions
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

Lines changed: 3 additions & 0 deletions
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)