Skip to content

Commit 54200a6

Browse files
committed
Auto merge of #3044 - rust-lang:rustup-2023-08-31, r=RalfJung
Automatic sync from rustc
2 parents 1890553 + c18eb93 commit 54200a6

File tree

6 files changed

+74
-65
lines changed

6 files changed

+74
-65
lines changed

rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
f3284dc3ad9254236d296daa1285dd273b492b01
1+
008c21c9779fd1e3632d9fe908b8afc0c421b26c

src/diagnostics.rs

Lines changed: 37 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
use std::fmt;
1+
use std::fmt::{self, Write};
22
use std::num::NonZeroU64;
33

44
use log::trace;
55

6-
use rustc_const_eval::ReportErrorExt;
76
use rustc_errors::DiagnosticMessage;
87
use rustc_span::{source_map::DUMMY_SP, SpanData, Symbol};
98
use rustc_target::abi::{Align, Size};
@@ -271,27 +270,30 @@ pub fn report_error<'tcx, 'mir>(
271270
};
272271
(title, helps)
273272
} else {
274-
#[rustfmt::skip]
275273
let title = match e.kind() {
276-
UndefinedBehavior(UndefinedBehaviorInfo::ValidationError(e)) if matches!(e.kind, ValidationErrorKind::PointerAsInt { .. } | ValidationErrorKind::PartialPointer) =>
277-
bug!("This validation error should be impossible in Miri: {:?}", e.kind),
278-
UndefinedBehavior(_) =>
279-
"Undefined Behavior",
280-
ResourceExhaustion(_) =>
281-
"resource exhaustion",
274+
UndefinedBehavior(UndefinedBehaviorInfo::ValidationError(validation_err))
275+
if matches!(
276+
validation_err.kind,
277+
ValidationErrorKind::PointerAsInt { .. } | ValidationErrorKind::PartialPointer
278+
) =>
279+
{
280+
ecx.handle_ice(); // print interpreter backtrace
281+
bug!("This validation error should be impossible in Miri: {}", ecx.format_error(e));
282+
}
283+
UndefinedBehavior(_) => "Undefined Behavior",
284+
ResourceExhaustion(_) => "resource exhaustion",
282285
Unsupported(
283286
// We list only the ones that can actually happen.
284-
UnsupportedOpInfo::Unsupported(_)
285-
) =>
286-
"unsupported operation",
287+
UnsupportedOpInfo::Unsupported(_) | UnsupportedOpInfo::UnsizedLocal,
288+
) => "unsupported operation",
287289
InvalidProgram(
288290
// We list only the ones that can actually happen.
289-
InvalidProgramInfo::AlreadyReported(_) |
290-
InvalidProgramInfo::Layout(..)
291-
) =>
292-
"post-monomorphization error",
293-
kind =>
294-
bug!("This error should be impossible in Miri: {kind:?}"),
291+
InvalidProgramInfo::AlreadyReported(_) | InvalidProgramInfo::Layout(..),
292+
) => "post-monomorphization error",
293+
_ => {
294+
ecx.handle_ice(); // print interpreter backtrace
295+
bug!("This error should be impossible in Miri: {}", ecx.format_error(e));
296+
}
295297
};
296298
#[rustfmt::skip]
297299
let helps = match e.kind() {
@@ -333,30 +335,23 @@ pub fn report_error<'tcx, 'mir>(
333335

334336
let stacktrace = ecx.generate_stacktrace();
335337
let (stacktrace, was_pruned) = prune_stacktrace(stacktrace, &ecx.machine);
336-
let (e, backtrace) = e.into_parts();
337-
backtrace.print_backtrace();
338-
339-
// We want to dump the allocation if this is `InvalidUninitBytes`. Since `add_args` consumes
340-
// the `InterpError`, we extract the variables it before that.
341-
let extra = match e {
342-
UndefinedBehavior(UndefinedBehaviorInfo::InvalidUninitBytes(Some((alloc_id, access)))) =>
343-
Some((alloc_id, access)),
344-
_ => None,
345-
};
346338

347-
// FIXME(fee1-dead), HACK: we want to use the error as title therefore we can just extract the
348-
// label and arguments from the InterpError.
349-
let e = {
350-
let handler = &ecx.tcx.sess.parse_sess.span_diagnostic;
351-
let mut diag = ecx.tcx.sess.struct_allow("");
352-
let msg = e.diagnostic_message();
353-
e.add_args(handler, &mut diag);
354-
let s = handler.eagerly_translate_to_string(msg, diag.args());
355-
diag.cancel();
356-
s
357-
};
339+
// We want to dump the allocation if this is `InvalidUninitBytes`. Since `format_error` consumes `e`, we compute the outut early.
340+
let mut extra = String::new();
341+
match e.kind() {
342+
UndefinedBehavior(UndefinedBehaviorInfo::InvalidUninitBytes(Some((alloc_id, access)))) => {
343+
writeln!(
344+
extra,
345+
"Uninitialized memory occurred at {alloc_id:?}{range:?}, in this allocation:",
346+
range = access.bad,
347+
)
348+
.unwrap();
349+
writeln!(extra, "{:?}", ecx.dump_alloc(*alloc_id)).unwrap();
350+
}
351+
_ => {}
352+
}
358353

359-
msg.insert(0, e);
354+
msg.insert(0, ecx.format_error(e));
360355

361356
report_msg(
362357
DiagLevel::Error,
@@ -375,6 +370,8 @@ pub fn report_error<'tcx, 'mir>(
375370
);
376371
}
377372

373+
eprint!("{extra}"); // newlines are already in the string
374+
378375
// Debug-dump all locals.
379376
for (i, frame) in ecx.active_thread_stack().iter().enumerate() {
380377
trace!("-------------------");
@@ -385,15 +382,6 @@ pub fn report_error<'tcx, 'mir>(
385382
}
386383
}
387384

388-
// Extra output to help debug specific issues.
389-
if let Some((alloc_id, access)) = extra {
390-
eprintln!(
391-
"Uninitialized memory occurred at {alloc_id:?}{range:?}, in this allocation:",
392-
range = access.bad,
393-
);
394-
eprintln!("{:?}", ecx.dump_alloc(alloc_id));
395-
}
396-
397385
None
398386
}
399387

src/helpers.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_middle::mir;
1414
use rustc_middle::ty::{
1515
self,
1616
layout::{IntegerExt as _, LayoutOf, TyAndLayout},
17-
List, Ty, TyCtxt,
17+
Ty, TyCtxt,
1818
};
1919
use rustc_span::{def_id::CrateNum, sym, Span, Symbol};
2020
use rustc_target::abi::{Align, FieldIdx, FieldsShape, Integer, Size, Variants};
@@ -282,13 +282,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
282282
Ok(ptr.addr().bytes() == 0)
283283
}
284284

285-
/// Get the `Place` for a local
286-
fn local_place(&self, local: mir::Local) -> InterpResult<'tcx, PlaceTy<'tcx, Provenance>> {
287-
let this = self.eval_context_ref();
288-
let place = mir::Place { local, projection: List::empty() };
289-
this.eval_place(place)
290-
}
291-
292285
/// Generate some random bytes, and write them to `dest`.
293286
fn gen_random(&mut self, ptr: Pointer<Option<Provenance>>, len: u64) -> InterpResult<'tcx> {
294287
// Some programs pass in a null pointer and a length of 0
@@ -350,17 +343,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
350343
// Initialize arguments.
351344
let mut callee_args = this.frame().body.args_iter();
352345
for arg in args {
353-
let callee_arg = this.local_place(
354-
callee_args
355-
.next()
356-
.ok_or_else(|| err_ub_format!("callee has fewer arguments than expected"))?,
357-
)?;
346+
let local = callee_args
347+
.next()
348+
.ok_or_else(|| err_ub_format!("callee has fewer arguments than expected"))?;
349+
// Make the local live, and insert the initial value.
350+
this.storage_live(local)?;
351+
let callee_arg = this.local_to_place(this.frame_idx(), local)?;
358352
this.write_immediate(*arg, &callee_arg)?;
359353
}
360354
if callee_args.next().is_some() {
361355
throw_ub_format!("callee has more arguments than expected");
362356
}
363357

358+
// Initialize remaining locals.
359+
this.storage_live_for_always_live_locals()?;
360+
364361
Ok(())
365362
}
366363

tests/fail/type-too-large.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@ignore-32bit
22

33
fn main() {
4-
let _fat: [u8; (1 << 61) + (1 << 31)];
4+
let _fat: [u8; (1 << 61) + (1 << 31)]; // ideally we'd error here, but we avoid computing the layout until absolutely necessary
55
_fat = [0; (1u64 << 61) as usize + (1u64 << 31) as usize]; //~ ERROR: post-monomorphization error
66
}

tests/fail/unsized-local.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: unsupported operation: unsized locals are not supported
22
--> $DIR/unsized-local.rs:LL:CC
33
|
44
LL | let x = *(Box::new(A) as Box<dyn Foo>);
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsized locals are not supported
5+
| ^ unsized locals are not supported
66
|
77
= help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support
88
= note: BACKTRACE:

tests/pass/unsized.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//@[tree]compile-flags: -Zmiri-tree-borrows
33
#![feature(unsized_tuple_coercion)]
44
#![feature(unsized_fn_params)]
5+
#![feature(custom_mir, core_intrinsics)]
56

67
use std::mem;
78

@@ -32,7 +33,30 @@ fn unsized_params() {
3233
f3(*p);
3334
}
3435

36+
fn unsized_field_projection() {
37+
use std::intrinsics::mir::*;
38+
39+
pub struct S<T: ?Sized>(T);
40+
41+
#[custom_mir(dialect = "runtime", phase = "optimized")]
42+
fn f(x: S<[u8]>) {
43+
mir! {
44+
{
45+
let idx = 0;
46+
// Project to an unsized field of an unsized local.
47+
x.0[idx] = 0;
48+
let _val = x.0[idx];
49+
Return()
50+
}
51+
}
52+
}
53+
54+
let x: Box<S<[u8]>> = Box::new(S([0]));
55+
f(*x);
56+
}
57+
3558
fn main() {
3659
unsized_tuple();
3760
unsized_params();
61+
unsized_field_projection();
3862
}

0 commit comments

Comments
 (0)