-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Field access of block: discrepancy between parser-lalr and rustc #28379
Comments
/cc @rust-lang/lang , is this grammar correct or just incidental? (tagging with lang until I know what they want, and I'll document that.) |
Hmm, interesting question! I think the reference grammar is correct here, and rustc is not working properly. The rule is that "statement-like" expressions cannot take part in binary expressions; I think that should include the For example, this fails to compile: fn foo(x: u32) { }
fn main() {
let f = foo;
{ f } (22)
} but the error it gives me is surprising:
|
If fn main() {
1 == {1};
1 == ({1} + {1});
} As the LALR grammar describes it, a semicolon-terminated expression statement is a Both parsers reject this: fn main() {
{1} == 1;
} I discovered an interesting case, though: fn main() {
let x = { 1 + {2} * {3} };
println!("{}", x);
} This code parses and compiles, but the two parsers disagree on what it should output.
If I remove the unnecessary block around the expression, fn main() {
let x = 1 + {2} * {3}; // removed the unnecessary block here
println!("{}", x);
} |
I split off the operator precedence issue to #28777. |
Let me be more precise. It cannot START a binary operator, when in On Wed, Sep 30, 2015 at 4:45 PM, Ryan Prichard [email protected]
|
In any case, this all feels like good motivation for me to try and get some On Wed, Sep 30, 2015 at 5:05 PM, Nicholas Matsakis [email protected]
|
Nominating for discussion. Related to #28785 |
I just realized why that example I gave of |
triage: P-medium This is a backwards incompat issue, but feels like an edge case. Nonetheless we should definitely fix it! |
I discovered another quirk involving the LALR grammar -- it accepts this: fn main() {
struct S { f: i32 };
let z = S { f: 0 };
match 0 { _ => &z }.f // <-- note the lack of semicolon
match 0 { _ => &z }.f // <-- note the lack of semicolon
()
} A rustc also accepts the code, but only if the semicolons are added after the two This quirk only applies to non-basic block expressions. |
This statement is not completely true, which reveals another LALR bug. It should accept this: fn main() {
{ ([0],) }.0[0];
{ ((|| {}),) }.0();
}
Edit: I'm slightly off still. |
Triage: |
The grammar in src/grammar/parser-lalr.y should probably be relaxed to accept the first example.
AFAIK, Rust could allow the other two cases (and others), because there are no statements or expressions that begin with
as
or==
.The text was updated successfully, but these errors were encountered: