@@ -227,6 +227,9 @@ pub enum StmtKind<'tcx> {
227227
228228 /// The lint level for this `let` statement.
229229 lint_level : LintLevel ,
230+
231+ /// Span of the `let <PAT> = <INIT>` part.
232+ span : Span ,
230233 } ,
231234}
232235
@@ -594,6 +597,55 @@ impl<'tcx> Pat<'tcx> {
594597 _ => None ,
595598 }
596599 }
600+
601+ /// Call `f` on every "binding" in a pattern, e.g., on `a` in
602+ /// `match foo() { Some(a) => (), None => () }`
603+ pub fn each_binding ( & self , mut f : impl FnMut ( Symbol , BindingMode , Ty < ' tcx > , Span ) ) {
604+ self . walk_always ( |p| {
605+ if let PatKind :: Binding { name, mode, ty, .. } = p. kind {
606+ f ( name, mode, ty, p. span ) ;
607+ }
608+ } ) ;
609+ }
610+
611+ /// Walk the pattern in left-to-right order.
612+ ///
613+ /// If `it(pat)` returns `false`, the children are not visited.
614+ pub fn walk ( & self , mut it : impl FnMut ( & Pat < ' tcx > ) -> bool ) {
615+ self . walk_ ( & mut it)
616+ }
617+
618+ fn walk_ ( & self , it : & mut impl FnMut ( & Pat < ' tcx > ) -> bool ) {
619+ if !it ( self ) {
620+ return ;
621+ }
622+
623+ use PatKind :: * ;
624+ match & self . kind {
625+ Wild | Range ( ..) | Binding { subpattern : None , .. } | Constant { .. } => { }
626+ AscribeUserType { subpattern, .. }
627+ | Binding { subpattern : Some ( subpattern) , .. }
628+ | Deref { subpattern } => subpattern. walk_ ( it) ,
629+ Leaf { subpatterns } | Variant { subpatterns, .. } => {
630+ subpatterns. iter ( ) . for_each ( |field| field. pattern . walk_ ( it) )
631+ }
632+ Or { pats } => pats. iter ( ) . for_each ( |p| p. walk_ ( it) ) ,
633+ Array { box ref prefix, ref slice, box ref suffix }
634+ | Slice { box ref prefix, ref slice, box ref suffix } => {
635+ prefix. iter ( ) . chain ( slice. iter ( ) ) . chain ( suffix. iter ( ) ) . for_each ( |p| p. walk_ ( it) )
636+ }
637+ }
638+ }
639+
640+ /// Walk the pattern in left-to-right order.
641+ ///
642+ /// If you always want to recurse, prefer this method over `walk`.
643+ pub fn walk_always ( & self , mut it : impl FnMut ( & Pat < ' tcx > ) ) {
644+ self . walk ( |p| {
645+ it ( p) ;
646+ true
647+ } )
648+ }
597649}
598650
599651impl < ' tcx > IntoDiagnosticArg for Pat < ' tcx > {
@@ -879,7 +931,7 @@ mod size_asserts {
879931 static_assert_size ! ( ExprKind <' _>, 40 ) ;
880932 static_assert_size ! ( Pat <' _>, 72 ) ;
881933 static_assert_size ! ( PatKind <' _>, 56 ) ;
882- static_assert_size ! ( Stmt <' _>, 48 ) ;
883- static_assert_size ! ( StmtKind <' _>, 40 ) ;
934+ static_assert_size ! ( Stmt <' _>, 56 ) ;
935+ static_assert_size ! ( StmtKind <' _>, 48 ) ;
884936 // tidy-alphabetical-end
885937}
0 commit comments