about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan MacKenzie <ecstaticmorse@gmail.com>2019-10-01 20:14:01 -0700
committerDylan MacKenzie <ecstaticmorse@gmail.com>2019-10-01 20:29:57 -0700
commit767550ef0fc0a01abd8dc50fead0967d215eca41 (patch)
treea2256d252c5e0d80c216b59b435481f2cfb8842f
parentf18535fa46752ac33ceaebe71386cf77a6df8f9a (diff)
downloadrust-767550ef0fc0a01abd8dc50fead0967d215eca41.tar.gz
rust-767550ef0fc0a01abd8dc50fead0967d215eca41.zip
Add `rustc_peek` support for `IndirectlyMutableLocals`
-rw-r--r--src/librustc_mir/transform/rustc_peek.rs32
-rw-r--r--src/libsyntax_pos/symbol.rs1
2 files changed, 33 insertions, 0 deletions
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index d0ffcbbae88..6edd28a4259 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -17,6 +17,7 @@ use crate::dataflow::DataflowResultsCursor;
 use crate::dataflow::{
     DefinitelyInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces
 };
+use crate::dataflow::IndirectlyMutableLocals;
 use crate::dataflow::move_paths::{MovePathIndex, LookupResult};
 use crate::dataflow::move_paths::{HasMoveData, MoveData};
 
@@ -51,6 +52,10 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
             do_dataflow(tcx, body, def_id, &attributes, &dead_unwinds,
                         DefinitelyInitializedPlaces::new(tcx, body, &mdpe),
                         |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
+        let flow_indirectly_mut =
+            do_dataflow(tcx, body, def_id, &attributes, &dead_unwinds,
+                        IndirectlyMutableLocals::new(tcx, body, param_env),
+                        |_, i| DebugFormatted::new(&i));
 
         if has_rustc_mir_with(&attributes, sym::rustc_peek_maybe_init).is_some() {
             sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_inits);
@@ -61,6 +66,9 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
         if has_rustc_mir_with(&attributes, sym::rustc_peek_definite_init).is_some() {
             sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_def_inits);
         }
+        if has_rustc_mir_with(&attributes, sym::rustc_peek_indirectly_mutable).is_some() {
+            sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_indirectly_mut);
+        }
         if has_rustc_mir_with(&attributes, sym::stop_after_dataflow).is_some() {
             tcx.sess.fatal("stop_after_dataflow ended compilation");
         }
@@ -252,9 +260,33 @@ impl<'tcx, O> RustcPeekAt<'tcx> for O
                     tcx.sess.span_err(call.span, "rustc_peek: bit not set");
                 }
             }
+
             LookupResult::Parent(..) => {
                 tcx.sess.span_err(call.span, "rustc_peek: argument untracked");
             }
         }
     }
 }
+
+impl<'tcx> RustcPeekAt<'tcx> for IndirectlyMutableLocals<'_, 'tcx> {
+    fn peek_at(
+        &self,
+        tcx: TyCtxt<'tcx>,
+        place: &mir::Place<'tcx>,
+        flow_state: &BitSet<Local>,
+        call: PeekCall,
+    ) {
+        warn!("peek_at: place={:?}", place);
+        let local = match place {
+            mir::Place { base: mir::PlaceBase::Local(l), projection: box [] } => *l,
+            _ => {
+                tcx.sess.span_err(call.span, "rustc_peek: argument was not a local");
+                return;
+            }
+        };
+
+        if !flow_state.contains(local) {
+            tcx.sess.span_err(call.span, "rustc_peek: bit not set");
+        }
+    }
+}
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 1769135e7f2..82c47e6dbb7 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -597,6 +597,7 @@ symbols! {
         rustc_peek_definite_init,
         rustc_peek_maybe_init,
         rustc_peek_maybe_uninit,
+        rustc_peek_indirectly_mutable,
         rustc_private,
         rustc_proc_macro_decls,
         rustc_promotable,