Skip to content

Support allocation failures when interpreting MIR #86255

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Jul 4, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion compiler/rustc_middle/src/mir/interpret/allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,17 @@ impl<Tag> Allocation<Tag> {

/// Try to create an Allocation of `size` bytes, failing if there is not enough memory
/// available to the compiler to do so.
pub fn uninit(size: Size, align: Align) -> InterpResult<'static, Self> {
pub fn uninit(size: Size, align: Align, panic_on_fail: bool) -> InterpResult<'static, Self> {
let mut bytes = Vec::new();
bytes.try_reserve(size.bytes_usize()).map_err(|_| {
// This results in an error that can happen non-deterministically, since the memory
// available to the compiler can change between runs. Normally queries are always
// deterministic. However, we can be non-determinstic here because all uses of const
// evaluation (including ConstProp!) will make compilation fail (via hard error
// or ICE) upon encountering a `MemoryExhausted` error.
if panic_on_fail {
panic!("Allocation::uninit called with panic_on_fail had allocation failure")
}
ty::tls::with(|tcx| {
tcx.sess.delay_span_bug(DUMMY_SP, "exhausted memory during interpreation")
});
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/vtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl<'tcx> TyCtxt<'tcx> {
let ptr_align = tcx.data_layout.pointer_align.abi;

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

// No need to do any alignment checks on the memory accesses below, because we know the
// allocation is correctly aligned as we created it above. Also we're only offsetting by
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_mir/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,

type MemoryExtra = MemoryExtra;

const PANIC_ON_ALLOC_FAIL: bool = false; // will be raised as a proper error

fn load_mir(
ecx: &InterpCx<'mir, 'tcx, Self>,
instance: ty::InstanceDef<'tcx>,
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_mir/src/interpret/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ pub trait Machine<'mir, 'tcx>: Sized {
/// that is added to the memory so that the work is not done twice.
const GLOBAL_KIND: Option<Self::MemoryKind>;

/// Should the machine panic on allocation failures?
const PANIC_ON_ALLOC_FAIL: bool;

/// Whether memory accesses should be alignment-checked.
fn enforce_alignment(memory_extra: &Self::MemoryExtra) -> bool;

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
align: Align,
kind: MemoryKind<M::MemoryKind>,
) -> InterpResult<'static, Pointer<M::PointerTag>> {
let alloc = Allocation::uninit(size, align)?;
let alloc = Allocation::uninit(size, align, M::PANIC_ON_ALLOC_FAIL)?;
Ok(self.allocate_with(alloc, kind))
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir/src/transform/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ impl<'mir, 'tcx> ConstPropMachine<'mir, 'tcx> {

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

type MemoryKind = !;

Expand Down