-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Description
For the token sequence #! to start a shebang which would get stripped, it must be located at the very start of the file (modulo Unicode BOM) and not be followed by (whitespace | line_comment | block_comment)* [. If that's not given, the lexer won't remove it for the parser to digest instead. Meaning if the #! doesn't start an inner attribute, the parser will emit a relatively opaque / terse error of the form expected `[`, found $ACTUAL.
The most common trigger would be leading whitespace (incl. leading newlines). Example:
#!/usr/bin/env -S cargo +nightly -Zscripterror: expected `[`, found `/`
--> src/lib.rs:1:4
|
1 | #!/usr/bin/env -S cargo +nightly -Zscript
| ^ expected `[`
Ideally the parser would helpfully point out that the #! doesn't start a shebang here because $reasons.
I suspect this to get hit increasingly more often with the advent of RFC3424 Cargo scripts but we're generally still in uncommon and P-low territory I'd say.
This diagnostic was originally encountered by @epage in the context of doctests (source). Example reproducer:
//! ```
//! #!/usr/bin/env -S cargo +nightly -Zscript
//! fn main() {}
//! ```
rustdoc file.rs --test currently yields (abbreviated):
---- file.rs - (line 1) stdout ----
error: expected `[`, found `/`
--> file.rs:2:3
|
2 | #!/usr/bin/env rustc
| ^ expected `[`
error: aborting due to 1 previous error
Couldn't compile the test.
NB: Whether rustdoc should interpret the #! in #[doc = "#!..."] (notice: no leading space!) or equivalently /// #!... as the start of a shebang (right now it doesn't) assuming the doc attr/comment is sandwiched in between /// ``` of course is a separate question for T-rustdoc to decide.#! will likely never start a shebang inside doctests and that's good, too.
Once rustc supports frontmatter (#136889) which will get treated very similarly, we can think about improving diagnostics for their "lookalikes", too (i.e., detecting "stray" --- (etc.) in the parser).