From 14e57b1e0b469ff14f290ef546176bdcb4c9a2c2 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Thu, 6 Oct 2022 19:14:08 +0300 Subject: [PATCH] Allow Or patterns in IfLet guard --- compiler/rustc_ast_lowering/src/expr.rs | 25 ++++++++++++++++++- src/test/ui/rfc-2294-if-let-guard/run-pass.rs | 6 +++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 46886c518afd5..09c7670eba696 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -512,8 +512,31 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr_call(overall_span, constructor, std::slice::from_ref(expr)) } + fn is_guard_if_let(&self, arm: &Arm) -> bool { + let mut if_let = false; + let _guard = arm.guard.as_ref().map(|cond| { + if let ExprKind::Let(..) = cond.kind { + if_let = true; + } else { + if_let = false; + } + }); + if_let + } + fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> { - let pat = self.lower_pat(&arm.pat); + let pat; + + // If we are using 'IfLet' guard with 'PatKind::Or' each subpattern gets it's own local + // which in confuses borrow checker about which of those locals are initialzied are which are not. + // This makes it so we only use last 'pat' in 'Or' pattern. + // See issue #88015 for more info. + if let PatKind::Or(pats) = &arm.pat.kind && self.is_guard_if_let(arm){ + pat = self.lower_pat(pats.last().unwrap()); + }else{ + pat = self.lower_pat(&arm.pat); + } + let guard = arm.guard.as_ref().map(|cond| { if let ExprKind::Let(ref pat, ref scrutinee, span) = cond.kind { hir::Guard::IfLet(self.arena.alloc(hir::Let { diff --git a/src/test/ui/rfc-2294-if-let-guard/run-pass.rs b/src/test/ui/rfc-2294-if-let-guard/run-pass.rs index 3da57989df2b5..3f63b0c3f21ea 100644 --- a/src/test/ui/rfc-2294-if-let-guard/run-pass.rs +++ b/src/test/ui/rfc-2294-if-let-guard/run-pass.rs @@ -30,4 +30,10 @@ fn main() { Some(x) if let Foo::Qux(y) = qux(x) => assert_eq!(y, 84), _ => panic!(), } + match () { + () | () if let x = 0 => { + x; + }, + _ => {} + }; }