]> git.lizzy.rs Git - rust.git/commitdiff
Add MirPass to collect Unevaluated consts in MIR body
authorSantiago Pastorino <spastorino@gmail.com>
Fri, 3 Apr 2020 21:26:24 +0000 (18:26 -0300)
committerSantiago Pastorino <spastorino@gmail.com>
Thu, 23 Apr 2020 19:50:17 +0000 (16:50 -0300)
src/librustc_middle/mir/mod.rs
src/librustc_mir/transform/mod.rs
src/librustc_mir/transform/uneval_const_set.rs [new file with mode: 0644]

index 489a47b5411f59f620a5ead7168a9f4ea443936c..5ab4689d2acb7540b7ab253416ea4afe42539717 100644 (file)
@@ -156,6 +156,9 @@ pub struct Body<'tcx> {
     /// A span representing this MIR, for error reporting.
     pub span: Span,
 
+    /// Unevaluated consts to evaluate them regardless of being optimized out
+    pub uneval_consts: Vec<Constant<'tcx>>,
+
     /// The user may be writing e.g. &[(SOME_CELL, 42)][i].1 and this would get promoted, because
     /// we'd statically know that no thing with interior mutability will ever be available to the
     /// user without some serious unsafe code.  Now this means that our promoted is actually
@@ -203,6 +206,7 @@ pub fn new(
             spread_arg: None,
             var_debug_info,
             span,
+            uneval_consts: Vec::new(),
             ignore_interior_mut_in_const_validation: false,
             control_flow_destroyed,
             predecessor_cache: PredecessorCache::new(),
@@ -227,6 +231,7 @@ pub fn new_cfg_only(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>) ->
             arg_count: 0,
             spread_arg: None,
             span: DUMMY_SP,
+            uneval_consts: Vec::new(),
             control_flow_destroyed: Vec::new(),
             generator_kind: None,
             var_debug_info: Vec::new(),
index a87955274a779c790fad76c083ff0dfcc0aaf49d..4735be29f6893be234cb3f16a33c8e7bc554cf7e 100644 (file)
@@ -4,7 +4,8 @@
 use rustc_hir::def_id::{CrateNum, DefId, DefIdSet, LocalDefId, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_index::vec::IndexVec;
-use rustc_middle::mir::{Body, ConstQualifs, MirPhase, Promoted};
+use rustc_middle::mir::visit::Visitor as _;
+use rustc_middle::mir::{traversal, Body, ConstQualifs, MirPhase, Promoted};
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::steal::Steal;
 use rustc_middle::ty::{InstanceDef, TyCtxt, TypeFoldable};
@@ -33,6 +34,7 @@
 pub mod simplify;
 pub mod simplify_branches;
 pub mod simplify_try;
+pub mod uneval_const_set;
 pub mod uninhabited_enum_branching;
 pub mod unreachable_prop;
 
@@ -237,6 +239,15 @@ fn mir_validated(
     let _ = tcx.mir_const_qualif(def_id);
 
     let mut body = tcx.mir_const(def_id).steal();
+
+    let mut uneval_consts = Vec::new();
+    let mut uneval_const_visitor =
+        self::uneval_const_set::UnevalConstSetVisitor::new(&mut uneval_consts);
+    for (bb, bb_data) in traversal::reverse_postorder(&body) {
+        uneval_const_visitor.visit_basic_block_data(bb, bb_data);
+    }
+    body.uneval_consts = uneval_consts;
+
     let promote_pass = promote_consts::PromoteTemps::default();
     run_passes(
         tcx,
diff --git a/src/librustc_mir/transform/uneval_const_set.rs b/src/librustc_mir/transform/uneval_const_set.rs
new file mode 100644 (file)
index 0000000..98190f0
--- /dev/null
@@ -0,0 +1,23 @@
+use rustc_middle::mir::visit::Visitor;
+use rustc_middle::mir::{Constant, Location};
+use rustc_middle::ty::ConstKind;
+
+pub struct UnevalConstSetVisitor<'a, 'tcx> {
+    uneval_consts: &'a mut Vec<Constant<'tcx>>,
+}
+
+impl<'a, 'tcx> UnevalConstSetVisitor<'a, 'tcx> {
+    pub fn new(uneval_consts: &'a mut Vec<Constant<'tcx>>) -> Self {
+        UnevalConstSetVisitor { uneval_consts }
+    }
+}
+
+impl<'a, 'tcx> Visitor<'tcx> for UnevalConstSetVisitor<'a, 'tcx> {
+    fn visit_constant(&mut self, constant: &Constant<'tcx>, _: Location) {
+        let const_kind = constant.literal.val;
+
+        if let ConstKind::Unevaluated(_, _, _) = const_kind {
+            self.uneval_consts.push(*constant);
+        }
+    }
+}