@@ -158,22 +158,7 @@ macro_rules! make_mir_visitor {
158
158
self . super_place_base( base, context, location) ;
159
159
}
160
160
161
- fn visit_projection( & mut self ,
162
- base: & $( $mutability) ? PlaceBase <' tcx>,
163
- projection: & $( $mutability) ? [ PlaceElem <' tcx>] ,
164
- context: PlaceContext ,
165
- location: Location ) {
166
- self . super_projection( base, projection, context, location) ;
167
- }
168
-
169
- fn visit_projection_elem( & mut self ,
170
- base: & $( $mutability) ? PlaceBase <' tcx>,
171
- proj_base: & $( $mutability) ? [ PlaceElem <' tcx>] ,
172
- elem: & $( $mutability) ? PlaceElem <' tcx>,
173
- context: PlaceContext ,
174
- location: Location ) {
175
- self . super_projection_elem( base, proj_base, elem, context, location) ;
176
- }
161
+ visit_place_fns!( $( $mutability) ?) ;
177
162
178
163
fn visit_constant( & mut self ,
179
164
constant: & $( $mutability) ? Constant <' tcx>,
@@ -681,28 +666,6 @@ macro_rules! make_mir_visitor {
681
666
) ;
682
667
}
683
668
684
- fn super_place( & mut self ,
685
- place: & $( $mutability) ? Place <' tcx>,
686
- context: PlaceContext ,
687
- location: Location ) {
688
- let mut context = context;
689
-
690
- if !place. projection. is_empty( ) {
691
- context = if context. is_mutating_use( ) {
692
- PlaceContext :: MutatingUse ( MutatingUseContext :: Projection )
693
- } else {
694
- PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Projection )
695
- } ;
696
- }
697
-
698
- self . visit_place_base( & $( $mutability) ? place. base, context, location) ;
699
-
700
- self . visit_projection( & $( $mutability) ? place. base,
701
- & $( $mutability) ? place. projection,
702
- context,
703
- location) ;
704
- }
705
-
706
669
fn super_place_base( & mut self ,
707
670
place_base: & $( $mutability) ? PlaceBase <' tcx>,
708
671
context: PlaceContext ,
@@ -717,45 +680,6 @@ macro_rules! make_mir_visitor {
717
680
}
718
681
}
719
682
720
- fn super_projection( & mut self ,
721
- base: & $( $mutability) ? PlaceBase <' tcx>,
722
- projection: & $( $mutability) ? [ PlaceElem <' tcx>] ,
723
- context: PlaceContext ,
724
- location: Location ) {
725
- let mut cursor = projection;
726
- while let [ proj_base @ .., elem] = cursor {
727
- cursor = proj_base;
728
- self . visit_projection_elem( base, cursor, elem, context, location) ;
729
- }
730
- }
731
-
732
- fn super_projection_elem( & mut self ,
733
- _base: & $( $mutability) ? PlaceBase <' tcx>,
734
- _proj_base: & $( $mutability) ? [ PlaceElem <' tcx>] ,
735
- elem: & $( $mutability) ? PlaceElem <' tcx>,
736
- _context: PlaceContext ,
737
- location: Location ) {
738
- match elem {
739
- ProjectionElem :: Field ( _field, ty) => {
740
- self . visit_ty( ty, TyContext :: Location ( location) ) ;
741
- }
742
- ProjectionElem :: Index ( local) => {
743
- self . visit_local(
744
- local,
745
- PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Copy ) ,
746
- location
747
- ) ;
748
- }
749
- ProjectionElem :: Deref |
750
- ProjectionElem :: Subslice { from: _, to: _ } |
751
- ProjectionElem :: ConstantIndex { offset: _,
752
- min_length: _,
753
- from_end: _ } |
754
- ProjectionElem :: Downcast ( _, _) => {
755
- }
756
- }
757
- }
758
-
759
683
fn super_local_decl( & mut self ,
760
684
local: Local ,
761
685
local_decl: & $( $mutability) ? LocalDecl <' tcx>) {
@@ -858,6 +782,141 @@ macro_rules! make_mir_visitor {
858
782
}
859
783
}
860
784
785
+ macro_rules! visit_place_fns {
786
+ ( mut ) => (
787
+ fn super_place(
788
+ & mut self ,
789
+ place: & mut Place <' tcx>,
790
+ context: PlaceContext ,
791
+ location: Location ,
792
+ ) {
793
+ self . visit_place_base( & mut place. base, context, location) ;
794
+
795
+ if let Some ( new_projection) = self . process_projection( & place. projection) {
796
+ place. projection = new_projection;
797
+ }
798
+ }
799
+
800
+ fn process_projection(
801
+ & mut self ,
802
+ projection: & ' a [ PlaceElem <' tcx>] ,
803
+ ) -> Option <Box <[ PlaceElem <' tcx>] >> {
804
+ let mut projection = Cow :: Borrowed ( projection) ;
805
+
806
+ for i in 0 ..projection. len( ) {
807
+ if let Some ( elem) = projection. get( i) {
808
+ if let Cow :: Owned ( elem) = self . process_projection_elem( Cow :: Borrowed ( elem) ) {
809
+ let vec = projection. to_mut( ) ;
810
+ vec[ i] = elem;
811
+ }
812
+ }
813
+ }
814
+
815
+ match projection {
816
+ Cow :: Borrowed ( _) => None ,
817
+ Cow :: Owned ( vec) => Some ( vec. into_boxed_slice( ) ) ,
818
+ }
819
+ }
820
+
821
+ fn process_projection_elem(
822
+ & mut self ,
823
+ elem: Cow <' a, PlaceElem <' tcx>>,
824
+ ) -> Cow <' a, PlaceElem <' tcx>> {
825
+ elem
826
+ }
827
+ ) ;
828
+
829
+ ( ) => (
830
+ fn visit_projection(
831
+ & mut self ,
832
+ base: & PlaceBase <' tcx>,
833
+ projection: & [ PlaceElem <' tcx>] ,
834
+ context: PlaceContext ,
835
+ location: Location ,
836
+ ) {
837
+ self . super_projection( base, projection, context, location) ;
838
+ }
839
+
840
+ fn visit_projection_elem(
841
+ & mut self ,
842
+ base: & PlaceBase <' tcx>,
843
+ proj_base: & [ PlaceElem <' tcx>] ,
844
+ elem: & PlaceElem <' tcx>,
845
+ context: PlaceContext ,
846
+ location: Location ,
847
+ ) {
848
+ self . super_projection_elem( base, proj_base, elem, context, location) ;
849
+ }
850
+
851
+ fn super_place(
852
+ & mut self ,
853
+ place: & Place <' tcx>,
854
+ context: PlaceContext ,
855
+ location: Location ,
856
+ ) {
857
+ let mut context = context;
858
+
859
+ if !place. projection. is_empty( ) {
860
+ context = if context. is_mutating_use( ) {
861
+ PlaceContext :: MutatingUse ( MutatingUseContext :: Projection )
862
+ } else {
863
+ PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Projection )
864
+ } ;
865
+ }
866
+
867
+ self . visit_place_base( & place. base, context, location) ;
868
+
869
+ self . visit_projection( & place. base,
870
+ & place. projection,
871
+ context,
872
+ location) ;
873
+ }
874
+
875
+ fn super_projection(
876
+ & mut self ,
877
+ base: & PlaceBase <' tcx>,
878
+ projection: & [ PlaceElem <' tcx>] ,
879
+ context: PlaceContext ,
880
+ location: Location ,
881
+ ) {
882
+ let mut cursor = projection;
883
+ while let [ proj_base @ .., elem] = cursor {
884
+ cursor = proj_base;
885
+ self . visit_projection_elem( base, cursor, elem, context, location) ;
886
+ }
887
+ }
888
+
889
+ fn super_projection_elem(
890
+ & mut self ,
891
+ _base: & PlaceBase <' tcx>,
892
+ _proj_base: & [ PlaceElem <' tcx>] ,
893
+ elem: & PlaceElem <' tcx>,
894
+ _context: PlaceContext ,
895
+ location: Location ,
896
+ ) {
897
+ match elem {
898
+ ProjectionElem :: Field ( _field, ty) => {
899
+ self . visit_ty( ty, TyContext :: Location ( location) ) ;
900
+ }
901
+ ProjectionElem :: Index ( local) => {
902
+ self . visit_local(
903
+ local,
904
+ PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Copy ) ,
905
+ location
906
+ ) ;
907
+ }
908
+ ProjectionElem :: Deref |
909
+ ProjectionElem :: Subslice { from: _, to: _ } |
910
+ ProjectionElem :: ConstantIndex { offset: _,
911
+ min_length: _,
912
+ from_end: _ } |
913
+ ProjectionElem :: Downcast ( _, _) => {
914
+ }
915
+ }
916
+ }
917
+ ) ;
918
+ }
919
+
861
920
make_mir_visitor ! ( Visitor , ) ;
862
921
make_mir_visitor ! ( MutVisitor , mut ) ;
863
922
0 commit comments