@@ -756,7 +756,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
756
756
guard : Option < ExprId > ,
757
757
opt_match_place : Option < ( Option < & Place < ' tcx > > , Span ) > ,
758
758
) -> Option < SourceScope > {
759
- self . visit_primary_bindings (
759
+ self . visit_primary_bindings_special (
760
760
pattern,
761
761
UserTypeProjections :: none ( ) ,
762
762
& mut |this, name, mode, var, span, ty, user_ty| {
@@ -847,10 +847,32 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
847
847
}
848
848
}
849
849
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.
853
856
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 (
854
876
& mut self ,
855
877
pattern : & Pat < ' tcx > ,
856
878
pattern_user_ty : UserTypeProjections ,
@@ -864,17 +886,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
864
886
UserTypeProjections ,
865
887
) ,
866
888
) {
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
+
871
894
match pattern. kind {
872
895
PatKind :: Binding { name, mode, var, ty, ref subpattern, is_primary, .. } => {
873
896
if is_primary {
874
897
f ( self , name, mode, var, pattern. span , ty, pattern_user_ty. clone ( ) ) ;
875
898
}
876
899
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) ;
878
901
}
879
902
}
880
903
@@ -883,17 +906,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
883
906
let from = u64:: try_from ( prefix. len ( ) ) . unwrap ( ) ;
884
907
let to = u64:: try_from ( suffix. len ( ) ) . unwrap ( ) ;
885
908
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) ;
887
910
}
888
911
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) ;
894
913
}
895
914
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) ;
897
916
}
898
917
}
899
918
@@ -904,11 +923,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
904
923
| PatKind :: Error ( _) => { }
905
924
906
925
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) ;
908
927
}
909
928
910
929
PatKind :: DerefPattern { ref subpattern, .. } => {
911
- self . visit_primary_bindings ( subpattern, UserTypeProjections :: none ( ) , f) ;
930
+ visit_subpat ( self , subpattern, UserTypeProjections :: none ( ) , f) ;
912
931
}
913
932
914
933
PatKind :: AscribeUserType {
@@ -926,26 +945,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
926
945
927
946
let base_user_ty = self . canonical_user_type_annotations . push ( annotation. clone ( ) ) ;
928
947
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)
930
949
}
931
950
932
951
PatKind :: ExpandedConstant { ref subpattern, .. } => {
933
- self . visit_primary_bindings ( subpattern, pattern_user_ty, f)
952
+ visit_subpat ( self , subpattern, pattern_user_ty, f)
934
953
}
935
954
936
955
PatKind :: Leaf { ref subpatterns } => {
937
956
for subpattern in subpatterns {
938
957
let subpattern_user_ty = pattern_user_ty. clone ( ) . leaf ( subpattern. field ) ;
939
958
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) ;
941
960
}
942
961
}
943
962
944
963
PatKind :: Variant { adt_def, args : _, variant_index, ref subpatterns } => {
945
964
for subpattern in subpatterns {
946
965
let subpattern_user_ty =
947
966
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) ;
949
968
}
950
969
}
951
970
PatKind :: Or { ref pats } => {
@@ -954,7 +973,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
954
973
// `let (x | y) = ...`, the primary binding of `y` occurs in
955
974
// the right subpattern
956
975
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) ;
958
977
}
959
978
}
960
979
}
0 commit comments