@@ -11,88 +11,19 @@ use crate::location::{LocationIndex, LocationTable};
1111type VarPointRelation = Vec < ( Local , LocationIndex ) > ;
1212type PathPointRelation = Vec < ( MovePathIndex , LocationIndex ) > ;
1313
14- struct UseFactsExtractor < ' a , ' tcx > {
15- var_defined_at : & ' a mut VarPointRelation ,
16- var_used_at : & ' a mut VarPointRelation ,
17- location_table : & ' a LocationTable ,
18- var_dropped_at : & ' a mut VarPointRelation ,
19- move_data : & ' a MoveData < ' tcx > ,
20- path_accessed_at_base : & ' a mut PathPointRelation ,
21- }
22-
23- // A Visitor to walk through the MIR and extract point-wise facts
24- impl < ' tcx > UseFactsExtractor < ' _ , ' tcx > {
25- fn location_to_index ( & self , location : Location ) -> LocationIndex {
26- self . location_table . mid_index ( location)
27- }
28-
29- fn insert_def ( & mut self , local : Local , location : Location ) {
30- debug ! ( "UseFactsExtractor::insert_def()" ) ;
31- self . var_defined_at . push ( ( local, self . location_to_index ( location) ) ) ;
32- }
33-
34- fn insert_use ( & mut self , local : Local , location : Location ) {
35- debug ! ( "UseFactsExtractor::insert_use()" ) ;
36- self . var_used_at . push ( ( local, self . location_to_index ( location) ) ) ;
37- }
38-
39- fn insert_drop_use ( & mut self , local : Local , location : Location ) {
40- debug ! ( "UseFactsExtractor::insert_drop_use()" ) ;
41- self . var_dropped_at . push ( ( local, self . location_to_index ( location) ) ) ;
42- }
43-
44- fn insert_path_access ( & mut self , path : MovePathIndex , location : Location ) {
45- debug ! ( "UseFactsExtractor::insert_path_access({:?}, {:?})" , path, location) ;
46- self . path_accessed_at_base . push ( ( path, self . location_to_index ( location) ) ) ;
47- }
48-
49- fn place_to_mpi ( & self , place : & Place < ' tcx > ) -> Option < MovePathIndex > {
50- match self . move_data . rev_lookup . find ( place. as_ref ( ) ) {
51- LookupResult :: Exact ( mpi) => Some ( mpi) ,
52- LookupResult :: Parent ( mmpi) => mmpi,
53- }
54- }
55- }
56-
57- impl < ' a , ' tcx > Visitor < ' tcx > for UseFactsExtractor < ' a , ' tcx > {
58- fn visit_local ( & mut self , local : Local , context : PlaceContext , location : Location ) {
59- match def_use:: categorize ( context) {
60- Some ( DefUse :: Def ) => self . insert_def ( local, location) ,
61- Some ( DefUse :: Use ) => self . insert_use ( local, location) ,
62- Some ( DefUse :: Drop ) => self . insert_drop_use ( local, location) ,
63- _ => ( ) ,
64- }
65- }
66-
67- fn visit_place ( & mut self , place : & Place < ' tcx > , context : PlaceContext , location : Location ) {
68- self . super_place ( place, context, location) ;
69- match context {
70- PlaceContext :: NonMutatingUse ( _) => {
71- if let Some ( mpi) = self . place_to_mpi ( place) {
72- self . insert_path_access ( mpi, location) ;
73- }
74- }
75-
76- PlaceContext :: MutatingUse ( MutatingUseContext :: Borrow ) => {
77- if let Some ( mpi) = self . place_to_mpi ( place) {
78- self . insert_path_access ( mpi, location) ;
79- }
80- }
81- _ => ( ) ,
82- }
83- }
84- }
85-
86- pub ( super ) fn populate_access_facts < ' a , ' tcx > (
14+ /// Emit polonius facts for variable defs, uses, drops, and path accesses.
15+ pub ( super ) fn emit_access_facts < ' a , ' tcx > (
8716 typeck : & mut TypeChecker < ' a , ' tcx > ,
8817 body : & Body < ' tcx > ,
8918 move_data : & MoveData < ' tcx > ,
9019) {
9120 if let Some ( facts) = typeck. all_facts . as_mut ( ) {
92- debug ! ( "populate_access_facts()" ) ;
21+ debug ! ( "emit_access_facts()" ) ;
22+
23+ let _prof_timer = typeck. infcx . tcx . prof . generic_activity ( "polonius_fact_generation" ) ;
9324 let location_table = typeck. location_table ;
9425
95- let mut extractor = UseFactsExtractor {
26+ let mut extractor = AccessFactsExtractor {
9627 var_defined_at : & mut facts. var_defined_at ,
9728 var_used_at : & mut facts. var_used_at ,
9829 var_dropped_at : & mut facts. var_dropped_at ,
@@ -107,7 +38,6 @@ pub(super) fn populate_access_facts<'a, 'tcx>(
10738 "add use_of_var_derefs_origin facts - local={:?}, type={:?}" ,
10839 local, local_decl. ty
10940 ) ;
110- let _prof_timer = typeck. infcx . tcx . prof . generic_activity ( "polonius_fact_generation" ) ;
11141 let universal_regions = & typeck. universal_regions ;
11242 typeck. infcx . tcx . for_each_free_region ( & local_decl. ty , |region| {
11343 let region_vid = universal_regions. to_region_vid ( region) ;
@@ -119,12 +49,12 @@ pub(super) fn populate_access_facts<'a, 'tcx>(
11949
12050/// For every potentially drop()-touched region `region` in `local`'s type
12151/// (`kind`), emit a Polonius `use_of_var_derefs_origin(local, origin)` fact.
122- pub ( super ) fn add_drop_of_var_derefs_origin < ' tcx > (
52+ pub ( super ) fn emit_drop_facts < ' tcx > (
12353 typeck : & mut TypeChecker < ' _ , ' tcx > ,
12454 local : Local ,
12555 kind : & GenericArg < ' tcx > ,
12656) {
127- debug ! ( "add_drop_of_var_derefs_origin (local={:?}, kind={:?}" , local, kind) ;
57+ debug ! ( "emit_drop_facts (local={:?}, kind={:?}" , local, kind) ;
12858 if let Some ( facts) = typeck. all_facts . as_mut ( ) {
12959 let _prof_timer = typeck. infcx . tcx . prof . generic_activity ( "polonius_fact_generation" ) ;
13060 let universal_regions = & typeck. universal_regions ;
@@ -134,3 +64,60 @@ pub(super) fn add_drop_of_var_derefs_origin<'tcx>(
13464 } ) ;
13565 }
13666}
67+
68+ /// MIR visitor extracting point-wise facts about accesses.
69+ struct AccessFactsExtractor < ' a , ' tcx > {
70+ var_defined_at : & ' a mut VarPointRelation ,
71+ var_used_at : & ' a mut VarPointRelation ,
72+ location_table : & ' a LocationTable ,
73+ var_dropped_at : & ' a mut VarPointRelation ,
74+ move_data : & ' a MoveData < ' tcx > ,
75+ path_accessed_at_base : & ' a mut PathPointRelation ,
76+ }
77+
78+ impl < ' tcx > AccessFactsExtractor < ' _ , ' tcx > {
79+ fn location_to_index ( & self , location : Location ) -> LocationIndex {
80+ self . location_table . mid_index ( location)
81+ }
82+ }
83+
84+ impl < ' a , ' tcx > Visitor < ' tcx > for AccessFactsExtractor < ' a , ' tcx > {
85+ fn visit_local ( & mut self , local : Local , context : PlaceContext , location : Location ) {
86+ match def_use:: categorize ( context) {
87+ Some ( DefUse :: Def ) => {
88+ debug ! ( "AccessFactsExtractor - emit def" ) ;
89+ self . var_defined_at . push ( ( local, self . location_to_index ( location) ) ) ;
90+ }
91+ Some ( DefUse :: Use ) => {
92+ debug ! ( "AccessFactsExtractor - emit use" ) ;
93+ self . var_used_at . push ( ( local, self . location_to_index ( location) ) ) ;
94+ }
95+ Some ( DefUse :: Drop ) => {
96+ debug ! ( "AccessFactsExtractor - emit drop" ) ;
97+ self . var_dropped_at . push ( ( local, self . location_to_index ( location) ) ) ;
98+ }
99+ _ => ( ) ,
100+ }
101+ }
102+
103+ fn visit_place ( & mut self , place : & Place < ' tcx > , context : PlaceContext , location : Location ) {
104+ self . super_place ( place, context, location) ;
105+
106+ match context {
107+ PlaceContext :: NonMutatingUse ( _)
108+ | PlaceContext :: MutatingUse ( MutatingUseContext :: Borrow ) => {
109+ let path = match self . move_data . rev_lookup . find ( place. as_ref ( ) ) {
110+ LookupResult :: Exact ( path) | LookupResult :: Parent ( Some ( path) ) => path,
111+ _ => {
112+ // There's no path access to emit.
113+ return ;
114+ }
115+ } ;
116+ debug ! ( "AccessFactsExtractor - emit path access ({path:?}, {location:?})" ) ;
117+ self . path_accessed_at_base . push ( ( path, self . location_to_index ( location) ) ) ;
118+ }
119+
120+ _ => { }
121+ }
122+ }
123+ }
0 commit comments