88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11- use syntax:: ast;
11+ use syntax:: ast:: { self , MetaItem } ;
1212
1313use rustc_data_structures:: indexed_set:: { IdxSet , IdxSetBuf } ;
1414use rustc_data_structures:: indexed_vec:: Idx ;
1515use rustc_data_structures:: bitslice:: { bitwise, BitwiseOperator } ;
1616
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 ;
1920
20- use std:: fmt:: Debug ;
21+ use std:: fmt:: { self , Debug } ;
2122use std:: io;
2223use std:: mem;
2324use std:: path:: PathBuf ;
@@ -28,6 +29,9 @@ pub use self::impls::{DefinitelyInitializedLvals, MovingOutStatements};
2829pub use self :: impls:: borrows:: { Borrows , BorrowData , BorrowIndex } ;
2930pub ( crate ) use self :: drop_flag_effects:: * ;
3031
32+ use self :: move_paths:: MoveData ;
33+ use self :: indexes:: MovePathIndex ;
34+
3135mod drop_flag_effects;
3236mod graphviz;
3337mod impls;
@@ -58,6 +62,67 @@ impl<'a, 'tcx: 'a, BD> Dataflow<BD> for DataflowBuilder<'a, 'tcx, BD>
5862 }
5963}
6064
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+
61126struct PropagationContext < ' b , ' a : ' b , ' tcx : ' a , O >
62127 where O : ' b + BitDenotation
63128{
0 commit comments