diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index e0e78a4d6095..7c95c7f64809 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -505,14 +505,19 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> { + let pat = self.lower_pat(&arm.pat); + let guard = arm.guard.as_ref().map(|cond| { + if let ExprKind::Let(ref pat, ref scrutinee) = cond.kind { + hir::Guard::IfLet(self.lower_pat(pat), self.lower_expr(scrutinee)) + } else { + hir::Guard::If(self.lower_expr(cond)) + } + }); hir::Arm { hir_id: self.next_id(), attrs: self.lower_attrs(&arm.attrs), - pat: self.lower_pat(&arm.pat), - guard: match arm.guard { - Some(ref x) => Some(hir::Guard::If(self.lower_expr(x))), - _ => None, - }, + pat, + guard, body: self.lower_expr(&arm.body), span: arm.span, } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 44dc6673564a..03cb4b76dc0e 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1160,6 +1160,7 @@ pub struct Arm<'hir> { #[derive(Debug, HashStable_Generic)] pub enum Guard<'hir> { If(&'hir Expr<'hir>), + IfLet(&'hir Pat<'hir>, &'hir Expr<'hir>), } #[derive(Debug, HashStable_Generic)] diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 3e8fc689acf7..ea3f2b7f679e 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1228,6 +1228,10 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) { if let Some(ref g) = arm.guard { match g { Guard::If(ref e) => visitor.visit_expr(e), + Guard::IfLet(ref pat, ref e) => { + visitor.visit_pat(pat); + visitor.visit_expr(e); + } } } visitor.visit_expr(&arm.body); diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 25b09d76295f..6897a3495131 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -2002,6 +2002,15 @@ impl<'a> State<'a> { self.print_expr(&e); self.s.space(); } + hir::Guard::IfLet(pat, e) => { + self.word_nbsp("if"); + self.word_nbsp("let"); + self.print_pat(&pat); + self.s.space(); + self.word_space("="); + self.print_expr(&e); + self.s.space(); + } } } self.word_space("=>"); diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs index c0a9bbc36b24..311d1afcfc0e 100644 --- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs +++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs @@ -6,7 +6,6 @@ fn _if_let_guard() { match () { () if let 0 = 1 => {} //~^ ERROR `if let` guard is not implemented - //~| ERROR `let` expressions are not supported here () if (let 0 = 1) => {} //~^ ERROR `let` expressions in this position are experimental diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr index 5c7f8190dd6e..d43096336c5b 100644 --- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr +++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr @@ -169,15 +169,6 @@ LL | use_expr!((let 0 = 1)); = note: see issue #53667 for more information = help: add `#![feature(let_chains)]` to the crate attributes to enable -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:7:15 - | -LL | () if let 0 = 1 => {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if`- and `while`-expressions - = note: as well as when nested within `&&` and parenthesis in those conditions - error: `let` expressions are not supported here --> $DIR/feature-gate.rs:11:16 |