about summary refs log tree commit diff
path: root/src/tools/miri
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-06-02 10:03:49 +0200
committerRalf Jung <post@ralfj.de>2023-06-02 10:03:49 +0200
commitc5aebfb9348277639b0877eb83995dfd1bd2ff23 (patch)
treed54ef5d9706906a3b6bd2aa5337bd32d03b4112e /src/tools/miri
parent777db72b08f316345cffde2fc83478668b9da7cf (diff)
parent33c3d101280c8eb3cd8af421bfb56a8afcc3881d (diff)
downloadrust-c5aebfb9348277639b0877eb83995dfd1bd2ff23.tar.gz
rust-c5aebfb9348277639b0877eb83995dfd1bd2ff23.zip
Merge from rustc
Diffstat (limited to 'src/tools/miri')
-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
-rw-r--r--src/tools/miri/tests/fail/modifying_constants.rs2
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.rs2
9 files changed, 69 insertions, 23 deletions
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
diff --git a/src/tools/miri/tests/fail/modifying_constants.rs b/src/tools/miri/tests/fail/modifying_constants.rs
index 2783ebd155f..40ba31dad8f 100644
--- a/src/tools/miri/tests/fail/modifying_constants.rs
+++ b/src/tools/miri/tests/fail/modifying_constants.rs
@@ -1,6 +1,8 @@
 // This should fail even without validation/SB
 //@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
 
+#![allow(cast_ref_to_mut)]
+
 fn main() {
     let x = &1; // the `&1` is promoted to a constant, but it used to be that only the pointer is marked static, not the pointee
     let y = unsafe { &mut *(x as *const i32 as *mut i32) };
diff --git a/src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.rs b/src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.rs
index d1322dc6e57..8cd59b3550d 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.rs
@@ -1,3 +1,5 @@
+#![allow(cast_ref_to_mut)]
+
 fn foo(x: &mut i32) -> i32 {
     *x = 5;
     unknown_code(&*x);