@@ -640,11 +640,17 @@ impl<'tcx> Pat<'tcx> {
640640 _ => None ,
641641 }
642642 }
643+ }
643644
645+ impl < ' tcx > Thir < ' tcx > {
644646 /// Call `f` on every "binding" in a pattern, e.g., on `a` in
645647 /// `match foo() { Some(a) => (), None => () }`
646- pub fn each_binding ( & self , mut f : impl FnMut ( Symbol , ByRef , Ty < ' tcx > , Span ) ) {
647- self . walk_always ( |p| {
648+ pub fn for_each_binding_in_pat (
649+ & self ,
650+ pat : & Pat < ' tcx > ,
651+ mut f : impl FnMut ( Symbol , ByRef , Ty < ' tcx > , Span ) ,
652+ ) {
653+ self . walk_pat_always ( pat, |p| {
648654 if let PatKind :: Binding { name, mode, ty, .. } = p. kind {
649655 f ( name, mode. 0 , ty, p. span ) ;
650656 }
@@ -654,22 +660,22 @@ impl<'tcx> Pat<'tcx> {
654660 /// Walk the pattern in left-to-right order.
655661 ///
656662 /// If `it(pat)` returns `false`, the children are not visited.
657- pub fn walk ( & self , mut it : impl FnMut ( & Pat < ' tcx > ) -> bool ) {
658- self . walk_ ( & mut it)
663+ pub fn walk_pat ( & self , pat : & Pat < ' tcx > , mut it : impl FnMut ( & Pat < ' tcx > ) -> bool ) {
664+ self . walk_pat_inner ( pat , & mut it)
659665 }
660666
661- fn walk_ ( & self , it : & mut impl FnMut ( & Pat < ' tcx > ) -> bool ) {
662- if !it ( self ) {
667+ fn walk_pat_inner ( & self , pat : & Pat < ' tcx > , it : & mut impl FnMut ( & Pat < ' tcx > ) -> bool ) {
668+ if !it ( pat ) {
663669 return ;
664670 }
665671
666- for_each_immediate_subpat ( self , |p| p . walk_ ( it) ) ;
672+ for_each_immediate_subpat ( pat , |p| self . walk_pat_inner ( p , it) ) ;
667673 }
668674
669675 /// Whether the pattern has a `PatKind::Error` nested within.
670- pub fn pat_error_reported ( & self ) -> Result < ( ) , ErrorGuaranteed > {
676+ pub fn pat_error_reported ( & self , pat : & Pat < ' tcx > ) -> Result < ( ) , ErrorGuaranteed > {
671677 let mut error = None ;
672- self . walk ( |pat| {
678+ self . walk_pat ( pat , |pat| {
673679 if let PatKind :: Error ( e) = pat. kind
674680 && error. is_none ( )
675681 {
@@ -683,26 +689,39 @@ impl<'tcx> Pat<'tcx> {
683689 }
684690 }
685691
692+ pub fn pat_references_error ( & self , pat : & Pat < ' tcx > ) -> bool {
693+ use rustc_type_ir:: visit:: TypeVisitableExt ;
694+
695+ let mut references_error = TypeVisitableExt :: references_error ( pat) ;
696+ if !references_error {
697+ for_each_immediate_subpat ( pat, |p| {
698+ references_error = references_error || self . pat_references_error ( p) ;
699+ } ) ;
700+ }
701+
702+ references_error
703+ }
704+
686705 /// Walk the pattern in left-to-right order.
687706 ///
688707 /// If you always want to recurse, prefer this method over `walk`.
689- pub fn walk_always ( & self , mut it : impl FnMut ( & Pat < ' tcx > ) ) {
690- self . walk ( |p| {
708+ pub fn walk_pat_always ( & self , pat : & Pat < ' tcx > , mut it : impl FnMut ( & Pat < ' tcx > ) ) {
709+ self . walk_pat ( pat , |p| {
691710 it ( p) ;
692711 true
693712 } )
694713 }
695714
696715 /// Whether this a never pattern.
697- pub fn is_never_pattern ( & self ) -> bool {
716+ pub fn is_never_pattern ( & self , pat : & Pat < ' tcx > ) -> bool {
698717 let mut is_never_pattern = false ;
699- self . walk ( |pat| match & pat. kind {
718+ self . walk_pat ( pat , |pat| match & pat. kind {
700719 PatKind :: Never => {
701720 is_never_pattern = true ;
702721 false
703722 }
704723 PatKind :: Or { pats } => {
705- is_never_pattern = pats. iter ( ) . all ( |p| p . is_never_pattern ( ) ) ;
724+ is_never_pattern = pats. iter ( ) . all ( |p| self . is_never_pattern ( p ) ) ;
706725 false
707726 }
708727 _ => true ,
0 commit comments