@@ -227,6 +227,9 @@ pub enum StmtKind<'tcx> {
227
227
228
228
/// The lint level for this `let` statement.
229
229
lint_level : LintLevel ,
230
+
231
+ /// Span of the `let <PAT> = <INIT>` part.
232
+ span : Span ,
230
233
} ,
231
234
}
232
235
@@ -594,6 +597,55 @@ impl<'tcx> Pat<'tcx> {
594
597
_ => None ,
595
598
}
596
599
}
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
+ }
597
649
}
598
650
599
651
impl < ' tcx > IntoDiagnosticArg for Pat < ' tcx > {
@@ -879,7 +931,7 @@ mod size_asserts {
879
931
static_assert_size ! ( ExprKind <' _>, 40 ) ;
880
932
static_assert_size ! ( Pat <' _>, 72 ) ;
881
933
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 ) ;
884
936
// tidy-alphabetical-end
885
937
}
0 commit comments