Recover shorthand struct literals in if conditions - #162295
Conversation
|
The parser was modified, potentially altering the grammar of (stable) Rust cc @fmease |
|
r? @khyperia rustbot has assigned @khyperia. Use Why was this reviewer chosen?The reviewer was selected based on:
|
| (self.look_ahead(1, |t| t.is_ident()) | ||
| && self.look_ahead(2, |t| t == &token::Comma || t == &token::Colon)) | ||
| // When struct literals are prohibited, `{ ident }` is normally parsed as a block. A | ||
| // second opening brace strongly suggests that the first pair belongs to a struct | ||
| // literal and the second starts the surrounding body. | ||
| || (self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL) | ||
| && self.look_ahead(1, Token::is_non_reserved_ident) | ||
| && self.look_ahead(2, |token| *token == token::CloseBrace) | ||
| && self.look_ahead(3, |token| *token == token::OpenBrace)) |
There was a problem hiding this comment.
This modifies the stable grammar of Rust and is thus not acceptable.
It regresses stable code like the following:
fn scope(cond: bool) {
let u = ();
if cond {
u
}
{
println!();
}
}or smaller:
#[cfg(false)] fn f() { if x { x } {} }There was a problem hiding this comment.
aha, yes! I didn't notice is_likely_struct_lit is on happy path, let me think about it.
There was a problem hiding this comment.
I updated the code.
This fix adds a lightweight extra { check after parsing each if or while body in error_on_ambiguous_struct_literal. If another block follows, it inspects the parsed AST to detect whether a shorthand struct literal was misinterpreted as the body.
I am not entirely satisfied with adding work to the normal parsing path, but I have not found a cleaner recovery point.
694f106 to
e8c0c3c
Compare
e8c0c3c to
ac7bb57
Compare
Fixes #147877