Skip to content

Commit a99f255

Browse files
committed
Allow reading non-mutable statics in const prop
1 parent dcc6c28 commit a99f255

File tree

5 files changed

+45
-11
lines changed

5 files changed

+45
-11
lines changed

src/librustc_mir/interpret/machine.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,9 @@ pub trait Machine<'mir, 'tcx>: Sized {
194194
frame.locals[local].access()
195195
}
196196

197-
/// Called before a `StaticKind::Static` value is read.
198-
fn before_eval_static(
199-
_ecx: &InterpCx<'mir, 'tcx, Self>,
200-
_place_static: &mir::Static<'tcx>,
197+
/// Called before a `StaticKind::Static` value is accessed.
198+
fn before_access_static(
199+
_allocation: &Allocation,
201200
) -> InterpResult<'tcx> {
202201
Ok(())
203202
}

src/librustc_mir/interpret/memory.rs

+2
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
462462
// Make sure we use the ID of the resolved memory, not the lazy one!
463463
let id = raw_const.alloc_id;
464464
let allocation = tcx.alloc_map.lock().unwrap_memory(id);
465+
466+
M::before_access_static(allocation)?;
465467
Cow::Borrowed(allocation)
466468
}
467469
}

src/librustc_mir/interpret/place.rs

-2
Original file line numberDiff line numberDiff line change
@@ -601,8 +601,6 @@ where
601601
}
602602

603603
StaticKind::Static => {
604-
M::before_eval_static(self, place_static)?;
605-
606604
let ty = place_static.ty;
607605
assert!(!ty.needs_subst());
608606
let layout = self.layout_of(ty)?;

src/librustc_mir/transform/const_prop.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc::hir::def::DefKind;
88
use rustc::hir::def_id::DefId;
99
use rustc::mir::{
1010
AggregateKind, Constant, Location, Place, PlaceBase, Body, Operand, Rvalue,
11-
Local, NullOp, UnOp, StatementKind, Statement, LocalKind, Static,
11+
Local, NullOp, UnOp, StatementKind, Statement, LocalKind,
1212
TerminatorKind, Terminator, ClearCrossCrate, SourceInfo, BinOp,
1313
SourceScope, SourceScopeLocalData, LocalDecl, BasicBlock,
1414
};
@@ -17,6 +17,7 @@ use rustc::mir::visit::{
1717
};
1818
use rustc::mir::interpret::{Scalar, InterpResult, PanicInfo};
1919
use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt};
20+
use syntax::ast::Mutability;
2021
use syntax_pos::{Span, DUMMY_SP};
2122
use rustc::ty::subst::InternalSubsts;
2223
use rustc_data_structures::fx::FxHashMap;
@@ -229,11 +230,16 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
229230
l.access()
230231
}
231232

232-
fn before_eval_static(
233-
_ecx: &InterpCx<'mir, 'tcx, Self>,
234-
_place_static: &Static<'tcx>,
233+
fn before_access_static(
234+
allocation: &Allocation<Self::PointerTag, Self::AllocExtra>,
235235
) -> InterpResult<'tcx> {
236-
throw_unsup_format!("can't eval statics in ConstProp");
236+
// if the static allocation is mutable or if it has relocations (it may be legal to mutate
237+
// the memory behind that in the future), then we can't const prop it
238+
if allocation.mutability == Mutability::Mutable || allocation.relocations().len() > 0 {
239+
throw_unsup_format!("can't eval mutable statics in ConstProp");
240+
}
241+
242+
Ok(())
237243
}
238244

239245
fn before_terminator(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// compile-flags: -O
2+
3+
static FOO: u8 = 2;
4+
5+
fn main() {
6+
let x = FOO + FOO;
7+
}
8+
9+
// END RUST SOURCE
10+
// START rustc.main.ConstProp.before.mir
11+
// bb0: {
12+
// ...
13+
// _2 = (FOO: u8);
14+
// ...
15+
// _3 = (FOO: u8);
16+
// _1 = Add(move _2, move _3);
17+
// ...
18+
// }
19+
// END rustc.main.ConstProp.before.mir
20+
// START rustc.main.ConstProp.after.mir
21+
// bb0: {
22+
// ...
23+
// _2 = const 2u8;
24+
// ...
25+
// _3 = const 2u8;
26+
// _1 = Add(move _2, move _3);
27+
// ...
28+
// }
29+
// END rustc.main.ConstProp.after.mir

0 commit comments

Comments
 (0)