Auto merge of #111677 - fee1-dead-contrib:rustc_const_eval-translatable, r=oli-obk,RalfJung
Use translatable diagnostics in `rustc_const_eval` This PR: * adds a `no_span` parameter to `note` / `help` attributes when using `Subdiagnostic` to allow adding notes/helps without using a span * has minor tweaks and changes to error messages
This commit is contained in:
commit
33c3d10128
93 changed files with 2385 additions and 1128 deletions
|
|
@ -2,7 +2,7 @@ error: this operation will panic at runtime
|
|||
--> $DIR/modulo_one.rs:11:5
|
||||
|
|
||||
LL | i32::MIN % (-1); // also caught by rustc
|
||||
| ^^^^^^^^^^^^^^^ attempt to compute the remainder of `i32::MIN % -1_i32`, which would overflow
|
||||
| ^^^^^^^^^^^^^^^ attempt to compute `i32::MIN % -1_i32`, which would overflow
|
||||
|
|
||||
= note: `#[deny(unconditional_panic)]` on by default
|
||||
|
||||
|
|
@ -10,13 +10,13 @@ error: this operation will panic at runtime
|
|||
--> $DIR/modulo_one.rs:21:5
|
||||
|
|
||||
LL | INT_MIN % NEG_ONE; // also caught by rustc
|
||||
| ^^^^^^^^^^^^^^^^^ attempt to compute the remainder of `i64::MIN % -1_i64`, which would overflow
|
||||
| ^^^^^^^^^^^^^^^^^ attempt to compute `i64::MIN % -1_i64`, which would overflow
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/modulo_one.rs:22:5
|
||||
|
|
||||
LL | INT_MIN % STATIC_NEG_ONE; // ONLY caught by rustc
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute the remainder of `i64::MIN % -1_i64`, which would overflow
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `i64::MIN % -1_i64`, which would overflow
|
||||
|
||||
error: any number modulo 1 will be 0
|
||||
--> $DIR/modulo_one.rs:8:5
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ use std::num::NonZeroU64;
|
|||
|
||||
use log::trace;
|
||||
|
||||
use rustc_const_eval::ReportErrorExt;
|
||||
use rustc_errors::DiagnosticMessage;
|
||||
use rustc_span::{source_map::DUMMY_SP, SpanData, Symbol};
|
||||
use rustc_target::abi::{Align, Size};
|
||||
|
||||
|
|
@ -83,7 +85,21 @@ impl fmt::Display for TerminationInfo {
|
|||
}
|
||||
}
|
||||
|
||||
impl MachineStopType for TerminationInfo {}
|
||||
impl fmt::Debug for TerminationInfo {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
}
|
||||
|
||||
impl MachineStopType for TerminationInfo {
|
||||
fn diagnostic_message(&self) -> DiagnosticMessage {
|
||||
self.to_string().into()
|
||||
}
|
||||
fn add_args(
|
||||
self: Box<Self>,
|
||||
_: &mut dyn FnMut(std::borrow::Cow<'static, str>, rustc_errors::DiagnosticArgValue<'static>),
|
||||
) {}
|
||||
}
|
||||
|
||||
/// Miri specific diagnostics
|
||||
pub enum NonHaltingDiagnostic {
|
||||
|
|
@ -302,8 +318,32 @@ pub fn report_error<'tcx, 'mir>(
|
|||
|
||||
let stacktrace = ecx.generate_stacktrace();
|
||||
let (stacktrace, was_pruned) = prune_stacktrace(stacktrace, &ecx.machine);
|
||||
e.print_backtrace();
|
||||
msg.insert(0, e.to_string());
|
||||
let (e, backtrace) = e.into_parts();
|
||||
backtrace.print_backtrace();
|
||||
|
||||
// We want to dump the allocation if this is `InvalidUninitBytes`. Since `add_args` consumes
|
||||
// the `InterpError`, we extract the variables it before that.
|
||||
let extra = match e {
|
||||
UndefinedBehavior(UndefinedBehaviorInfo::InvalidUninitBytes(Some((alloc_id, access)))) => {
|
||||
Some((alloc_id, access))
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
|
||||
// FIXME(fee1-dead), HACK: we want to use the error as title therefore we can just extract the
|
||||
// label and arguments from the InterpError.
|
||||
let e = {
|
||||
let handler = &ecx.tcx.sess.parse_sess.span_diagnostic;
|
||||
let mut diag = ecx.tcx.sess.struct_allow("");
|
||||
let msg = e.diagnostic_message();
|
||||
e.add_args(handler, &mut diag);
|
||||
let s = handler.eagerly_translate_to_string(msg, diag.args());
|
||||
diag.cancel();
|
||||
s
|
||||
};
|
||||
|
||||
msg.insert(0, e);
|
||||
|
||||
report_msg(
|
||||
DiagLevel::Error,
|
||||
if let Some(title) = title { format!("{title}: {}", msg[0]) } else { msg[0].clone() },
|
||||
|
|
@ -332,15 +372,12 @@ pub fn report_error<'tcx, 'mir>(
|
|||
}
|
||||
|
||||
// Extra output to help debug specific issues.
|
||||
match e.kind() {
|
||||
UndefinedBehavior(UndefinedBehaviorInfo::InvalidUninitBytes(Some((alloc_id, access)))) => {
|
||||
eprintln!(
|
||||
"Uninitialized memory occurred at {alloc_id:?}{range:?}, in this allocation:",
|
||||
range = access.uninit,
|
||||
);
|
||||
eprintln!("{:?}", ecx.dump_alloc(*alloc_id));
|
||||
}
|
||||
_ => {}
|
||||
if let Some((alloc_id, access)) = extra {
|
||||
eprintln!(
|
||||
"Uninitialized memory occurred at {alloc_id:?}{range:?}, in this allocation:",
|
||||
range = access.uninit,
|
||||
);
|
||||
eprintln!("{:?}", ecx.dump_alloc(alloc_id));
|
||||
}
|
||||
|
||||
None
|
||||
|
|
@ -438,12 +475,15 @@ pub fn report_msg<'tcx>(
|
|||
// Add visual separator before backtrace.
|
||||
err.note(if extra_span { "BACKTRACE (of the first span):" } else { "BACKTRACE:" });
|
||||
}
|
||||
|
||||
let (mut err, handler) = err.into_diagnostic().unwrap();
|
||||
|
||||
// Add backtrace
|
||||
for (idx, frame_info) in stacktrace.iter().enumerate() {
|
||||
let is_local = machine.is_local(frame_info);
|
||||
// No span for non-local frames and the first frame (which is the error site).
|
||||
if is_local && idx > 0 {
|
||||
err.span_note(frame_info.span, frame_info.to_string());
|
||||
err.eager_subdiagnostic(handler, frame_info.as_note(machine.tcx));
|
||||
} else {
|
||||
let sm = sess.source_map();
|
||||
let span = sm.span_to_embeddable_string(frame_info.span);
|
||||
|
|
@ -451,7 +491,7 @@ pub fn report_msg<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
err.emit();
|
||||
handler.emit_diagnostic(&mut err);
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
|
||||
|
|
|
|||
|
|
@ -422,8 +422,9 @@ pub fn eval_entry<'tcx>(
|
|||
let mut ecx = match create_ecx(tcx, entry_id, entry_type, &config) {
|
||||
Ok(v) => v,
|
||||
Err(err) => {
|
||||
err.print_backtrace();
|
||||
panic!("Miri initialization error: {}", err.kind())
|
||||
let (kind, backtrace) = err.into_parts();
|
||||
backtrace.print_backtrace();
|
||||
panic!("Miri initialization error: {kind:?}")
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -164,9 +164,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
// We don't give a span -- this isn't actually used directly by the program anyway.
|
||||
let const_val = this
|
||||
.eval_global(cid, None)
|
||||
.unwrap_or_else(|err| panic!("failed to evaluate required Rust item: {path:?}\n{err}"));
|
||||
.unwrap_or_else(|err| panic!("failed to evaluate required Rust item: {path:?}\n{err:?}"));
|
||||
this.read_scalar(&const_val.into())
|
||||
.unwrap_or_else(|err| panic!("failed to read required Rust item: {path:?}\n{err}"))
|
||||
.unwrap_or_else(|err| panic!("failed to read required Rust item: {path:?}\n{err:?}"))
|
||||
}
|
||||
|
||||
/// Helper function to get a `libc` constant as a `Scalar`.
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
|
||||
extern crate rustc_apfloat;
|
||||
extern crate rustc_ast;
|
||||
extern crate rustc_errors;
|
||||
#[macro_use]
|
||||
extern crate rustc_middle;
|
||||
extern crate rustc_const_eval;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,6 @@ fn main() {
|
|||
unsafe {
|
||||
let a = data.as_mut_ptr();
|
||||
let b = a.wrapping_offset(1) as *mut _;
|
||||
copy_nonoverlapping(a, b, 2); //~ ERROR: copy_nonoverlapping called on overlapping ranges
|
||||
copy_nonoverlapping(a, b, 2); //~ ERROR: `copy_nonoverlapping` called on overlapping ranges
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: Undefined Behavior: copy_nonoverlapping called on overlapping ranges
|
||||
error: Undefined Behavior: `copy_nonoverlapping` called on overlapping ranges
|
||||
--> $DIR/copy_overlapping.rs:LL:CC
|
||||
|
|
||||
LL | copy_nonoverlapping(a, b, 2);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ copy_nonoverlapping called on overlapping ranges
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `copy_nonoverlapping` called on overlapping ranges
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: Undefined Behavior: out-of-bounds offset_from: ALLOC has size 4, so pointer at offset 10 is out-of-bounds
|
||||
error: Undefined Behavior: out-of-bounds `offset_from`: ALLOC has size 4, so pointer at offset 10 is out-of-bounds
|
||||
--> $DIR/ptr_offset_from_oob.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { end_ptr.offset_from(end_ptr) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: ALLOC has size 4, so pointer at offset 10 is out-of-bounds
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from`: ALLOC has size 4, so pointer at offset 10 is out-of-bounds
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue