/// 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
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(),
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(),
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};
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;
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,
--- /dev/null
+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);
+ }
+ }
+}