Add MirPass to collect Unevaluated consts in MIR body
This commit is contained in:
parent
6807bb7482
commit
f8976e377f
3 changed files with 40 additions and 1 deletions
|
@ -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(),
|
||||
|
|
|
@ -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,
|
||||
|
|
23
src/librustc_mir/transform/uneval_const_set.rs
Normal file
23
src/librustc_mir/transform/uneval_const_set.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue