@@ -756,7 +756,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
756756 guard : Option < ExprId > ,
757757 opt_match_place : Option < ( Option < & Place < ' tcx > > , Span ) > ,
758758 ) -> Option < SourceScope > {
759- self . visit_primary_bindings (
759+ self . visit_primary_bindings_special (
760760 pattern,
761761 UserTypeProjections :: none ( ) ,
762762 & mut |this, name, mode, var, span, ty, user_ty| {
@@ -847,10 +847,32 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
847847 }
848848 }
849849
850- /// Visit all of the primary bindings in a patterns, that is, visit the
851- /// leftmost occurrence of each variable bound in a pattern. A variable
852- /// will occur more than once in an or-pattern.
850+ /// Visits all of the "primary" bindings in a pattern, i.e. the leftmost
851+ /// occurrence of each variable bound by the pattern.
852+ /// See [`PatKind::Binding::is_primary`] for more context.
853+ ///
854+ /// This variant provides only the limited subset of binding data needed
855+ /// by its callers, and should be a "pure" visit without side-effects.
853856 pub ( super ) fn visit_primary_bindings (
857+ & mut self ,
858+ pattern : & Pat < ' tcx > ,
859+ f : & mut impl FnMut ( & mut Self , LocalVarId , Span ) ,
860+ ) {
861+ pattern. walk_always ( |pat| {
862+ if let PatKind :: Binding { var, is_primary : true , .. } = pat. kind {
863+ f ( self , var, pat. span ) ;
864+ }
865+ } )
866+ }
867+
868+ /// Visits all of the "primary" bindings in a pattern, while preparing
869+ /// additional user-type-annotation data needed by `declare_bindings`.
870+ ///
871+ /// This also has the side-effect of pushing all user type annotations
872+ /// onto `canonical_user_type_annotations`, so that they end up in MIR
873+ /// even if they aren't associated with any bindings.
874+ #[ instrument( level = "debug" , skip( self , f) ) ]
875+ fn visit_primary_bindings_special (
854876 & mut self ,
855877 pattern : & Pat < ' tcx > ,
856878 pattern_user_ty : UserTypeProjections ,
@@ -864,17 +886,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
864886 UserTypeProjections ,
865887 ) ,
866888 ) {
867- debug ! (
868- "visit_primary_bindings: pattern={:?} pattern_user_ty={:?}" ,
869- pattern, pattern_user_ty
870- ) ;
889+ // Avoid having to write the full method name at each recursive call.
890+ let visit_subpat = |this : & mut Self , subpat, user_tys, f : & mut _ | {
891+ this. visit_primary_bindings_special ( subpat, user_tys, f)
892+ } ;
893+
871894 match pattern. kind {
872895 PatKind :: Binding { name, mode, var, ty, ref subpattern, is_primary, .. } => {
873896 if is_primary {
874897 f ( self , name, mode, var, pattern. span , ty, pattern_user_ty. clone ( ) ) ;
875898 }
876899 if let Some ( subpattern) = subpattern. as_ref ( ) {
877- self . visit_primary_bindings ( subpattern, pattern_user_ty, f) ;
900+ visit_subpat ( self , subpattern, pattern_user_ty, f) ;
878901 }
879902 }
880903
@@ -883,17 +906,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
883906 let from = u64:: try_from ( prefix. len ( ) ) . unwrap ( ) ;
884907 let to = u64:: try_from ( suffix. len ( ) ) . unwrap ( ) ;
885908 for subpattern in prefix. iter ( ) {
886- self . visit_primary_bindings ( subpattern, pattern_user_ty. clone ( ) . index ( ) , f) ;
909+ visit_subpat ( self , subpattern, pattern_user_ty. clone ( ) . index ( ) , f) ;
887910 }
888911 if let Some ( subpattern) = slice {
889- self . visit_primary_bindings (
890- subpattern,
891- pattern_user_ty. clone ( ) . subslice ( from, to) ,
892- f,
893- ) ;
912+ visit_subpat ( self , subpattern, pattern_user_ty. clone ( ) . subslice ( from, to) , f) ;
894913 }
895914 for subpattern in suffix. iter ( ) {
896- self . visit_primary_bindings ( subpattern, pattern_user_ty. clone ( ) . index ( ) , f) ;
915+ visit_subpat ( self , subpattern, pattern_user_ty. clone ( ) . index ( ) , f) ;
897916 }
898917 }
899918
@@ -904,11 +923,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
904923 | PatKind :: Error ( _) => { }
905924
906925 PatKind :: Deref { ref subpattern } => {
907- self . visit_primary_bindings ( subpattern, pattern_user_ty. deref ( ) , f) ;
926+ visit_subpat ( self , subpattern, pattern_user_ty. deref ( ) , f) ;
908927 }
909928
910929 PatKind :: DerefPattern { ref subpattern, .. } => {
911- self . visit_primary_bindings ( subpattern, UserTypeProjections :: none ( ) , f) ;
930+ visit_subpat ( self , subpattern, UserTypeProjections :: none ( ) , f) ;
912931 }
913932
914933 PatKind :: AscribeUserType {
@@ -926,26 +945,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
926945
927946 let base_user_ty = self . canonical_user_type_annotations . push ( annotation. clone ( ) ) ;
928947 let subpattern_user_ty = pattern_user_ty. push_user_type ( base_user_ty) ;
929- self . visit_primary_bindings ( subpattern, subpattern_user_ty, f)
948+ visit_subpat ( self , subpattern, subpattern_user_ty, f)
930949 }
931950
932951 PatKind :: ExpandedConstant { ref subpattern, .. } => {
933- self . visit_primary_bindings ( subpattern, pattern_user_ty, f)
952+ visit_subpat ( self , subpattern, pattern_user_ty, f)
934953 }
935954
936955 PatKind :: Leaf { ref subpatterns } => {
937956 for subpattern in subpatterns {
938957 let subpattern_user_ty = pattern_user_ty. clone ( ) . leaf ( subpattern. field ) ;
939958 debug ! ( "visit_primary_bindings: subpattern_user_ty={:?}" , subpattern_user_ty) ;
940- self . visit_primary_bindings ( & subpattern. pattern , subpattern_user_ty, f) ;
959+ visit_subpat ( self , & subpattern. pattern , subpattern_user_ty, f) ;
941960 }
942961 }
943962
944963 PatKind :: Variant { adt_def, args : _, variant_index, ref subpatterns } => {
945964 for subpattern in subpatterns {
946965 let subpattern_user_ty =
947966 pattern_user_ty. clone ( ) . variant ( adt_def, variant_index, subpattern. field ) ;
948- self . visit_primary_bindings ( & subpattern. pattern , subpattern_user_ty, f) ;
967+ visit_subpat ( self , & subpattern. pattern , subpattern_user_ty, f) ;
949968 }
950969 }
951970 PatKind :: Or { ref pats } => {
@@ -954,7 +973,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
954973 // `let (x | y) = ...`, the primary binding of `y` occurs in
955974 // the right subpattern
956975 for subpattern in pats. iter ( ) {
957- self . visit_primary_bindings ( subpattern, pattern_user_ty. clone ( ) , f) ;
976+ visit_subpat ( self , subpattern, pattern_user_ty. clone ( ) , f) ;
958977 }
959978 }
960979 }
0 commit comments