diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 1cfe5219997b1..7fa818ba7d3ae 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -3,6 +3,7 @@ mod init_mask; mod provenance_map; +use std::alloc::{self, Layout}; use std::borrow::Cow; use std::hash::Hash; use std::ops::{Deref, DerefMut, Range}; @@ -434,7 +435,7 @@ impl Allocation { // available to the compiler can change between runs. Normally queries are always // deterministic. However, we can be non-deterministic here because all uses of const // evaluation (including ConstProp!) will make compilation fail (via hard error - // or ICE) upon encountering a `MemoryExhausted` error. + // or OOM) upon encountering a `MemoryExhausted` error. let bytes = Bytes::zeroed(size, align, params).ok_or_else(fail)?; Ok(Allocation { @@ -468,7 +469,7 @@ impl Allocation { .into() } - /// Try to create an Allocation of `size` bytes, panics if there is not enough memory + /// Try to create an Allocation of `size` bytes. Aborts if there is not enough memory /// available to the compiler to do so. /// /// Example use case: To obtain an Allocation filled with specific data, @@ -480,10 +481,15 @@ impl Allocation { params: ::AllocParams, ) -> Self { match Self::new_inner(size, align, init, params, || { - panic!( - "interpreter ran out of memory: cannot create allocation of {} bytes", - size.bytes() - ); + // `size` may actually be bigger than isize::MAX since it is a *target* size. + // Clamp it to isize::MAX to still give a somewhat reasonable error message. + alloc::handle_alloc_error( + Layout::from_size_align( + size.bytes().min(isize::MAX as u64) as usize, + align.bytes_usize(), + ) + .unwrap(), + ) }) { Ok(x) => x, Err(x) => x,