about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-06-02 05:11:49 +0000
committerbors <bors@rust-lang.org>2023-06-02 05:11:49 +0000
commit33c3d101280c8eb3cd8af421bfb56a8afcc3881d (patch)
tree2e65db5c7568d3a9220cca76dec79c036a97d749 /src
parent774a3d1523bde3a16f8a92dbaac01d211ba911c3 (diff)
parentf6c2bc5c24fd08200c0e4438d981ca58dc71f488 (diff)
downloadrust-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.stderr6
-rw-r--r--src/tools/miri/src/diagnostics.rs68
-rw-r--r--src/tools/miri/src/eval.rs5
-rw-r--r--src/tools/miri/src/helpers.rs4
-rw-r--r--src/tools/miri/src/lib.rs1
-rw-r--r--src/tools/miri/tests/fail/intrinsics/copy_overlapping.rs2
-rw-r--r--src/tools/miri/tests/fail/intrinsics/copy_overlapping.stderr4
-rw-r--r--src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr4
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