diff --git a/compiler/rustc_mir_build/src/thir/visit.rs b/compiler/rustc_mir_build/src/thir/visit.rs index 6e0229f38a574..f611bb6eb43e9 100644 --- a/compiler/rustc_mir_build/src/thir/visit.rs +++ b/compiler/rustc_mir_build/src/thir/visit.rs @@ -20,6 +20,10 @@ pub trait Visitor<'a, 'tcx: 'a>: Sized { walk_arm(self, arm); } + fn visit_pat(&mut self, pat: &Pat<'tcx>) { + walk_pat(self, pat); + } + fn visit_const(&mut self, _cnst: &'tcx Const<'tcx>) {} } @@ -155,12 +159,13 @@ pub fn walk_stmt<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, stmt: &Stm initializer, remainder_scope: _, init_scope: _, - pattern: _, + ref pattern, lint_level: _, } => { if let Some(init) = initializer { visitor.visit_expr(&visitor.thir()[init]); } + visitor.visit_pat(pattern); } } } @@ -177,10 +182,56 @@ pub fn walk_block<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, block: &B pub fn walk_arm<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, arm: &Arm<'tcx>) { match arm.guard { Some(Guard::If(expr)) => visitor.visit_expr(&visitor.thir()[expr]), - Some(Guard::IfLet(ref _pat, expr)) => { + Some(Guard::IfLet(ref pat, expr)) => { + visitor.visit_pat(pat); visitor.visit_expr(&visitor.thir()[expr]); } None => {} } + visitor.visit_pat(&arm.pattern); visitor.visit_expr(&visitor.thir()[arm.body]); } + +pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'tcx>) { + use PatKind::*; + match pat.kind.as_ref() { + AscribeUserType { subpattern, ascription: _ } + | Deref { subpattern } + | Binding { + subpattern: Some(subpattern), + mutability: _, + mode: _, + var: _, + ty: _, + is_primary: _, + name: _, + } => visitor.visit_pat(&subpattern), + Binding { .. } | Wild => {} + Variant { subpatterns, adt_def: _, substs: _, variant_index: _ } | Leaf { subpatterns } => { + for subpattern in subpatterns { + visitor.visit_pat(&subpattern.pattern); + } + } + Constant { value } => visitor.visit_const(value), + Range(range) => { + visitor.visit_const(range.lo); + visitor.visit_const(range.hi); + } + Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => { + for subpattern in prefix { + visitor.visit_pat(&subpattern); + } + if let Some(pat) = slice { + visitor.visit_pat(pat); + } + for subpattern in suffix { + visitor.visit_pat(&subpattern); + } + } + Or { pats } => { + for pat in pats { + visitor.visit_pat(&pat); + } + } + }; +}