Skip to content

Commit

Permalink
Add MirPass to collect Unevaluated consts in MIR body
Browse files Browse the repository at this point in the history
  • Loading branch information
spastorino committed Apr 23, 2020
1 parent 6807bb7 commit f8976e3
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/librustc_middle/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -203,6 +206,7 @@ impl<'tcx> Body<'tcx> {
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(),
Expand All @@ -227,6 +231,7 @@ impl<'tcx> Body<'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(),
Expand Down
13 changes: 12 additions & 1 deletion src/librustc_mir/transform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use rustc_hir as hir;
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};
Expand Down Expand Up @@ -33,6 +34,7 @@ pub mod rustc_peek;
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;

Expand Down Expand Up @@ -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,
Expand Down
23 changes: 23 additions & 0 deletions src/librustc_mir/transform/uneval_const_set.rs
Original file line number Diff line number Diff line change
@@ -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);
}
}
}

0 comments on commit f8976e3

Please sign in to comment.