Skip to content

Commit e9d69d9

Browse files
committed
Allocation failure in constprop panics right away
1 parent 3e20129 commit e9d69d9

File tree

6 files changed

+12
-3
lines changed

6 files changed

+12
-3
lines changed

compiler/rustc_middle/src/mir/interpret/allocation.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,17 @@ impl<Tag> Allocation<Tag> {
126126

127127
/// Try to create an Allocation of `size` bytes, failing if there is not enough memory
128128
/// available to the compiler to do so.
129-
pub fn uninit(size: Size, align: Align) -> InterpResult<'static, Self> {
129+
pub fn uninit(size: Size, align: Align, panic_on_fail: bool) -> InterpResult<'static, Self> {
130130
let mut bytes = Vec::new();
131131
bytes.try_reserve(size.bytes_usize()).map_err(|_| {
132132
// This results in an error that can happen non-deterministically, since the memory
133133
// available to the compiler can change between runs. Normally queries are always
134134
// deterministic. However, we can be non-determinstic here because all uses of const
135135
// evaluation (including ConstProp!) will make compilation fail (via hard error
136136
// or ICE) upon encountering a `MemoryExhausted` error.
137+
if panic_on_fail {
138+
panic!("Allocation::uninit called with panic_on_fail had allocation failure")
139+
}
137140
ty::tls::with(|tcx| {
138141
tcx.sess.delay_span_bug(DUMMY_SP, "exhausted memory during interpreation")
139142
});

compiler/rustc_middle/src/ty/vtable.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ impl<'tcx> TyCtxt<'tcx> {
6060
let ptr_align = tcx.data_layout.pointer_align.abi;
6161

6262
let vtable_size = ptr_size * u64::try_from(vtable_entries.len()).unwrap();
63-
let mut vtable = Allocation::uninit(vtable_size, ptr_align)?;
63+
let mut vtable = Allocation::uninit(vtable_size, ptr_align, true)?;
6464

6565
// No need to do any alignment checks on the memory accesses below, because we know the
6666
// allocation is correctly aligned as we created it above. Also we're only offsetting by

compiler/rustc_mir/src/const_eval/machine.rs

+2
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
201201

202202
type MemoryExtra = MemoryExtra;
203203

204+
const PANIC_ON_ALLOC_FAIL: bool = false; // will be raised as a proper error
205+
204206
fn load_mir(
205207
ecx: &InterpCx<'mir, 'tcx, Self>,
206208
instance: ty::InstanceDef<'tcx>,

compiler/rustc_mir/src/interpret/machine.rs

+3
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ pub trait Machine<'mir, 'tcx>: Sized {
122122
/// that is added to the memory so that the work is not done twice.
123123
const GLOBAL_KIND: Option<Self::MemoryKind>;
124124

125+
/// Should the machine panic on allocation failures?
126+
const PANIC_ON_ALLOC_FAIL: bool;
127+
125128
/// Whether memory accesses should be alignment-checked.
126129
fn enforce_alignment(memory_extra: &Self::MemoryExtra) -> bool;
127130

compiler/rustc_mir/src/interpret/memory.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
208208
align: Align,
209209
kind: MemoryKind<M::MemoryKind>,
210210
) -> InterpResult<'static, Pointer<M::PointerTag>> {
211-
let alloc = Allocation::uninit(size, align)?;
211+
let alloc = Allocation::uninit(size, align, M::PANIC_ON_ALLOC_FAIL)?;
212212
Ok(self.allocate_with(alloc, kind))
213213
}
214214

compiler/rustc_mir/src/transform/const_prop.rs

+1
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ impl<'mir, 'tcx> ConstPropMachine<'mir, 'tcx> {
181181

182182
impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> {
183183
compile_time_machine!(<'mir, 'tcx>);
184+
const PANIC_ON_ALLOC_FAIL: bool = true; // all allocations are small
184185

185186
type MemoryKind = !;
186187

0 commit comments

Comments
 (0)