Properly handle const prop failures
This commit is contained in:
parent
c94bafb69b
commit
d04da1125d
4 changed files with 28 additions and 6 deletions
|
@ -131,11 +131,14 @@ impl<Tag> Allocation<Tag> {
|
|||
// 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 do one of:
|
||||
// - cause a fatal compiler error when they see this error as the result of const
|
||||
// evaluation
|
||||
// - panic on evaluation failure
|
||||
// - always evaluate very small constants that are practically unlikely to result in
|
||||
// memory exhaustion
|
||||
// - error on failure
|
||||
// - used for static initalizer evalution
|
||||
// - used for const value evaluation
|
||||
// - const prop errors on this since otherwise it would generate different code based
|
||||
// on available memory
|
||||
// - panic on failure to allocate very small sizes
|
||||
// - actually panicking won't happen since there wouldn't be enough memory to panic
|
||||
// - used for caller location evaluation
|
||||
InterpError::ResourceExhaustion(ResourceExhaustionInfo::MemoryExhausted)
|
||||
})?;
|
||||
bytes.resize(size.bytes_usize(), 0);
|
||||
|
|
|
@ -535,4 +535,10 @@ impl InterpError<'_> {
|
|||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Did the error originate from volatile conditons such as the memory available to the
|
||||
/// interpreter?
|
||||
pub fn is_spurious(&self) -> bool {
|
||||
matches!(self, InterpError::ResourceExhaustion(ResourceExhaustionInfo::MemoryExhausted))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::convert::TryFrom;
|
||||
|
||||
use crate::mir::interpret::{alloc_range, AllocId, Allocation, Pointer, Scalar, InterpResult};
|
||||
use crate::mir::interpret::{alloc_range, AllocId, Allocation, InterpResult, Pointer, Scalar};
|
||||
use crate::ty::fold::TypeFoldable;
|
||||
use crate::ty::{self, DefId, SubstsRef, Ty, TyCtxt};
|
||||
use rustc_ast::Mutability;
|
||||
|
|
|
@ -478,6 +478,19 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
Ok(op) => Some(op),
|
||||
Err(error) => {
|
||||
let tcx = self.ecx.tcx.at(c.span);
|
||||
if error.kind().is_spurious() {
|
||||
// Spurious errors can't be ignored since otherwise the amount of available
|
||||
// memory influences the result of optimization and the build. The error
|
||||
// doesn't need to be fatal since no code will actually be generated anyways.
|
||||
self.ecx
|
||||
.tcx
|
||||
.tcx
|
||||
.sess
|
||||
.struct_err("memory exhausted during optimization")
|
||||
.help("try increasing the amount of memory available to the compiler")
|
||||
.emit();
|
||||
return None;
|
||||
}
|
||||
let err = ConstEvalErr::new(&self.ecx, error, Some(c.span));
|
||||
if let Some(lint_root) = self.lint_root(source_info) {
|
||||
let lint_only = match c.literal {
|
||||
|
|
Loading…
Add table
Reference in a new issue