Skip to content

Commit dda8a7f

Browse files
committed
Auto merge of #73596 - petrochenkov:shebang2, r=Mark-Simulacrum
rustc_lexer: Simplify shebang parsing once more Fixes #73250 (beta regression) Treat any line starting with `!#` as a shebang candidate, not only lines with something non-whitespace. This way we no longer need to define what `is_whitespace` means ([Linux shebang whitespace](https://github.com/torvalds/linux/blob/master/fs/binfmt_script.c), ASCII whitespace, Rust lexer whitespace, etc), which is nice. This change makes some invalid Rust code valid (see the regression above), but still never interprets a fragment of valid Rust code as a shebang. (This PR also removes one duplicate test.)
2 parents 7750c3d + 7b2064f commit dda8a7f

File tree

4 files changed

+21
-20
lines changed

4 files changed

+21
-20
lines changed

src/librustc_lexer/src/lib.rs

+12-15
Original file line numberDiff line numberDiff line change
@@ -179,21 +179,18 @@ pub enum Base {
179179
/// but shebang isn't a part of rust syntax.
180180
pub fn strip_shebang(input: &str) -> Option<usize> {
181181
// Shebang must start with `#!` literally, without any preceding whitespace.
182-
if input.starts_with("#!") {
183-
let input_tail = &input[2..];
184-
// Shebang must have something non-whitespace after `#!` on the first line.
185-
let first_line_tail = input_tail.lines().next()?;
186-
if first_line_tail.contains(|c| !is_whitespace(c)) {
187-
// Ok, this is a shebang but if the next non-whitespace token is `[` or maybe
188-
// a doc comment (due to `TokenKind::(Line,Block)Comment` ambiguity at lexer level),
189-
// then it may be valid Rust code, so consider it Rust code.
190-
let next_non_whitespace_token = tokenize(input_tail).map(|tok| tok.kind).find(|tok|
191-
!matches!(tok, TokenKind::Whitespace | TokenKind::LineComment | TokenKind::BlockComment { .. })
192-
);
193-
if next_non_whitespace_token != Some(TokenKind::OpenBracket) {
194-
// No other choice than to consider this a shebang.
195-
return Some(2 + first_line_tail.len());
196-
}
182+
// For simplicity we consider any line starting with `#!` a shebang,
183+
// regardless of restrictions put on shebangs by specific platforms.
184+
if let Some(input_tail) = input.strip_prefix("#!") {
185+
// Ok, this is a shebang but if the next non-whitespace token is `[` or maybe
186+
// a doc comment (due to `TokenKind::(Line,Block)Comment` ambiguity at lexer level),
187+
// then it may be valid Rust code, so consider it Rust code.
188+
let next_non_whitespace_token = tokenize(input_tail).map(|tok| tok.kind).find(|tok|
189+
!matches!(tok, TokenKind::Whitespace | TokenKind::LineComment | TokenKind::BlockComment { .. })
190+
);
191+
if next_non_whitespace_token != Some(TokenKind::OpenBracket) {
192+
// No other choice than to consider this a shebang.
193+
return Some(2 + input_tail.lines().next().unwrap_or_default().len());
197194
}
198195
}
199196
None
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!
2+
3+
// check-pass
4+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!
2+
3+
// check-pass
4+
// ignore-tidy-end-whitespace
5+
fn main() {}

src/test/ui/shebang.rs

-5
This file was deleted.

0 commit comments

Comments
 (0)