Auto merge of #82116 - tmiasko:box-error, r=oli-obk
Reduce size of InterpErrorInfo to 8 bytes r? `@ghost`
This commit is contained in:
commit
5ef21063f0
@ -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 }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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(
|
||||||
|
@ -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")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
);
|
);
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
);
|
);
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user