Closed
Description
There seems to be a problem with parsing |
followed by if
, but only for tail expressions. If I bind it using let
, the code compiles. Here is an example (playground):
// Fails to compile
/*
fn or_vals(conds: (bool, bool), vals: (u8, u8)) -> u8 {
if conds.0 { vals.0 } else { 0 } | if conds.1 { vals.1 } else { 0 }
}
*/
fn or_vals(conds: (bool, bool), vals: (u8, u8)) -> u8 {
let x = if conds.0 { vals.0 } else { 0 } | if conds.1 { vals.1 } else { 0 };
x
}
fn main() {
assert_eq!(or_vals((false, false), (1, 2)), 0);
assert_eq!(or_vals((true, false), (1, 2)), 1);
assert_eq!(or_vals((false, true), (1, 2)), 2);
assert_eq!(or_vals((true, true), (1, 2)), 3);
println!("tests pass!");
}
The first version fails to compile with this error:
error: expected identifier, found keyword `if`
--> src/main.rs:5:40
|
5 | if conds.0 { vals.0 } else { 0 } | if conds.1 { vals.1 } else { 0 }
| ^^ expected identifier, found keyword
error: expected one of `,`, `:`, or `@`, found `conds`
--> src/main.rs:5:43
|
5 | if conds.0 { vals.0 } else { 0 } | if conds.1 { vals.1 } else { 0 }
| -^^^^^ expected one of `,`, `:`, or `@`
| |
| help: missing `,`
error: expected one of `,`, `:`, or `@`, found `.`
--> src/main.rs:5:48
|
5 | if conds.0 { vals.0 } else { 0 } | if conds.1 { vals.1 } else { 0 }
| ^
| |
| expected one of `,`, `:`, or `@`
| help: missing `,`
error: expected one of `,`, `...`, `..=`, `..`, or `:`, found `{`
--> src/main.rs:5:51
|
5 | if conds.0 { vals.0 } else { 0 } | if conds.1 { vals.1 } else { 0 }
| ^ expected one of `,`, `...`, `..=`, `..`, or `:`
error: could not compile `playground` due to 4 previous errors
I expect the first version to compile, and I also expect whether an expression is accepted or rejected by the compiler to not depend on if it is part of a let
statement or a tail expression.
Additionally, clippy suggests the first version via the clippy::let_and_return
lint.
This happens in stable, beta, and nightly.