@@ -17,6 +17,7 @@ use crate::dataflow::DataflowResultsCursor;
1717use crate :: dataflow:: {
1818 DefinitelyInitializedPlaces , MaybeInitializedPlaces , MaybeUninitializedPlaces
1919} ;
20+ use crate :: dataflow:: IndirectlyMutableLocals ;
2021use crate :: dataflow:: move_paths:: { MovePathIndex , LookupResult } ;
2122use crate :: dataflow:: move_paths:: { HasMoveData , MoveData } ;
2223
@@ -51,6 +52,10 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
5152 do_dataflow ( tcx, body, def_id, & attributes, & dead_unwinds,
5253 DefinitelyInitializedPlaces :: new ( tcx, body, & mdpe) ,
5354 |bd, i| DebugFormatted :: new ( & bd. move_data ( ) . move_paths [ i] ) ) ;
55+ let flow_indirectly_mut =
56+ do_dataflow ( tcx, body, def_id, & attributes, & dead_unwinds,
57+ IndirectlyMutableLocals :: new ( tcx, body, param_env) ,
58+ |_, i| DebugFormatted :: new ( & i) ) ;
5459
5560 if has_rustc_mir_with ( & attributes, sym:: rustc_peek_maybe_init) . is_some ( ) {
5661 sanity_check_via_rustc_peek ( tcx, body, def_id, & attributes, & flow_inits) ;
@@ -61,6 +66,9 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
6166 if has_rustc_mir_with ( & attributes, sym:: rustc_peek_definite_init) . is_some ( ) {
6267 sanity_check_via_rustc_peek ( tcx, body, def_id, & attributes, & flow_def_inits) ;
6368 }
69+ if has_rustc_mir_with ( & attributes, sym:: rustc_peek_indirectly_mutable) . is_some ( ) {
70+ sanity_check_via_rustc_peek ( tcx, body, def_id, & attributes, & flow_indirectly_mut) ;
71+ }
6472 if has_rustc_mir_with ( & attributes, sym:: stop_after_dataflow) . is_some ( ) {
6573 tcx. sess . fatal ( "stop_after_dataflow ended compilation" ) ;
6674 }
@@ -252,9 +260,33 @@ impl<'tcx, O> RustcPeekAt<'tcx> for O
252260 tcx. sess . span_err ( call. span , "rustc_peek: bit not set" ) ;
253261 }
254262 }
263+
255264 LookupResult :: Parent ( ..) => {
256265 tcx. sess . span_err ( call. span , "rustc_peek: argument untracked" ) ;
257266 }
258267 }
259268 }
260269}
270+
271+ impl < ' tcx > RustcPeekAt < ' tcx > for IndirectlyMutableLocals < ' _ , ' tcx > {
272+ fn peek_at (
273+ & self ,
274+ tcx : TyCtxt < ' tcx > ,
275+ place : & mir:: Place < ' tcx > ,
276+ flow_state : & BitSet < Local > ,
277+ call : PeekCall ,
278+ ) {
279+ warn ! ( "peek_at: place={:?}" , place) ;
280+ let local = match place {
281+ mir:: Place { base : mir:: PlaceBase :: Local ( l) , projection : box [ ] } => * l,
282+ _ => {
283+ tcx. sess . span_err ( call. span , "rustc_peek: argument was not a local" ) ;
284+ return ;
285+ }
286+ } ;
287+
288+ if !flow_state. contains ( local) {
289+ tcx. sess . span_err ( call. span , "rustc_peek: bit not set" ) ;
290+ }
291+ }
292+ }
0 commit comments