Skip to content

Commit e190f0d

Browse files
committed
Reduce size of InterpErrorInfo to 8 bytes
1 parent ee88f46 commit e190f0d

File tree

7 files changed

+47
-24
lines changed

7 files changed

+47
-24
lines changed

Diff for: compiler/rustc_middle/src/mir/interpret/error.rs

+22-6
Original file line numberDiff line numberDiff line change
@@ -40,29 +40,45 @@ pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<'
4040
struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg)
4141
}
4242

43+
#[cfg(target_arch = "x86_64")]
44+
static_assert_size!(InterpErrorInfo<'_>, 8);
45+
4346
/// Packages the kind of error we got from the const code interpreter
4447
/// up with a Rust-level backtrace of where the error occurred.
4548
/// Thsese should always be constructed by calling `.into()` on
4649
/// a `InterpError`. In `librustc_mir::interpret`, we have `throw_err_*`
4750
/// macros for this.
4851
#[derive(Debug)]
49-
pub struct InterpErrorInfo<'tcx> {
50-
pub kind: InterpError<'tcx>,
52+
pub struct InterpErrorInfo<'tcx>(Box<InterpErrorInfoInner<'tcx>>);
53+
54+
#[derive(Debug)]
55+
struct InterpErrorInfoInner<'tcx> {
56+
kind: InterpError<'tcx>,
5157
backtrace: Option<Box<Backtrace>>,
5258
}
5359

5460
impl fmt::Display for InterpErrorInfo<'_> {
5561
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56-
write!(f, "{}", self.kind)
62+
write!(f, "{}", self.0.kind)
5763
}
5864
}
5965

60-
impl InterpErrorInfo<'_> {
66+
impl InterpErrorInfo<'tcx> {
6167
pub fn print_backtrace(&self) {
62-
if let Some(backtrace) = self.backtrace.as_ref() {
68+
if let Some(backtrace) = self.0.backtrace.as_ref() {
6369
print_backtrace(backtrace);
6470
}
6571
}
72+
73+
pub fn into_kind(self) -> InterpError<'tcx> {
74+
let InterpErrorInfo(box InterpErrorInfoInner { kind, .. }) = self;
75+
kind
76+
}
77+
78+
#[inline]
79+
pub fn kind(&self) -> &InterpError<'tcx> {
80+
&self.0.kind
81+
}
6682
}
6783

6884
fn print_backtrace(backtrace: &Backtrace) {
@@ -108,7 +124,7 @@ impl<'tcx> From<InterpError<'tcx>> for InterpErrorInfo<'tcx> {
108124
}
109125
};
110126

111-
InterpErrorInfo { kind, backtrace }
127+
InterpErrorInfo(Box::new(InterpErrorInfoInner { kind, backtrace }))
112128
}
113129
}
114130

Diff for: compiler/rustc_mir/src/const_eval/error.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,11 @@ impl<'tcx> ConstEvalErr<'tcx> {
8484
{
8585
error.print_backtrace();
8686
let stacktrace = ecx.generate_stacktrace();
87-
ConstEvalErr { error: error.kind, stacktrace, span: span.unwrap_or_else(|| ecx.cur_span()) }
87+
ConstEvalErr {
88+
error: error.into_kind(),
89+
stacktrace,
90+
span: span.unwrap_or_else(|| ecx.cur_span()),
91+
}
8892
}
8993

9094
pub fn struct_error(

Diff for: compiler/rustc_mir/src/const_eval/eval_queries.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
230230
};
231231
return eval_nullary_intrinsic(tcx, key.param_env, def_id, substs).map_err(|error| {
232232
let span = tcx.def_span(def_id);
233-
let error = ConstEvalErr { error: error.kind, stacktrace: vec![], span };
233+
let error = ConstEvalErr { error: error.into_kind(), stacktrace: vec![], span };
234234
error.report_as_error(tcx.at(span), "could not evaluate nullary intrinsic")
235235
});
236236
}

Diff for: compiler/rustc_mir/src/const_eval/machine.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
245245
Ok(Some(match ecx.load_mir(instance.def, None) {
246246
Ok(body) => body,
247247
Err(err) => {
248-
if let err_unsup!(NoMirFor(did)) = err.kind {
249-
let path = ecx.tcx.def_path_str(did);
248+
if let err_unsup!(NoMirFor(did)) = err.kind() {
249+
let path = ecx.tcx.def_path_str(*did);
250250
return Err(ConstEvalErrKind::NeedsRfc(format!(
251251
"calling extern function `{}`",
252252
path

Diff for: compiler/rustc_mir/src/interpret/intern.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ where
356356
// an allocation, which we should avoid. When that happens,
357357
// dedicated error variants should be introduced instead.
358358
assert!(
359-
!error.kind.allocates(),
359+
!error.kind().allocates(),
360360
"interning encountered allocating error: {}",
361361
error
362362
);

Diff for: compiler/rustc_mir/src/interpret/validity.rs

+15-12
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::ops::RangeInclusive;
1111

1212
use rustc_data_structures::fx::FxHashSet;
1313
use rustc_hir as hir;
14-
use rustc_middle::mir::interpret::{InterpError, InterpErrorInfo};
14+
use rustc_middle::mir::interpret::InterpError;
1515
use rustc_middle::ty;
1616
use rustc_middle::ty::layout::TyAndLayout;
1717
use rustc_span::symbol::{sym, Symbol};
@@ -83,14 +83,17 @@ macro_rules! try_validation {
8383
Ok(x) => x,
8484
// We catch the error and turn it into a validation failure. We are okay with
8585
// allocation here as this can only slow down builds that fail anyway.
86-
$( $( Err(InterpErrorInfo { kind: $p, .. }) )|+ =>
87-
throw_validation_failure!(
88-
$where,
89-
{ $( $what_fmt ),+ } $( expected { $( $expected_fmt ),+ } )?
90-
),
91-
)+
92-
#[allow(unreachable_patterns)]
93-
Err(e) => Err::<!, _>(e)?,
86+
Err(e) => match e.kind() {
87+
$(
88+
$($p)|+ =>
89+
throw_validation_failure!(
90+
$where,
91+
{ $( $what_fmt ),+ } $( expected { $( $expected_fmt ),+ } )?
92+
)
93+
),+,
94+
#[allow(unreachable_patterns)]
95+
_ => Err::<!, _>(e)?,
96+
}
9497
}
9598
}};
9699
}
@@ -877,7 +880,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
877880
Err(err) => {
878881
// For some errors we might be able to provide extra information.
879882
// (This custom logic does not fit the `try_validation!` macro.)
880-
match err.kind {
883+
match err.kind() {
881884
err_ub!(InvalidUninitBytes(Some(access))) => {
882885
// Some byte was uninitialized, determine which
883886
// element that byte belongs to so we can
@@ -935,10 +938,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
935938
match visitor.visit_value(op) {
936939
Ok(()) => Ok(()),
937940
// Pass through validation failures.
938-
Err(err) if matches!(err.kind, err_ub!(ValidationFailure { .. })) => Err(err),
941+
Err(err) if matches!(err.kind(), err_ub!(ValidationFailure { .. })) => Err(err),
939942
// Also pass through InvalidProgram, those just indicate that we could not
940943
// validate and each caller will know best what to do with them.
941-
Err(err) if matches!(err.kind, InterpError::InvalidProgram(_)) => Err(err),
944+
Err(err) if matches!(err.kind(), InterpError::InvalidProgram(_)) => Err(err),
942945
// Avoid other errors as those do not show *where* in the value the issue lies.
943946
Err(err) => {
944947
err.print_backtrace();

Diff for: compiler/rustc_mir/src/transform/const_prop.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
466466
// an allocation, which we should avoid. When that happens,
467467
// dedicated error variants should be introduced instead.
468468
assert!(
469-
!error.kind.allocates(),
469+
!error.kind().allocates(),
470470
"const-prop encountered allocating error: {}",
471471
error
472472
);

0 commit comments

Comments
 (0)