Skip to content

When a match guard indirectly contains if let, rustc requires only the let_chains feature and not also if_let_guard #93150

Closed
@ChayimFriedman2

Description

@ChayimFriedman2

If you compile the following code:

fn main() {
    match true {
        _ if let true = true => {}
        _ => {}
    }
}

rustc complains as expected:

error[E0658]: `if let` guards are experimental
 --> src/main.rs:3:11
  |
5 |         _ if let true = true => {}
  |           ^^^^^^^^^^^^^^^^^^
  |
  = note: see issue #51114 <https://github.com/rust-lang/rust/issues/51114> for more information
  = help: add `#![feature(if_let_guard)]` to the crate attributes to enable
  = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`

Playground.

However, if I use the let_chains feature, by e.g. wrapping the let true = true in parentheses, or adding another clause, it compiles without error:

#![feature(let_chains)]

fn main() {
    match true {
        _ if let true = true && true => {}
        _ => {}
    }
}

Playground.

It depends only on the let_chains feature, instead of both let_chains and if_let_guard.

This is because here:

if let ExprKind::Let(..) = cond.kind {
// Remove the last feature gating of a `let` expression since it's stable.
this.sess.gated_spans.ungate_last(sym::let_chains, cond.span);
let span = if_span.to(cond.span);
this.sess.gated_spans.gate(sym::if_let_guard, span);
}

We only gate it under if_let_guard if the let is directly under the guard node.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-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