Skip to content

Failure parsing | followed by if in tail expressions #93536

Closed
@j-browne

Description

@j-browne

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsC-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions