1
Fork 0

Add MirPass to collect Unevaluated consts in MIR body

This commit is contained in:
Santiago Pastorino 2020-04-03 18:26:24 -03:00
parent 6807bb7482
commit f8976e377f
No known key found for this signature in database
GPG key ID: 8131A24E0C79EFAF
3 changed files with 40 additions and 1 deletions

View 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 @@ 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(),
@ -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(),

View file

@ -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};
@ -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;
@ -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,

View file

@ -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);
}
}
}