Skip to content

Provide a more helpful diagnostic on "shebang lookalikes" (and soon "frontmatter lookalikes" too) #137249

Closed
@fmease

Description

@fmease

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).

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsA-parserArea: The lexing & parsing of Rust source code to an ASTD-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.P-lowLow priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions