@@ -755,7 +755,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
755
755
guard : Option < ExprId > ,
756
756
opt_match_place : Option < ( Option < & Place < ' tcx > > , Span ) > ,
757
757
) -> Option < SourceScope > {
758
- self . visit_primary_bindings (
758
+ self . visit_primary_bindings_special (
759
759
pattern,
760
760
UserTypeProjections :: none ( ) ,
761
761
& mut |this, name, mode, var, span, ty, user_ty| {
@@ -846,10 +846,32 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
846
846
}
847
847
}
848
848
849
- /// Visit all of the primary bindings in a patterns, that is, visit the
850
- /// leftmost occurrence of each variable bound in a pattern. A variable
851
- /// will occur more than once in an or-pattern.
849
+ /// Visits all of the "primary" bindings in a pattern, i.e. the leftmost
850
+ /// occurrence of each variable bound by the pattern.
851
+ /// See [`PatKind::Binding::is_primary`] for more context.
852
+ ///
853
+ /// This variant provides only the limited subset of binding data needed
854
+ /// by its callers, and should be a "pure" visit without side-effects.
852
855
pub ( super ) fn visit_primary_bindings (
856
+ & mut self ,
857
+ pattern : & Pat < ' tcx > ,
858
+ f : & mut impl FnMut ( & mut Self , LocalVarId , Span ) ,
859
+ ) {
860
+ pattern. walk_always ( |pat| {
861
+ if let PatKind :: Binding { var, is_primary : true , .. } = pat. kind {
862
+ f ( self , var, pat. span ) ;
863
+ }
864
+ } )
865
+ }
866
+
867
+ /// Visits all of the "primary" bindings in a pattern, while preparing
868
+ /// additional user-type-annotation data needed by `declare_bindings`.
869
+ ///
870
+ /// This also has the side-effect of pushing all user type annotations
871
+ /// onto `canonical_user_type_annotations`, so that they end up in MIR
872
+ /// even if they aren't associated with any bindings.
873
+ #[ instrument( level = "debug" , skip( self , f) ) ]
874
+ fn visit_primary_bindings_special (
853
875
& mut self ,
854
876
pattern : & Pat < ' tcx > ,
855
877
pattern_user_ty : UserTypeProjections ,
@@ -863,17 +885,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
863
885
UserTypeProjections ,
864
886
) ,
865
887
) {
866
- debug ! (
867
- "visit_primary_bindings: pattern={:?} pattern_user_ty={:?}" ,
868
- pattern, pattern_user_ty
869
- ) ;
888
+ // Avoid having to write the full method name at each recursive call.
889
+ let visit_subpat = |this : & mut Self , subpat, user_tys, f : & mut _ | {
890
+ this. visit_primary_bindings_special ( subpat, user_tys, f)
891
+ } ;
892
+
870
893
match pattern. kind {
871
894
PatKind :: Binding { name, mode, var, ty, ref subpattern, is_primary, .. } => {
872
895
if is_primary {
873
896
f ( self , name, mode, var, pattern. span , ty, pattern_user_ty. clone ( ) ) ;
874
897
}
875
898
if let Some ( subpattern) = subpattern. as_ref ( ) {
876
- self . visit_primary_bindings ( subpattern, pattern_user_ty, f) ;
899
+ visit_subpat ( self , subpattern, pattern_user_ty, f) ;
877
900
}
878
901
}
879
902
@@ -882,17 +905,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
882
905
let from = u64:: try_from ( prefix. len ( ) ) . unwrap ( ) ;
883
906
let to = u64:: try_from ( suffix. len ( ) ) . unwrap ( ) ;
884
907
for subpattern in prefix. iter ( ) {
885
- self . visit_primary_bindings ( subpattern, pattern_user_ty. clone ( ) . index ( ) , f) ;
908
+ visit_subpat ( self , subpattern, pattern_user_ty. clone ( ) . index ( ) , f) ;
886
909
}
887
910
if let Some ( subpattern) = slice {
888
- self . visit_primary_bindings (
889
- subpattern,
890
- pattern_user_ty. clone ( ) . subslice ( from, to) ,
891
- f,
892
- ) ;
911
+ visit_subpat ( self , subpattern, pattern_user_ty. clone ( ) . subslice ( from, to) , f) ;
893
912
}
894
913
for subpattern in suffix. iter ( ) {
895
- self . visit_primary_bindings ( subpattern, pattern_user_ty. clone ( ) . index ( ) , f) ;
914
+ visit_subpat ( self , subpattern, pattern_user_ty. clone ( ) . index ( ) , f) ;
896
915
}
897
916
}
898
917
@@ -903,11 +922,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
903
922
| PatKind :: Error ( _) => { }
904
923
905
924
PatKind :: Deref { ref subpattern } => {
906
- self . visit_primary_bindings ( subpattern, pattern_user_ty. deref ( ) , f) ;
925
+ visit_subpat ( self , subpattern, pattern_user_ty. deref ( ) , f) ;
907
926
}
908
927
909
928
PatKind :: DerefPattern { ref subpattern, .. } => {
910
- self . visit_primary_bindings ( subpattern, UserTypeProjections :: none ( ) , f) ;
929
+ visit_subpat ( self , subpattern, UserTypeProjections :: none ( ) , f) ;
911
930
}
912
931
913
932
PatKind :: AscribeUserType {
@@ -925,26 +944,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
925
944
926
945
let base_user_ty = self . canonical_user_type_annotations . push ( annotation. clone ( ) ) ;
927
946
let subpattern_user_ty = pattern_user_ty. push_user_type ( base_user_ty) ;
928
- self . visit_primary_bindings ( subpattern, subpattern_user_ty, f)
947
+ visit_subpat ( self , subpattern, subpattern_user_ty, f)
929
948
}
930
949
931
950
PatKind :: ExpandedConstant { ref subpattern, .. } => {
932
- self . visit_primary_bindings ( subpattern, pattern_user_ty, f)
951
+ visit_subpat ( self , subpattern, pattern_user_ty, f)
933
952
}
934
953
935
954
PatKind :: Leaf { ref subpatterns } => {
936
955
for subpattern in subpatterns {
937
956
let subpattern_user_ty = pattern_user_ty. clone ( ) . leaf ( subpattern. field ) ;
938
957
debug ! ( "visit_primary_bindings: subpattern_user_ty={:?}" , subpattern_user_ty) ;
939
- self . visit_primary_bindings ( & subpattern. pattern , subpattern_user_ty, f) ;
958
+ visit_subpat ( self , & subpattern. pattern , subpattern_user_ty, f) ;
940
959
}
941
960
}
942
961
943
962
PatKind :: Variant { adt_def, args : _, variant_index, ref subpatterns } => {
944
963
for subpattern in subpatterns {
945
964
let subpattern_user_ty =
946
965
pattern_user_ty. clone ( ) . variant ( adt_def, variant_index, subpattern. field ) ;
947
- self . visit_primary_bindings ( & subpattern. pattern , subpattern_user_ty, f) ;
966
+ visit_subpat ( self , & subpattern. pattern , subpattern_user_ty, f) ;
948
967
}
949
968
}
950
969
PatKind :: Or { ref pats } => {
@@ -953,7 +972,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
953
972
// `let (x | y) = ...`, the primary binding of `y` occurs in
954
973
// the right subpattern
955
974
for subpattern in pats. iter ( ) {
956
- self . visit_primary_bindings ( subpattern, pattern_user_ty. clone ( ) , f) ;
975
+ visit_subpat ( self , subpattern, pattern_user_ty. clone ( ) , f) ;
957
976
}
958
977
}
959
978
}
0 commit comments