From 49d2d5a1161720ccd5b76ac2afbdceb6ea7e2e6e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 31 Jan 2025 15:02:41 +0100 Subject: Extract `unescape` from `rustc_lexer` into its own crate --- compiler/rustc_parse/src/parser/expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index e0e6c2177da..0b745217bc8 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -6,6 +6,7 @@ use core::ops::{Bound, ControlFlow}; use ast::mut_visit::{self, MutVisitor}; use ast::token::IdentIsRaw; use ast::{CoroutineKind, ForLoopKind, GenBlockKind, MatchKind, Pat, Path, PathSegment, Recovered}; +use literal_escaper::unescape_char; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::TokenTree; @@ -21,7 +22,6 @@ use rustc_ast::{ use rustc_ast_pretty::pprust; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{Applicability, Diag, PResult, StashKey, Subdiagnostic}; -use rustc_lexer::unescape::unescape_char; use rustc_macros::Subdiagnostic; use rustc_session::errors::{ExprParenthesesNeeded, report_lit_error}; use rustc_session::lint::BuiltinLintDiag; -- cgit 1.4.1-3-g733a5 From a73e44bce16c9610c5415db3037a69eef0df3c4e Mon Sep 17 00:00:00 2001 From: Pyrode Date: Thu, 27 Feb 2025 12:23:47 +0530 Subject: Provide helpful diagnostics for shebang lookalikes --- compiler/rustc_parse/src/parser/attr.rs | 19 ++++++++++++++++++- .../ui/parser/shebang/issue-71471-ignore-tidy.stderr | 3 +++ .../ui/parser/shebang/shebang-must-start-file.stderr | 3 +++ tests/ui/parser/shebang/shebang-split.rs | 5 +++++ tests/ui/parser/shebang/shebang-split.stderr | 8 ++++++++ 5 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 tests/ui/parser/shebang/shebang-split.rs create mode 100644 tests/ui/parser/shebang/shebang-split.stderr (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 066b570c23f..53614049f08 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -127,12 +127,29 @@ impl<'a> Parser<'a> { let lo = self.token.span; // Attributes can't have attributes of their own [Editor's note: not with that attitude] self.collect_tokens_no_attrs(|this| { + let pound_hi = this.token.span.hi(); assert!(this.eat(exp!(Pound)), "parse_attribute called in non-attribute position"); + let not_lo = this.token.span.lo(); let style = if this.eat(exp!(Bang)) { ast::AttrStyle::Inner } else { ast::AttrStyle::Outer }; - this.expect(exp!(OpenBracket))?; + let mut bracket_res = this.expect(exp!(OpenBracket)); + // If `#!` is not followed by `[` + if let Err(err) = &mut bracket_res + && style == ast::AttrStyle::Inner + && pound_hi == not_lo + { + err.note( + "the token sequence `#!` here looks like the start of \ + a shebang interpreter directive but it is not", + ); + err.help( + "if you meant this to be a shebang interpreter directive, \ + move it to the very start of the file", + ); + } + bracket_res?; let item = this.parse_attr_item(ForceCollect::No)?; this.expect(exp!(CloseBracket))?; let attr_sp = lo.to(this.prev_token.span); diff --git a/tests/ui/parser/shebang/issue-71471-ignore-tidy.stderr b/tests/ui/parser/shebang/issue-71471-ignore-tidy.stderr index 41cd4fb93fa..cdd36ba4cae 100644 --- a/tests/ui/parser/shebang/issue-71471-ignore-tidy.stderr +++ b/tests/ui/parser/shebang/issue-71471-ignore-tidy.stderr @@ -3,6 +3,9 @@ error: expected `[`, found `B` | LL | #!B | ^ expected `[` + | + = note: the token sequence `#!` here looks like the start of a shebang interpreter directive but it is not + = help: if you meant this to be a shebang interpreter directive, move it to the very start of the file error: aborting due to 1 previous error diff --git a/tests/ui/parser/shebang/shebang-must-start-file.stderr b/tests/ui/parser/shebang/shebang-must-start-file.stderr index 56991c96b7a..cf897d07780 100644 --- a/tests/ui/parser/shebang/shebang-must-start-file.stderr +++ b/tests/ui/parser/shebang/shebang-must-start-file.stderr @@ -3,6 +3,9 @@ error: expected `[`, found `/` | LL | #!/bin/bash | ^ expected `[` + | + = note: the token sequence `#!` here looks like the start of a shebang interpreter directive but it is not + = help: if you meant this to be a shebang interpreter directive, move it to the very start of the file error: aborting due to 1 previous error diff --git a/tests/ui/parser/shebang/shebang-split.rs b/tests/ui/parser/shebang/shebang-split.rs new file mode 100644 index 00000000000..470bb669143 --- /dev/null +++ b/tests/ui/parser/shebang/shebang-split.rs @@ -0,0 +1,5 @@ +// empty line +# !/bin/env + +// checks that diagnostics for shebang lookalikes is not present +//@ error-pattern: expected `[`\n\n diff --git a/tests/ui/parser/shebang/shebang-split.stderr b/tests/ui/parser/shebang/shebang-split.stderr new file mode 100644 index 00000000000..804df1f0086 --- /dev/null +++ b/tests/ui/parser/shebang/shebang-split.stderr @@ -0,0 +1,8 @@ +error: expected `[`, found `/` + --> $DIR/shebang-split.rs:2:4 + | +LL | # !/bin/env + | ^ expected `[` + +error: aborting due to 1 previous error + -- cgit 1.4.1-3-g733a5 From 66c49c73ee16c02e7b01c4c22070b92410318a5f Mon Sep 17 00:00:00 2001 From: Moritz Hedtke Date: Fri, 14 Mar 2025 18:50:41 +0100 Subject: Make `Parser::parse_expr_cond` public. This allows usage in rustfmt and rustfmt forks. --- compiler/rustc_parse/src/parser/expr.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 9b2d562a69e..0774324eae7 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2588,7 +2588,8 @@ impl<'a> Parser<'a> { } /// Parses the condition of a `if` or `while` expression. - fn parse_expr_cond(&mut self) -> PResult<'a, P> { + // Public because it is used in rustfmt forks such as https://github.com/tucant/rustfmt/blob/30c83df9e1db10007bdd16dafce8a86b404329b2/src/parse/macros/html.rs#L57 for custom if expressions. + pub fn parse_expr_cond(&mut self) -> PResult<'a, P> { let attrs = self.parse_outer_attributes()?; let (mut cond, _) = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL | Restrictions::ALLOW_LET, attrs)?; -- cgit 1.4.1-3-g733a5