Skip to content

Commit 77134bd

Browse files
Rollup merge of #153611 - RalfJung:interp-error-strings, r=oli-obk
interpret: go back to regular string interpolation for error messages Using the translatable diagnostic infrastructure adds a whole lot of boilerplate which isn't actually useful for const-eval errors, so let's get rid of it. This effectively reverts #111677. That PR effectively added 1000 lines and this PR only removes around 600 -- the difference is caused by (a) keeping some of the types around for validation, where we can use them to share error strings and to trigger the extra help for pointer byte shenanigans during CTFE, and (b) this not being a full revert of #111677; I am not touching diagnostics outside the interpreter such as all the const-checking code which also got converted to fluent in the same PR. The last commit does something similar for `LayoutError`, which also helps deduplicate a bunch of error strings. I can make that into a separate PR if you prefer. r? @oli-obk Fixes #113117 Fixes #116764 Fixes #112618
2 parents 4e64a8b + fe1f92a commit 77134bd

File tree

37 files changed

+820
-1557
lines changed

37 files changed

+820
-1557
lines changed

compiler/rustc_abi/src/lib.rs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,20 +1000,6 @@ pub enum AlignFromBytesError {
10001000
TooLarge(u64),
10011001
}
10021002

1003-
impl AlignFromBytesError {
1004-
pub fn diag_ident(self) -> &'static str {
1005-
match self {
1006-
Self::NotPowerOfTwo(_) => "not_power_of_two",
1007-
Self::TooLarge(_) => "too_large",
1008-
}
1009-
}
1010-
1011-
pub fn align(self) -> u64 {
1012-
let (Self::NotPowerOfTwo(align) | Self::TooLarge(align)) = self;
1013-
align
1014-
}
1015-
}
1016-
10171003
impl fmt::Debug for AlignFromBytesError {
10181004
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10191005
fmt::Display::fmt(self, f)
@@ -1023,8 +1009,8 @@ impl fmt::Debug for AlignFromBytesError {
10231009
impl fmt::Display for AlignFromBytesError {
10241010
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10251011
match self {
1026-
AlignFromBytesError::NotPowerOfTwo(align) => write!(f, "`{align}` is not a power of 2"),
1027-
AlignFromBytesError::TooLarge(align) => write!(f, "`{align}` is too large"),
1012+
AlignFromBytesError::NotPowerOfTwo(align) => write!(f, "{align} is not a power of 2"),
1013+
AlignFromBytesError::TooLarge(align) => write!(f, "{align} is too large"),
10281014
}
10291015
}
10301016
}

compiler/rustc_codegen_gcc/src/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
538538
| LayoutError::InvalidSimd { .. }
539539
| LayoutError::ReferencesError(_) = err
540540
{
541-
self.tcx.dcx().emit_fatal(respan(span, err.into_diagnostic()))
541+
self.tcx.dcx().span_fatal(span, err.to_string())
542542
} else {
543543
self.tcx.dcx().emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err })
544544
}

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1135,7 +1135,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
11351135
| LayoutError::ReferencesError(_)
11361136
| LayoutError::InvalidSimd { .. } = err
11371137
{
1138-
self.tcx.dcx().emit_fatal(Spanned { span, node: err.into_diagnostic() })
1138+
self.tcx.dcx().span_fatal(span, err.to_string())
11391139
} else {
11401140
self.tcx.dcx().emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err })
11411141
}

compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ fn push_debuginfo_type_name<'tcx>(
9595
// Computing the layout can still fail here, e.g. if the target architecture
9696
// cannot represent the type. See
9797
// https://github.com/rust-lang/rust/issues/94961.
98-
tcx.dcx().emit_fatal(e.into_diagnostic());
98+
tcx.dcx().fatal(e.to_string());
9999
}
100100
}
101101
} else {

compiler/rustc_const_eval/src/const_eval/dummy_machine.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,8 @@ pub macro throw_machine_stop_str($($tt:tt)*) {{
2525
write!(f, $($tt)*)
2626
}
2727
}
28+
impl rustc_middle::mir::interpret::MachineStopType for Zst {}
2829

29-
impl rustc_middle::mir::interpret::MachineStopType for Zst {
30-
fn diagnostic_message(&self) -> rustc_errors::DiagMessage {
31-
self.to_string().into()
32-
}
33-
34-
fn add_args(
35-
self: Box<Self>,
36-
_: &mut dyn FnMut(rustc_errors::DiagArgName, rustc_errors::DiagArgValue),
37-
) {}
38-
}
3930
throw_machine_stop!(Zst)
4031
}}
4132

compiler/rustc_const_eval/src/const_eval/error.rs

Lines changed: 49 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1-
use std::mem;
1+
use std::{fmt, mem};
22

3-
use rustc_errors::{Diag, DiagArgName, DiagArgValue, DiagMessage, IntoDiagArg};
3+
use rustc_errors::Diag;
44
use rustc_middle::mir::AssertKind;
5-
use rustc_middle::mir::interpret::{AllocId, Provenance, ReportedErrorInfo, UndefinedBehaviorInfo};
5+
use rustc_middle::mir::interpret::{
6+
AllocId, Provenance, ReportedErrorInfo, UndefinedBehaviorInfo, UnsupportedOpInfo,
7+
};
68
use rustc_middle::query::TyCtxtAt;
79
use rustc_middle::ty::ConstInt;
810
use rustc_middle::ty::layout::LayoutError;
911
use rustc_span::{Span, Symbol};
1012

1113
use super::CompileTimeMachine;
12-
use crate::errors::{self, FrameNote, ReportErrorExt};
14+
use crate::errors::{self, FrameNote};
1315
use crate::interpret::{
1416
CtfeProvenance, ErrorHandled, Frame, InterpCx, InterpErrorInfo, InterpErrorKind,
1517
MachineStopType, Pointer, err_inval, err_machine_stop,
@@ -40,65 +42,49 @@ pub enum ConstEvalErrKind {
4042
ConstMakeGlobalWithOffset(Pointer<Option<CtfeProvenance>>),
4143
}
4244

43-
impl MachineStopType for ConstEvalErrKind {
44-
fn diagnostic_message(&self) -> DiagMessage {
45+
impl fmt::Display for ConstEvalErrKind {
46+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4547
use ConstEvalErrKind::*;
46-
use rustc_errors::msg;
47-
4848
match self {
49-
ConstAccessesMutGlobal => "constant accesses mutable global memory".into(),
49+
ConstAccessesMutGlobal => write!(f, "constant accesses mutable global memory"),
5050
ModifiedGlobal => {
51-
"modifying a static's initial value from another static's initializer".into()
51+
write!(f, "modifying a static's initial value from another static's initializer")
5252
}
53-
Panic { .. } => msg!("evaluation panicked: {$msg}"),
53+
Panic { msg, .. } => write!(f, "evaluation panicked: {msg}"),
5454
RecursiveStatic => {
55-
"encountered static that tried to access itself during initialization".into()
55+
write!(f, "encountered static that tried to access itself during initialization")
5656
}
57-
AssertFailure(x) => x.diagnostic_message(),
57+
AssertFailure(x) => write!(f, "{x}"),
5858
WriteThroughImmutablePointer => {
59-
msg!(
59+
write!(
60+
f,
6061
"writing through a pointer that was derived from a shared (immutable) reference"
6162
)
6263
}
63-
ConstMakeGlobalPtrAlreadyMadeGlobal { .. } => {
64-
msg!("attempting to call `const_make_global` twice on the same allocation {$alloc}")
65-
}
66-
ConstMakeGlobalPtrIsNonHeap(_) => {
67-
msg!(
68-
"pointer passed to `const_make_global` does not point to a heap allocation: {$ptr}"
64+
ConstMakeGlobalPtrAlreadyMadeGlobal(alloc) => {
65+
write!(
66+
f,
67+
"attempting to call `const_make_global` twice on the same allocation {alloc}"
6968
)
7069
}
71-
ConstMakeGlobalWithDanglingPtr(_) => {
72-
msg!("pointer passed to `const_make_global` is dangling: {$ptr}")
73-
}
74-
ConstMakeGlobalWithOffset(_) => {
75-
msg!("making {$ptr} global which does not point to the beginning of an object")
76-
}
77-
}
78-
}
79-
fn add_args(self: Box<Self>, adder: &mut dyn FnMut(DiagArgName, DiagArgValue)) {
80-
use ConstEvalErrKind::*;
81-
match *self {
82-
RecursiveStatic
83-
| ConstAccessesMutGlobal
84-
| ModifiedGlobal
85-
| WriteThroughImmutablePointer => {}
86-
AssertFailure(kind) => kind.add_args(adder),
87-
Panic { msg, .. } => {
88-
adder("msg".into(), msg.into_diag_arg(&mut None));
70+
ConstMakeGlobalPtrIsNonHeap(ptr) => {
71+
write!(
72+
f,
73+
"pointer passed to `const_make_global` does not point to a heap allocation: {ptr}"
74+
)
8975
}
90-
ConstMakeGlobalPtrIsNonHeap(ptr)
91-
| ConstMakeGlobalWithOffset(ptr)
92-
| ConstMakeGlobalWithDanglingPtr(ptr) => {
93-
adder("ptr".into(), format!("{ptr:?}").into_diag_arg(&mut None));
76+
ConstMakeGlobalWithDanglingPtr(ptr) => {
77+
write!(f, "pointer passed to `const_make_global` is dangling: {ptr}")
9478
}
95-
ConstMakeGlobalPtrAlreadyMadeGlobal(alloc) => {
96-
adder("alloc".into(), alloc.into_diag_arg(&mut None));
79+
ConstMakeGlobalWithOffset(ptr) => {
80+
write!(f, "making {ptr} global which does not point to the beginning of an object")
9781
}
9882
}
9983
}
10084
}
10185

86+
impl MachineStopType for ConstEvalErrKind {}
87+
10288
/// The errors become [`InterpErrorKind::MachineStop`] when being raised.
10389
impl<'tcx> Into<InterpErrorInfo<'tcx>> for ConstEvalErrKind {
10490
fn into(self) -> InterpErrorInfo<'tcx> {
@@ -207,14 +193,20 @@ where
207193
_ => {
208194
let (our_span, frames) = get_span_and_frames();
209195
let span = span.substitute_dummy(our_span);
210-
let mut err = tcx.dcx().struct_span_err(our_span, error.diagnostic_message());
211-
// We allow invalid programs in infallible promoteds since invalid layouts can occur
212-
// anyway (e.g. due to size overflow). And we allow OOM as that can happen any time.
213-
let allowed_in_infallible = matches!(
196+
let mut err = tcx.dcx().struct_span_err(our_span, error.to_string());
197+
if matches!(
214198
error,
215-
InterpErrorKind::ResourceExhaustion(_) | InterpErrorKind::InvalidProgram(_)
216-
);
217-
199+
InterpErrorKind::UndefinedBehavior(UndefinedBehaviorInfo::ValidationError {
200+
ptr_bytes_warning: true,
201+
..
202+
}) | InterpErrorKind::Unsupported(
203+
UnsupportedOpInfo::ReadPointerAsInt(..)
204+
| UnsupportedOpInfo::ReadPartialPointer(..)
205+
)
206+
) {
207+
err.help("this code performed an operation that depends on the underlying bytes representing a pointer");
208+
err.help("the absolute address of a pointer is not known at compile-time, so such operations are not supported");
209+
}
218210
if let InterpErrorKind::UndefinedBehavior(UndefinedBehaviorInfo::InvalidUninitBytes(
219211
Some((alloc_id, _access)),
220212
)) = error
@@ -229,7 +221,12 @@ where
229221
err.subdiagnostic(raw_bytes);
230222
}
231223

232-
error.add_args(&mut err);
224+
// We allow invalid programs in infallible promoteds since invalid layouts can occur
225+
// anyway (e.g. due to size overflow). And we allow OOM as that can happen any time.
226+
let allowed_in_infallible = matches!(
227+
error,
228+
InterpErrorKind::ResourceExhaustion(_) | InterpErrorKind::InvalidProgram(_)
229+
);
233230

234231
mk(&mut err, span, frames);
235232
let g = err.emit();

compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use std::hash::Hash;
55
use rustc_abi::{Align, FIRST_VARIANT, Size};
66
use rustc_ast::Mutability;
77
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, IndexEntry};
8-
use rustc_errors::msg;
98
use rustc_hir::def_id::{DefId, LocalDefId};
109
use rustc_hir::{self as hir, CRATE_HIR_ID, LangItem, find_attr};
1110
use rustc_middle::mir::AssertMessage;
@@ -24,7 +23,7 @@ use crate::interpret::{
2423
self, AllocId, AllocInit, AllocRange, ConstAllocation, CtfeProvenance, FnArg, Frame,
2524
GlobalAlloc, ImmTy, InterpCx, InterpResult, OpTy, PlaceTy, Pointer, RangeSet, Scalar,
2625
compile_time_machine, ensure_monomorphic_enough, err_inval, interp_ok, throw_exhaust,
27-
throw_inval, throw_ub, throw_ub_custom, throw_unsup, throw_unsup_format,
26+
throw_inval, throw_ub, throw_ub_format, throw_unsup, throw_unsup_format,
2827
type_implements_dyn_trait,
2928
};
3029

@@ -489,18 +488,9 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
489488

490489
let align = match Align::from_bytes(align) {
491490
Ok(a) => a,
492-
Err(err) => throw_ub_custom!(
493-
msg!(
494-
"invalid align passed to `{$name}`: {$align} is {$err_kind ->
495-
[not_power_of_two] not a power of 2
496-
[too_large] too large
497-
*[other] {\"\"}
498-
}"
499-
),
500-
name = "const_allocate",
501-
err_kind = err.diag_ident(),
502-
align = err.align()
503-
),
491+
Err(err) => {
492+
throw_ub_format!("invalid align passed to `const_allocate`: {err}")
493+
}
504494
};
505495

506496
let ptr = ecx.allocate_ptr(
@@ -519,18 +509,9 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
519509
let size = Size::from_bytes(size);
520510
let align = match Align::from_bytes(align) {
521511
Ok(a) => a,
522-
Err(err) => throw_ub_custom!(
523-
msg!(
524-
"invalid align passed to `{$name}`: {$align} is {$err_kind ->
525-
[not_power_of_two] not a power of 2
526-
[too_large] too large
527-
*[other] {\"\"}
528-
}"
529-
),
530-
name = "const_deallocate",
531-
err_kind = err.diag_ident(),
532-
align = err.align()
533-
),
512+
Err(err) => {
513+
throw_ub_format!("invalid align passed to `const_deallocate`: {err}")
514+
}
534515
};
535516

536517
// If an allocation is created in an another const,

0 commit comments

Comments
 (0)