Auto merge of #82116 - tmiasko:box-error, r=oli-obk

Reduce size of InterpErrorInfo to 8 bytes

r? `@ghost`
This commit is contained in:
bors 2021-02-17 16:47:18 +00:00
commit 5ef21063f0
8 changed files with 48 additions and 25 deletions

View File

@ -40,29 +40,45 @@ pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<'
struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg) struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg)
} }
#[cfg(target_arch = "x86_64")]
static_assert_size!(InterpErrorInfo<'_>, 8);
/// Packages the kind of error we got from the const code interpreter /// Packages the kind of error we got from the const code interpreter
/// up with a Rust-level backtrace of where the error occurred. /// up with a Rust-level backtrace of where the error occurred.
/// Thsese should always be constructed by calling `.into()` on /// Thsese should always be constructed by calling `.into()` on
/// a `InterpError`. In `librustc_mir::interpret`, we have `throw_err_*` /// a `InterpError`. In `librustc_mir::interpret`, we have `throw_err_*`
/// macros for this. /// macros for this.
#[derive(Debug)] #[derive(Debug)]
pub struct InterpErrorInfo<'tcx> { pub struct InterpErrorInfo<'tcx>(Box<InterpErrorInfoInner<'tcx>>);
pub kind: InterpError<'tcx>,
#[derive(Debug)]
struct InterpErrorInfoInner<'tcx> {
kind: InterpError<'tcx>,
backtrace: Option<Box<Backtrace>>, backtrace: Option<Box<Backtrace>>,
} }
impl fmt::Display for InterpErrorInfo<'_> { impl fmt::Display for InterpErrorInfo<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.kind) write!(f, "{}", self.0.kind)
} }
} }
impl InterpErrorInfo<'_> { impl InterpErrorInfo<'tcx> {
pub fn print_backtrace(&self) { pub fn print_backtrace(&self) {
if let Some(backtrace) = self.backtrace.as_ref() { if let Some(backtrace) = self.0.backtrace.as_ref() {
print_backtrace(backtrace); print_backtrace(backtrace);
} }
} }
pub fn into_kind(self) -> InterpError<'tcx> {
let InterpErrorInfo(box InterpErrorInfoInner { kind, .. }) = self;
kind
}
#[inline]
pub fn kind(&self) -> &InterpError<'tcx> {
&self.0.kind
}
} }
fn print_backtrace(backtrace: &Backtrace) { fn print_backtrace(backtrace: &Backtrace) {
@ -108,7 +124,7 @@ impl<'tcx> From<InterpError<'tcx>> for InterpErrorInfo<'tcx> {
} }
}; };
InterpErrorInfo { kind, backtrace } InterpErrorInfo(Box::new(InterpErrorInfoInner { kind, backtrace }))
} }
} }

View File

@ -84,7 +84,11 @@ impl<'tcx> ConstEvalErr<'tcx> {
{ {
error.print_backtrace(); error.print_backtrace();
let stacktrace = ecx.generate_stacktrace(); let stacktrace = ecx.generate_stacktrace();
ConstEvalErr { error: error.kind, stacktrace, span: span.unwrap_or_else(|| ecx.cur_span()) } ConstEvalErr {
error: error.into_kind(),
stacktrace,
span: span.unwrap_or_else(|| ecx.cur_span()),
}
} }
pub fn struct_error( pub fn struct_error(

View File

@ -230,7 +230,7 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
}; };
return eval_nullary_intrinsic(tcx, key.param_env, def_id, substs).map_err(|error| { return eval_nullary_intrinsic(tcx, key.param_env, def_id, substs).map_err(|error| {
let span = tcx.def_span(def_id); let span = tcx.def_span(def_id);
let error = ConstEvalErr { error: error.kind, stacktrace: vec![], span }; let error = ConstEvalErr { error: error.into_kind(), stacktrace: vec![], span };
error.report_as_error(tcx.at(span), "could not evaluate nullary intrinsic") error.report_as_error(tcx.at(span), "could not evaluate nullary intrinsic")
}); });
} }

View File

@ -245,8 +245,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
Ok(Some(match ecx.load_mir(instance.def, None) { Ok(Some(match ecx.load_mir(instance.def, None) {
Ok(body) => body, Ok(body) => body,
Err(err) => { Err(err) => {
if let err_unsup!(NoMirFor(did)) = err.kind { if let err_unsup!(NoMirFor(did)) = err.kind() {
let path = ecx.tcx.def_path_str(did); let path = ecx.tcx.def_path_str(*did);
return Err(ConstEvalErrKind::NeedsRfc(format!( return Err(ConstEvalErrKind::NeedsRfc(format!(
"calling extern function `{}`", "calling extern function `{}`",
path path

View File

@ -356,7 +356,7 @@ where
// an allocation, which we should avoid. When that happens, // an allocation, which we should avoid. When that happens,
// dedicated error variants should be introduced instead. // dedicated error variants should be introduced instead.
assert!( assert!(
!error.kind.allocates(), !error.kind().allocates(),
"interning encountered allocating error: {}", "interning encountered allocating error: {}",
error error
); );

View File

@ -11,7 +11,7 @@ use std::ops::RangeInclusive;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_middle::mir::interpret::{InterpError, InterpErrorInfo}; use rustc_middle::mir::interpret::InterpError;
use rustc_middle::ty; use rustc_middle::ty;
use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::layout::TyAndLayout;
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Symbol};
@ -83,14 +83,17 @@ macro_rules! try_validation {
Ok(x) => x, Ok(x) => x,
// We catch the error and turn it into a validation failure. We are okay with // We catch the error and turn it into a validation failure. We are okay with
// allocation here as this can only slow down builds that fail anyway. // allocation here as this can only slow down builds that fail anyway.
$( $( Err(InterpErrorInfo { kind: $p, .. }) )|+ => Err(e) => match e.kind() {
throw_validation_failure!( $(
$where, $($p)|+ =>
{ $( $what_fmt ),+ } $( expected { $( $expected_fmt ),+ } )? throw_validation_failure!(
), $where,
)+ { $( $what_fmt ),+ } $( expected { $( $expected_fmt ),+ } )?
#[allow(unreachable_patterns)] )
Err(e) => Err::<!, _>(e)?, ),+,
#[allow(unreachable_patterns)]
_ => Err::<!, _>(e)?,
}
} }
}}; }};
} }
@ -877,7 +880,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
Err(err) => { Err(err) => {
// For some errors we might be able to provide extra information. // For some errors we might be able to provide extra information.
// (This custom logic does not fit the `try_validation!` macro.) // (This custom logic does not fit the `try_validation!` macro.)
match err.kind { match err.kind() {
err_ub!(InvalidUninitBytes(Some(access))) => { err_ub!(InvalidUninitBytes(Some(access))) => {
// Some byte was uninitialized, determine which // Some byte was uninitialized, determine which
// element that byte belongs to so we can // element that byte belongs to so we can
@ -935,10 +938,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
match visitor.visit_value(op) { match visitor.visit_value(op) {
Ok(()) => Ok(()), Ok(()) => Ok(()),
// Pass through validation failures. // Pass through validation failures.
Err(err) if matches!(err.kind, err_ub!(ValidationFailure { .. })) => Err(err), Err(err) if matches!(err.kind(), err_ub!(ValidationFailure { .. })) => Err(err),
// Also pass through InvalidProgram, those just indicate that we could not // Also pass through InvalidProgram, those just indicate that we could not
// validate and each caller will know best what to do with them. // validate and each caller will know best what to do with them.
Err(err) if matches!(err.kind, InterpError::InvalidProgram(_)) => Err(err), Err(err) if matches!(err.kind(), InterpError::InvalidProgram(_)) => Err(err),
// Avoid other errors as those do not show *where* in the value the issue lies. // Avoid other errors as those do not show *where* in the value the issue lies.
Err(err) => { Err(err) => {
err.print_backtrace(); err.print_backtrace();

View File

@ -466,7 +466,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
// an allocation, which we should avoid. When that happens, // an allocation, which we should avoid. When that happens,
// dedicated error variants should be introduced instead. // dedicated error variants should be introduced instead.
assert!( assert!(
!error.kind.allocates(), !error.kind().allocates(),
"const-prop encountered allocating error: {}", "const-prop encountered allocating error: {}",
error error
); );

View File

@ -1,5 +1,5 @@
#![feature(llvm_asm)] #![feature(llvm_asm)]
// compile-flags: -Ccodegen-units=1
// build-fail // build-fail
// only-x86_64 // only-x86_64