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 -Zscript
error: 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).