diff --git a/compiler/rustc_mir_build/src/thir/visit.rs b/compiler/rustc_mir_build/src/thir/visit.rs index 1a60b1de7fd9..0f3276a1b057 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>) {} } @@ -142,18 +146,19 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp } pub fn walk_stmt<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, stmt: &Stmt<'tcx>) { - match stmt.kind { - StmtKind::Expr { expr, scope: _ } => visitor.visit_expr(&visitor.thir()[expr]), + match &stmt.kind { + StmtKind::Expr { expr, scope: _ } => visitor.visit_expr(&visitor.thir()[*expr]), StmtKind::Let { initializer, remainder_scope: _, init_scope: _, - pattern: _, + pattern, lint_level: _, } => { if let Some(init) = initializer { - visitor.visit_expr(&visitor.thir()[init]); + visitor.visit_expr(&visitor.thir()[*init]); } + visitor.visit_pat(&pattern); } } } @@ -170,10 +175,48 @@ 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, .. } + | Deref { subpattern, .. } + | Binding { subpattern: Some(subpattern), .. } => visitor.visit_pat(&subpattern), + Binding { .. } | Wild => {} + Variant { subpatterns, .. } | 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); + } + } + }; +}