Skip to content

Commit f8976e3

Browse files
committed
Add MirPass to collect Unevaluated consts in MIR body
1 parent 6807bb7 commit f8976e3

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

src/librustc_middle/mir/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ pub struct Body<'tcx> {
156156
/// A span representing this MIR, for error reporting.
157157
pub span: Span,
158158

159+
/// Unevaluated consts to evaluate them regardless of being optimized out
160+
pub uneval_consts: Vec<Constant<'tcx>>,
161+
159162
/// The user may be writing e.g. &[(SOME_CELL, 42)][i].1 and this would get promoted, because
160163
/// we'd statically know that no thing with interior mutability will ever be available to the
161164
/// user without some serious unsafe code. Now this means that our promoted is actually
@@ -203,6 +206,7 @@ impl<'tcx> Body<'tcx> {
203206
spread_arg: None,
204207
var_debug_info,
205208
span,
209+
uneval_consts: Vec::new(),
206210
ignore_interior_mut_in_const_validation: false,
207211
control_flow_destroyed,
208212
predecessor_cache: PredecessorCache::new(),
@@ -227,6 +231,7 @@ impl<'tcx> Body<'tcx> {
227231
arg_count: 0,
228232
spread_arg: None,
229233
span: DUMMY_SP,
234+
uneval_consts: Vec::new(),
230235
control_flow_destroyed: Vec::new(),
231236
generator_kind: None,
232237
var_debug_info: Vec::new(),

src/librustc_mir/transform/mod.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ use rustc_hir as hir;
44
use rustc_hir::def_id::{CrateNum, DefId, DefIdSet, LocalDefId, LOCAL_CRATE};
55
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
66
use rustc_index::vec::IndexVec;
7-
use rustc_middle::mir::{Body, ConstQualifs, MirPhase, Promoted};
7+
use rustc_middle::mir::visit::Visitor as _;
8+
use rustc_middle::mir::{traversal, Body, ConstQualifs, MirPhase, Promoted};
89
use rustc_middle::ty::query::Providers;
910
use rustc_middle::ty::steal::Steal;
1011
use rustc_middle::ty::{InstanceDef, TyCtxt, TypeFoldable};
@@ -33,6 +34,7 @@ pub mod rustc_peek;
3334
pub mod simplify;
3435
pub mod simplify_branches;
3536
pub mod simplify_try;
37+
pub mod uneval_const_set;
3638
pub mod uninhabited_enum_branching;
3739
pub mod unreachable_prop;
3840

@@ -237,6 +239,15 @@ fn mir_validated(
237239
let _ = tcx.mir_const_qualif(def_id);
238240

239241
let mut body = tcx.mir_const(def_id).steal();
242+
243+
let mut uneval_consts = Vec::new();
244+
let mut uneval_const_visitor =
245+
self::uneval_const_set::UnevalConstSetVisitor::new(&mut uneval_consts);
246+
for (bb, bb_data) in traversal::reverse_postorder(&body) {
247+
uneval_const_visitor.visit_basic_block_data(bb, bb_data);
248+
}
249+
body.uneval_consts = uneval_consts;
250+
240251
let promote_pass = promote_consts::PromoteTemps::default();
241252
run_passes(
242253
tcx,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use rustc_middle::mir::visit::Visitor;
2+
use rustc_middle::mir::{Constant, Location};
3+
use rustc_middle::ty::ConstKind;
4+
5+
pub struct UnevalConstSetVisitor<'a, 'tcx> {
6+
uneval_consts: &'a mut Vec<Constant<'tcx>>,
7+
}
8+
9+
impl<'a, 'tcx> UnevalConstSetVisitor<'a, 'tcx> {
10+
pub fn new(uneval_consts: &'a mut Vec<Constant<'tcx>>) -> Self {
11+
UnevalConstSetVisitor { uneval_consts }
12+
}
13+
}
14+
15+
impl<'a, 'tcx> Visitor<'tcx> for UnevalConstSetVisitor<'a, 'tcx> {
16+
fn visit_constant(&mut self, constant: &Constant<'tcx>, _: Location) {
17+
let const_kind = constant.literal.val;
18+
19+
if let ConstKind::Unevaluated(_, _, _) = const_kind {
20+
self.uneval_consts.push(*constant);
21+
}
22+
}
23+
}

0 commit comments

Comments
 (0)