Skip to content

Commit d04da11

Browse files
committed
Properly handle const prop failures
1 parent c94bafb commit d04da11

File tree

4 files changed

+28
-6
lines changed

4 files changed

+28
-6
lines changed

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,14 @@ impl<Tag> Allocation<Tag> {
131131
// available to the compiler can change between runs. Normally queries are always
132132
// deterministic. However, we can be non-determinstic here because all uses of const
133133
// evaluation do one of:
134-
// - cause a fatal compiler error when they see this error as the result of const
135-
// evaluation
136-
// - panic on evaluation failure
137-
// - always evaluate very small constants that are practically unlikely to result in
138-
// memory exhaustion
134+
// - error on failure
135+
// - used for static initalizer evalution
136+
// - used for const value evaluation
137+
// - const prop errors on this since otherwise it would generate different code based
138+
// on available memory
139+
// - panic on failure to allocate very small sizes
140+
// - actually panicking won't happen since there wouldn't be enough memory to panic
141+
// - used for caller location evaluation
139142
InterpError::ResourceExhaustion(ResourceExhaustionInfo::MemoryExhausted)
140143
})?;
141144
bytes.resize(size.bytes_usize(), 0);

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,4 +535,10 @@ impl InterpError<'_> {
535535
_ => false,
536536
}
537537
}
538+
539+
/// Did the error originate from volatile conditons such as the memory available to the
540+
/// interpreter?
541+
pub fn is_spurious(&self) -> bool {
542+
matches!(self, InterpError::ResourceExhaustion(ResourceExhaustionInfo::MemoryExhausted))
543+
}
538544
}

compiler/rustc_middle/src/ty/vtable.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::convert::TryFrom;
22

3-
use crate::mir::interpret::{alloc_range, AllocId, Allocation, Pointer, Scalar, InterpResult};
3+
use crate::mir::interpret::{alloc_range, AllocId, Allocation, InterpResult, Pointer, Scalar};
44
use crate::ty::fold::TypeFoldable;
55
use crate::ty::{self, DefId, SubstsRef, Ty, TyCtxt};
66
use rustc_ast::Mutability;

compiler/rustc_mir/src/transform/const_prop.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,19 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
478478
Ok(op) => Some(op),
479479
Err(error) => {
480480
let tcx = self.ecx.tcx.at(c.span);
481+
if error.kind().is_spurious() {
482+
// Spurious errors can't be ignored since otherwise the amount of available
483+
// memory influences the result of optimization and the build. The error
484+
// doesn't need to be fatal since no code will actually be generated anyways.
485+
self.ecx
486+
.tcx
487+
.tcx
488+
.sess
489+
.struct_err("memory exhausted during optimization")
490+
.help("try increasing the amount of memory available to the compiler")
491+
.emit();
492+
return None;
493+
}
481494
let err = ConstEvalErr::new(&self.ecx, error, Some(c.span));
482495
if let Some(lint_root) = self.lint_root(source_info) {
483496
let lint_only = match c.literal {

0 commit comments

Comments
 (0)