@@ -640,11 +640,17 @@ impl<'tcx> Pat<'tcx> {
640
640
_ => None ,
641
641
}
642
642
}
643
+ }
643
644
645
+ impl < ' tcx > Thir < ' tcx > {
644
646
/// Call `f` on every "binding" in a pattern, e.g., on `a` in
645
647
/// `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| {
648
654
if let PatKind :: Binding { name, mode, ty, .. } = p. kind {
649
655
f ( name, mode. 0 , ty, p. span ) ;
650
656
}
@@ -654,22 +660,22 @@ impl<'tcx> Pat<'tcx> {
654
660
/// Walk the pattern in left-to-right order.
655
661
///
656
662
/// 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)
659
665
}
660
666
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 ) {
663
669
return ;
664
670
}
665
671
666
- for_each_immediate_subpat ( self , |p| p . walk_ ( it) ) ;
672
+ for_each_immediate_subpat ( pat , |p| self . walk_pat_inner ( p , it) ) ;
667
673
}
668
674
669
675
/// 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 > {
671
677
let mut error = None ;
672
- self . walk ( |pat| {
678
+ self . walk_pat ( pat , |pat| {
673
679
if let PatKind :: Error ( e) = pat. kind
674
680
&& error. is_none ( )
675
681
{
@@ -683,26 +689,39 @@ impl<'tcx> Pat<'tcx> {
683
689
}
684
690
}
685
691
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
+
686
705
/// Walk the pattern in left-to-right order.
687
706
///
688
707
/// 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| {
691
710
it ( p) ;
692
711
true
693
712
} )
694
713
}
695
714
696
715
/// Whether this a never pattern.
697
- pub fn is_never_pattern ( & self ) -> bool {
716
+ pub fn is_never_pattern ( & self , pat : & Pat < ' tcx > ) -> bool {
698
717
let mut is_never_pattern = false ;
699
- self . walk ( |pat| match & pat. kind {
718
+ self . walk_pat ( pat , |pat| match & pat. kind {
700
719
PatKind :: Never => {
701
720
is_never_pattern = true ;
702
721
false
703
722
}
704
723
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 ) ) ;
706
725
false
707
726
}
708
727
_ => true ,
0 commit comments