diff options
| author | bors <bors@rust-lang.org> | 2023-06-02 05:11:49 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-06-02 05:11:49 +0000 |
| commit | 33c3d101280c8eb3cd8af421bfb56a8afcc3881d (patch) | |
| tree | 2e65db5c7568d3a9220cca76dec79c036a97d749 /src | |
| parent | 774a3d1523bde3a16f8a92dbaac01d211ba911c3 (diff) | |
| parent | f6c2bc5c24fd08200c0e4438d981ca58dc71f488 (diff) | |
| download | rust-33c3d101280c8eb3cd8af421bfb56a8afcc3881d.tar.gz rust-33c3d101280c8eb3cd8af421bfb56a8afcc3881d.zip | |
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
Diffstat (limited to 'src')
| -rw-r--r-- | src/tools/clippy/tests/ui/modulo_one.stderr | 6 | ||||
| -rw-r--r-- | src/tools/miri/src/diagnostics.rs | 68 | ||||
| -rw-r--r-- | src/tools/miri/src/eval.rs | 5 | ||||
| -rw-r--r-- | src/tools/miri/src/helpers.rs | 4 | ||||
| -rw-r--r-- | src/tools/miri/src/lib.rs | 1 | ||||
| -rw-r--r-- | src/tools/miri/tests/fail/intrinsics/copy_overlapping.rs | 2 | ||||
| -rw-r--r-- | src/tools/miri/tests/fail/intrinsics/copy_overlapping.stderr | 4 | ||||
| -rw-r--r-- | src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr | 4 |
8 files changed, 68 insertions, 26 deletions
diff --git a/src/tools/clippy/tests/ui/modulo_one.stderr b/src/tools/clippy/tests/ui/modulo_one.stderr index 04ecdef5e99..83a76f81d4e 100644 --- a/src/tools/clippy/tests/ui/modulo_one.stderr +++ b/src/tools/clippy/tests/ui/modulo_one.stderr @@ -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 diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 14931baaadf..8c788c915fe 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -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> { diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 43d8f221ce3..1e9d48be65e 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -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:?}") } }; diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index a2b49e6f219..f1190265239 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -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`. diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 893a4dbd4c8..f711f01f323 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -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; diff --git a/src/tools/miri/tests/fail/intrinsics/copy_overlapping.rs b/src/tools/miri/tests/fail/intrinsics/copy_overlapping.rs index 3df881bd43c..9c73bdc17be 100644 --- a/src/tools/miri/tests/fail/intrinsics/copy_overlapping.rs +++ b/src/tools/miri/tests/fail/intrinsics/copy_overlapping.rs @@ -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 } } diff --git a/src/tools/miri/tests/fail/intrinsics/copy_overlapping.stderr b/src/tools/miri/tests/fail/intrinsics/copy_overlapping.stderr index cdb3da74ca9..13a76aae730 100644 --- a/src/tools/miri/tests/fail/intrinsics/copy_overlapping.stderr +++ b/src/tools/miri/tests/fail/intrinsics/copy_overlapping.stderr @@ -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 diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr index a31b929d7a7..0b9cda62b33 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr @@ -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 |
