8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- use syntax:: ast;
11
+ use syntax:: ast:: { self , MetaItem } ;
12
12
13
13
use rustc_data_structures:: indexed_set:: { IdxSet , IdxSetBuf } ;
14
14
use rustc_data_structures:: indexed_vec:: Idx ;
15
15
use rustc_data_structures:: bitslice:: { bitwise, BitwiseOperator } ;
16
16
17
- use rustc:: ty:: { TyCtxt } ;
18
- use rustc:: mir:: { self , Mir , Location } ;
17
+ use rustc:: ty:: { self , TyCtxt } ;
18
+ use rustc:: mir:: { self , Mir , BasicBlock , Location } ;
19
+ use rustc:: session:: Session ;
19
20
20
- use std:: fmt:: Debug ;
21
+ use std:: fmt:: { self , Debug } ;
21
22
use std:: io;
22
23
use std:: mem;
23
24
use std:: path:: PathBuf ;
@@ -28,6 +29,9 @@ pub use self::impls::{DefinitelyInitializedLvals, MovingOutStatements};
28
29
pub use self :: impls:: borrows:: { Borrows , BorrowData , BorrowIndex } ;
29
30
pub ( crate ) use self :: drop_flag_effects:: * ;
30
31
32
+ use self :: move_paths:: MoveData ;
33
+ use self :: indexes:: MovePathIndex ;
34
+
31
35
mod drop_flag_effects;
32
36
mod graphviz;
33
37
mod impls;
@@ -58,6 +62,67 @@ impl<'a, 'tcx: 'a, BD> Dataflow<BD> for DataflowBuilder<'a, 'tcx, BD>
58
62
}
59
63
}
60
64
65
+ pub ( crate ) fn has_rustc_mir_with ( attrs : & [ ast:: Attribute ] , name : & str ) -> Option < MetaItem > {
66
+ for attr in attrs {
67
+ if attr. check_name ( "rustc_mir" ) {
68
+ let items = attr. meta_item_list ( ) ;
69
+ for item in items. iter ( ) . flat_map ( |l| l. iter ( ) ) {
70
+ match item. meta_item ( ) {
71
+ Some ( mi) if mi. check_name ( name) => return Some ( mi. clone ( ) ) ,
72
+ _ => continue
73
+ }
74
+ }
75
+ }
76
+ }
77
+ return None ;
78
+ }
79
+
80
+ pub struct MoveDataParamEnv < ' tcx > {
81
+ pub ( crate ) move_data : MoveData < ' tcx > ,
82
+ pub ( crate ) param_env : ty:: ParamEnv < ' tcx > ,
83
+ }
84
+
85
+ pub ( crate ) fn do_dataflow < ' a , ' tcx , BD , P > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
86
+ mir : & Mir < ' tcx > ,
87
+ node_id : ast:: NodeId ,
88
+ attributes : & [ ast:: Attribute ] ,
89
+ dead_unwinds : & IdxSet < BasicBlock > ,
90
+ bd : BD ,
91
+ p : P )
92
+ -> DataflowResults < BD >
93
+ where BD : BitDenotation < Idx =MovePathIndex > + DataflowOperator ,
94
+ P : Fn ( & BD , BD :: Idx ) -> & fmt:: Debug
95
+ {
96
+ let name_found = |sess : & Session , attrs : & [ ast:: Attribute ] , name| -> Option < String > {
97
+ if let Some ( item) = has_rustc_mir_with ( attrs, name) {
98
+ if let Some ( s) = item. value_str ( ) {
99
+ return Some ( s. to_string ( ) )
100
+ } else {
101
+ sess. span_err (
102
+ item. span ,
103
+ & format ! ( "{} attribute requires a path" , item. name( ) ) ) ;
104
+ return None ;
105
+ }
106
+ }
107
+ return None ;
108
+ } ;
109
+
110
+ let print_preflow_to =
111
+ name_found ( tcx. sess , attributes, "borrowck_graphviz_preflow" ) ;
112
+ let print_postflow_to =
113
+ name_found ( tcx. sess , attributes, "borrowck_graphviz_postflow" ) ;
114
+
115
+ let mut mbcx = DataflowBuilder {
116
+ node_id,
117
+ print_preflow_to,
118
+ print_postflow_to,
119
+ flow_state : DataflowAnalysis :: new ( tcx, mir, dead_unwinds, bd) ,
120
+ } ;
121
+
122
+ mbcx. dataflow ( p) ;
123
+ mbcx. flow_state . results ( )
124
+ }
125
+
61
126
struct PropagationContext < ' b , ' a : ' b , ' tcx : ' a , O >
62
127
where O : ' b + BitDenotation
63
128
{
0 commit comments