Skip to content

Commit 8095bbc

Browse files
committed
Auto merge of #2911 - RalfJung:rustup, r=RalfJung
Rustup
2 parents eadeab5 + 716dc09 commit 8095bbc

10 files changed

+75
-26
lines changed

rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
617d3d6d722c432cdcbf210e6db55c3bdeafe381
1+
33c3d101280c8eb3cd8af421bfb56a8afcc3881d

src/diagnostics.rs

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use std::num::NonZeroU64;
33

44
use log::trace;
55

6+
use rustc_const_eval::ReportErrorExt;
7+
use rustc_errors::DiagnosticMessage;
68
use rustc_span::{source_map::DUMMY_SP, SpanData, Symbol};
79
use rustc_target::abi::{Align, Size};
810

@@ -83,7 +85,25 @@ impl fmt::Display for TerminationInfo {
8385
}
8486
}
8587

86-
impl MachineStopType for TerminationInfo {}
88+
impl fmt::Debug for TerminationInfo {
89+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90+
write!(f, "{self}")
91+
}
92+
}
93+
94+
impl MachineStopType for TerminationInfo {
95+
fn diagnostic_message(&self) -> DiagnosticMessage {
96+
self.to_string().into()
97+
}
98+
fn add_args(
99+
self: Box<Self>,
100+
_: &mut dyn FnMut(
101+
std::borrow::Cow<'static, str>,
102+
rustc_errors::DiagnosticArgValue<'static>,
103+
),
104+
) {
105+
}
106+
}
87107

88108
/// Miri specific diagnostics
89109
pub enum NonHaltingDiagnostic {
@@ -302,8 +322,31 @@ pub fn report_error<'tcx, 'mir>(
302322

303323
let stacktrace = ecx.generate_stacktrace();
304324
let (stacktrace, was_pruned) = prune_stacktrace(stacktrace, &ecx.machine);
305-
e.print_backtrace();
306-
msg.insert(0, e.to_string());
325+
let (e, backtrace) = e.into_parts();
326+
backtrace.print_backtrace();
327+
328+
// We want to dump the allocation if this is `InvalidUninitBytes`. Since `add_args` consumes
329+
// the `InterpError`, we extract the variables it before that.
330+
let extra = match e {
331+
UndefinedBehavior(UndefinedBehaviorInfo::InvalidUninitBytes(Some((alloc_id, access)))) =>
332+
Some((alloc_id, access)),
333+
_ => None,
334+
};
335+
336+
// FIXME(fee1-dead), HACK: we want to use the error as title therefore we can just extract the
337+
// label and arguments from the InterpError.
338+
let e = {
339+
let handler = &ecx.tcx.sess.parse_sess.span_diagnostic;
340+
let mut diag = ecx.tcx.sess.struct_allow("");
341+
let msg = e.diagnostic_message();
342+
e.add_args(handler, &mut diag);
343+
let s = handler.eagerly_translate_to_string(msg, diag.args());
344+
diag.cancel();
345+
s
346+
};
347+
348+
msg.insert(0, e);
349+
307350
report_msg(
308351
DiagLevel::Error,
309352
if let Some(title) = title { format!("{title}: {}", msg[0]) } else { msg[0].clone() },
@@ -332,15 +375,12 @@ pub fn report_error<'tcx, 'mir>(
332375
}
333376

334377
// Extra output to help debug specific issues.
335-
match e.kind() {
336-
UndefinedBehavior(UndefinedBehaviorInfo::InvalidUninitBytes(Some((alloc_id, access)))) => {
337-
eprintln!(
338-
"Uninitialized memory occurred at {alloc_id:?}{range:?}, in this allocation:",
339-
range = access.uninit,
340-
);
341-
eprintln!("{:?}", ecx.dump_alloc(*alloc_id));
342-
}
343-
_ => {}
378+
if let Some((alloc_id, access)) = extra {
379+
eprintln!(
380+
"Uninitialized memory occurred at {alloc_id:?}{range:?}, in this allocation:",
381+
range = access.uninit,
382+
);
383+
eprintln!("{:?}", ecx.dump_alloc(alloc_id));
344384
}
345385

346386
None
@@ -438,20 +478,23 @@ pub fn report_msg<'tcx>(
438478
// Add visual separator before backtrace.
439479
err.note(if extra_span { "BACKTRACE (of the first span):" } else { "BACKTRACE:" });
440480
}
481+
482+
let (mut err, handler) = err.into_diagnostic().unwrap();
483+
441484
// Add backtrace
442485
for (idx, frame_info) in stacktrace.iter().enumerate() {
443486
let is_local = machine.is_local(frame_info);
444487
// No span for non-local frames and the first frame (which is the error site).
445488
if is_local && idx > 0 {
446-
err.span_note(frame_info.span, frame_info.to_string());
489+
err.eager_subdiagnostic(handler, frame_info.as_note(machine.tcx));
447490
} else {
448491
let sm = sess.source_map();
449492
let span = sm.span_to_embeddable_string(frame_info.span);
450493
err.note(format!("{frame_info} at {span}"));
451494
}
452495
}
453496

454-
err.emit();
497+
handler.emit_diagnostic(&mut err);
455498
}
456499

457500
impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {

src/eval.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,8 +422,9 @@ pub fn eval_entry<'tcx>(
422422
let mut ecx = match create_ecx(tcx, entry_id, entry_type, &config) {
423423
Ok(v) => v,
424424
Err(err) => {
425-
err.print_backtrace();
426-
panic!("Miri initialization error: {}", err.kind())
425+
let (kind, backtrace) = err.into_parts();
426+
backtrace.print_backtrace();
427+
panic!("Miri initialization error: {kind:?}")
427428
}
428429
};
429430

src/helpers.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
162162
let instance = this.resolve_path(path, Namespace::ValueNS);
163163
let cid = GlobalId { instance, promoted: None };
164164
// We don't give a span -- this isn't actually used directly by the program anyway.
165-
let const_val = this
166-
.eval_global(cid, None)
167-
.unwrap_or_else(|err| panic!("failed to evaluate required Rust item: {path:?}\n{err}"));
165+
let const_val = this.eval_global(cid, None).unwrap_or_else(|err| {
166+
panic!("failed to evaluate required Rust item: {path:?}\n{err:?}")
167+
});
168168
this.read_scalar(&const_val.into())
169-
.unwrap_or_else(|err| panic!("failed to read required Rust item: {path:?}\n{err}"))
169+
.unwrap_or_else(|err| panic!("failed to read required Rust item: {path:?}\n{err:?}"))
170170
}
171171

172172
/// Helper function to get a `libc` constant as a `Scalar`.

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343

4444
extern crate rustc_apfloat;
4545
extern crate rustc_ast;
46+
extern crate rustc_errors;
4647
#[macro_use]
4748
extern crate rustc_middle;
4849
extern crate rustc_const_eval;

tests/fail/intrinsics/copy_overlapping.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ fn main() {
1010
unsafe {
1111
let a = data.as_mut_ptr();
1212
let b = a.wrapping_offset(1) as *mut _;
13-
copy_nonoverlapping(a, b, 2); //~ ERROR: copy_nonoverlapping called on overlapping ranges
13+
copy_nonoverlapping(a, b, 2); //~ ERROR: `copy_nonoverlapping` called on overlapping ranges
1414
}
1515
}

tests/fail/intrinsics/copy_overlapping.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: Undefined Behavior: copy_nonoverlapping called on overlapping ranges
1+
error: Undefined Behavior: `copy_nonoverlapping` called on overlapping ranges
22
--> $DIR/copy_overlapping.rs:LL:CC
33
|
44
LL | copy_nonoverlapping(a, b, 2);
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ copy_nonoverlapping called on overlapping ranges
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `copy_nonoverlapping` called on overlapping ranges
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information

tests/fail/intrinsics/ptr_offset_from_oob.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: Undefined Behavior: out-of-bounds offset_from: ALLOC has size 4, so pointer at offset 10 is out-of-bounds
1+
error: Undefined Behavior: out-of-bounds `offset_from`: ALLOC has size 4, so pointer at offset 10 is out-of-bounds
22
--> $DIR/ptr_offset_from_oob.rs:LL:CC
33
|
44
LL | unsafe { end_ptr.offset_from(end_ptr) };
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: ALLOC has size 4, so pointer at offset 10 is out-of-bounds
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from`: ALLOC has size 4, so pointer at offset 10 is out-of-bounds
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information

tests/fail/modifying_constants.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// This should fail even without validation/SB
22
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
33

4+
#![allow(cast_ref_to_mut)]
5+
46
fn main() {
57
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
68
let y = unsafe { &mut *(x as *const i32 as *mut i32) };

tests/fail/stacked_borrows/shr_frozen_violation1.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![allow(cast_ref_to_mut)]
2+
13
fn foo(x: &mut i32) -> i32 {
24
*x = 5;
35
unknown_code(&*x);

0 commit comments

Comments
 (0)