@@ -51,92 +51,102 @@ pub fn sanity_check_via_rustc_peek<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
5151
5252 let blocks = mir. all_basic_blocks ( ) ;
5353 ' next_block: for bb in blocks {
54- let bb_data = mir. basic_block_data ( bb) ;
55- let & repr:: BasicBlockData { ref statements,
56- ref terminator,
57- is_cleanup : _ } = bb_data;
58-
59- let ( args, span) = match is_rustc_peek ( tcx, terminator) {
60- Some ( args_and_span) => args_and_span,
61- None => continue ,
62- } ;
63- assert ! ( args. len( ) == 1 ) ;
64- let peek_arg_lval = match args[ 0 ] {
65- repr:: Operand :: Consume ( ref lval @ repr:: Lvalue :: Temp ( _) ) => {
66- lval
67- }
68- repr:: Operand :: Consume ( _) => {
69- bug ! ( "dataflow::sanity_check cannot feed a non-temp to rustc_peek." ) ;
70- }
71- repr:: Operand :: Constant ( _) => {
72- bug ! ( "dataflow::sanity_check cannot feed a constant to rustc_peek." ) ;
73- }
74- } ;
54+ each_block ( tcx, mir, flow_ctxt, results, bb) ;
55+ }
56+ }
7557
76- let mut entry = results. 0 . sets . on_entry_set_for ( bb. index ( ) ) . to_owned ( ) ;
77- let mut gen = results. 0 . sets . gen_set_for ( bb. index ( ) ) . to_owned ( ) ;
78- let mut kill = results. 0 . sets . kill_set_for ( bb. index ( ) ) . to_owned ( ) ;
58+ fn each_block < ' a , ' tcx , O > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
59+ mir : & Mir < ' tcx > ,
60+ flow_ctxt : & O :: Ctxt ,
61+ results : & DataflowResults < O > ,
62+ bb : repr:: BasicBlock ) where
63+ O : BitDenotation < Bit =MovePath < ' tcx > , Idx =MovePathIndex > , O :: Ctxt : HasMoveData < ' tcx >
64+ {
65+ let bb_data = mir. basic_block_data ( bb) ;
66+ let & repr:: BasicBlockData { ref statements,
67+ ref terminator,
68+ is_cleanup : _ } = bb_data;
69+
70+ let ( args, span) = match is_rustc_peek ( tcx, terminator) {
71+ Some ( args_and_span) => args_and_span,
72+ None => return ,
73+ } ;
74+ assert ! ( args. len( ) == 1 ) ;
75+ let peek_arg_lval = match args[ 0 ] {
76+ repr:: Operand :: Consume ( ref lval @ repr:: Lvalue :: Temp ( _) ) => {
77+ lval
78+ }
79+ repr:: Operand :: Consume ( _) |
80+ repr:: Operand :: Constant ( _) => {
81+ tcx. sess . diagnostic ( ) . span_err (
82+ span, "dataflow::sanity_check cannot feed a non-temp to rustc_peek." ) ;
83+ return ;
84+ }
85+ } ;
7986
80- let move_data = flow_ctxt. move_data ( ) ;
87+ let mut entry = results. 0 . sets . on_entry_set_for ( bb. index ( ) ) . to_owned ( ) ;
88+ let mut gen = results. 0 . sets . gen_set_for ( bb. index ( ) ) . to_owned ( ) ;
89+ let mut kill = results. 0 . sets . kill_set_for ( bb. index ( ) ) . to_owned ( ) ;
8190
82- // Emulate effect of all statements in the block up to (but
83- // not including) the borrow within `peek_arg_lval`. Do *not*
84- // include call to `peek_arg_lval` itself (since we are
85- // peeking the state of the argument at time immediate
86- // preceding Call to `rustc_peek`).
91+ let move_data = flow_ctxt. move_data ( ) ;
8792
88- let mut sets = super :: BlockSets { on_entry : & mut entry,
89- gen_set : & mut gen,
90- kill_set : & mut kill } ;
93+ // Emulate effect of all statements in the block up to (but not
94+ // including) the borrow within `peek_arg_lval`. Do *not* include
95+ // call to `peek_arg_lval` itself (since we are peeking the state
96+ // of the argument at time immediate preceding Call to
97+ // `rustc_peek`).
9198
92- for ( j, stmt) in statements. iter ( ) . enumerate ( ) {
93- debug ! ( "rustc_peek: ({:?},{}) {:?}" , bb, j, stmt) ;
94- let ( lvalue, rvalue) = match stmt. kind {
95- repr:: StatementKind :: Assign ( ref lvalue, ref rvalue) => {
96- ( lvalue, rvalue)
97- }
98- } ;
99-
100- if lvalue == peek_arg_lval {
101- if let repr:: Rvalue :: Ref ( _,
102- repr:: BorrowKind :: Shared ,
103- ref peeking_at_lval) = * rvalue {
104- // Okay, our search is over.
105- let peek_mpi = move_data. rev_lookup . find ( peeking_at_lval) ;
106- let bit_state = sets. on_entry . contains ( & peek_mpi) ;
107- debug ! ( "rustc_peek({:?} = &{:?}) bit_state: {}" ,
108- lvalue, peeking_at_lval, bit_state) ;
109- if !bit_state {
110- tcx. sess . span_err ( span, & format ! ( "rustc_peek: bit not set" ) ) ;
111- }
112- continue ' next_block;
113- } else {
114- // Our search should have been over, but the input
115- // does not match expectations of `rustc_peek` for
116- // this sanity_check.
117- tcx. sess . span_err ( span, & format ! ( "rustc_peek: argument expression \
118- must be immediate borrow of form `&expr`") ) ;
119- }
120- }
99+ let mut sets = super :: BlockSets { on_entry : & mut entry,
100+ gen_set : & mut gen,
101+ kill_set : & mut kill } ;
121102
122- let lhs_mpi = move_data. rev_lookup . find ( lvalue) ;
103+ for ( j, stmt) in statements. iter ( ) . enumerate ( ) {
104+ debug ! ( "rustc_peek: ({:?},{}) {:?}" , bb, j, stmt) ;
105+ let ( lvalue, rvalue) = match stmt. kind {
106+ repr:: StatementKind :: Assign ( ref lvalue, ref rvalue) => {
107+ ( lvalue, rvalue)
108+ }
109+ } ;
123110
124- debug ! ( "rustc_peek: computing effect on lvalue: {:?} ({:?}) in stmt: {:?}" ,
125- lvalue, lhs_mpi, stmt) ;
126- // reset GEN and KILL sets before emulating their effect.
127- for e in sets. gen_set . words_mut ( ) { * e = 0 ; }
128- for e in sets. kill_set . words_mut ( ) { * e = 0 ; }
129- results. 0 . operator . statement_effect ( flow_ctxt, & mut sets, bb, j) ;
130- sets. on_entry . union ( sets. gen_set ) ;
131- sets. on_entry . subtract ( sets. kill_set ) ;
111+ if lvalue == peek_arg_lval {
112+ if let repr:: Rvalue :: Ref ( _,
113+ repr:: BorrowKind :: Shared ,
114+ ref peeking_at_lval) = * rvalue {
115+ // Okay, our search is over.
116+ let peek_mpi = move_data. rev_lookup . find ( peeking_at_lval) ;
117+ let bit_state = sets. on_entry . contains ( & peek_mpi) ;
118+ debug ! ( "rustc_peek({:?} = &{:?}) bit_state: {}" ,
119+ lvalue, peeking_at_lval, bit_state) ;
120+ if !bit_state {
121+ tcx. sess . span_err ( span, & format ! ( "rustc_peek: bit not set" ) ) ;
122+ }
123+ return ;
124+ } else {
125+ // Our search should have been over, but the input
126+ // does not match expectations of `rustc_peek` for
127+ // this sanity_check.
128+ let msg = & format ! ( "rustc_peek: argument expression \
129+ must be immediate borrow of form `&expr`") ;
130+ tcx. sess . span_err ( span, msg) ;
131+ }
132132 }
133-
134- tcx. sess . span_err ( span, & format ! ( "rustc_peek: MIR did not match \
135- anticipated pattern; note that \
136- rustc_peek expects input of \
137- form `&expr`") ) ;
133+
134+ let lhs_mpi = move_data. rev_lookup . find ( lvalue) ;
135+
136+ debug ! ( "rustc_peek: computing effect on lvalue: {:?} ({:?}) in stmt: {:?}" ,
137+ lvalue, lhs_mpi, stmt) ;
138+ // reset GEN and KILL sets before emulating their effect.
139+ for e in sets. gen_set . words_mut ( ) { * e = 0 ; }
140+ for e in sets. kill_set . words_mut ( ) { * e = 0 ; }
141+ results. 0 . operator . statement_effect ( flow_ctxt, & mut sets, bb, j) ;
142+ sets. on_entry . union ( sets. gen_set ) ;
143+ sets. on_entry . subtract ( sets. kill_set ) ;
138144 }
139145
146+ tcx. sess . span_err ( span, & format ! ( "rustc_peek: MIR did not match \
147+ anticipated pattern; note that \
148+ rustc_peek expects input of \
149+ form `&expr`") ) ;
140150}
141151
142152fn is_rustc_peek < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
0 commit comments