about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPyrode <pyrode.01@gmail.com>2025-02-27 12:23:47 +0530
committerPyrode <pyrode.01@gmail.com>2025-03-13 19:53:53 +0530
commita73e44bce16c9610c5415db3037a69eef0df3c4e (patch)
treea56601586144e9e51f1ba63b2082aafca926ee94
parent961351c76c812e3aeb65bfb542742500a6436aed (diff)
downloadrust-a73e44bce16c9610c5415db3037a69eef0df3c4e.tar.gz
rust-a73e44bce16c9610c5415db3037a69eef0df3c4e.zip
Provide helpful diagnostics for shebang lookalikes
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs19
-rw-r--r--tests/ui/parser/shebang/issue-71471-ignore-tidy.stderr3
-rw-r--r--tests/ui/parser/shebang/shebang-must-start-file.stderr3
-rw-r--r--tests/ui/parser/shebang/shebang-split.rs5
-rw-r--r--tests/ui/parser/shebang/shebang-split.stderr8
5 files changed, 37 insertions, 1 deletions
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
+