@@ -3,6 +3,8 @@ use std::num::NonZeroU64;
33
44use log:: trace;
55
6+ use rustc_const_eval:: ReportErrorExt ;
7+ use rustc_errors:: DiagnosticMessage ;
68use rustc_span:: { source_map:: DUMMY_SP , SpanData , Symbol } ;
79use rustc_target:: abi:: { Align , Size } ;
810
@@ -83,7 +85,21 @@ 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 ( std:: borrow:: Cow < ' static , str > , rustc_errors:: DiagnosticArgValue < ' static > ) ,
101+ ) { }
102+ }
87103
88104/// Miri specific diagnostics
89105pub enum NonHaltingDiagnostic {
@@ -302,8 +318,32 @@ pub fn report_error<'tcx, 'mir>(
302318
303319 let stacktrace = ecx. generate_stacktrace ( ) ;
304320 let ( stacktrace, was_pruned) = prune_stacktrace ( stacktrace, & ecx. machine ) ;
305- e. print_backtrace ( ) ;
306- msg. insert ( 0 , e. to_string ( ) ) ;
321+ let ( e, backtrace) = e. into_parts ( ) ;
322+ backtrace. print_backtrace ( ) ;
323+
324+ // We want to dump the allocation if this is `InvalidUninitBytes`. Since `add_args` consumes
325+ // the `InterpError`, we extract the variables it before that.
326+ let extra = match e {
327+ UndefinedBehavior ( UndefinedBehaviorInfo :: InvalidUninitBytes ( Some ( ( alloc_id, access) ) ) ) => {
328+ Some ( ( alloc_id, access) )
329+ }
330+ _ => None
331+ } ;
332+
333+ // FIXME(fee1-dead), HACK: we want to use the error as title therefore we can just extract the
334+ // label and arguments from the InterpError.
335+ let e = {
336+ let handler = & ecx. tcx . sess . parse_sess . span_diagnostic ;
337+ let mut diag = ecx. tcx . sess . struct_allow ( "" ) ;
338+ let msg = e. diagnostic_message ( ) ;
339+ e. add_args ( handler, & mut diag) ;
340+ let s = handler. eagerly_translate_to_string ( msg, diag. args ( ) ) ;
341+ diag. cancel ( ) ;
342+ s
343+ } ;
344+
345+ msg. insert ( 0 , e) ;
346+
307347 report_msg (
308348 DiagLevel :: Error ,
309349 if let Some ( title) = title { format ! ( "{title}: {}" , msg[ 0 ] ) } else { msg[ 0 ] . clone ( ) } ,
@@ -332,15 +372,12 @@ pub fn report_error<'tcx, 'mir>(
332372 }
333373
334374 // 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- _ => { }
375+ if let Some ( ( alloc_id, access) ) = extra {
376+ eprintln ! (
377+ "Uninitialized memory occurred at {alloc_id:?}{range:?}, in this allocation:" ,
378+ range = access. uninit,
379+ ) ;
380+ eprintln ! ( "{:?}" , ecx. dump_alloc( alloc_id) ) ;
344381 }
345382
346383 None
@@ -438,20 +475,23 @@ pub fn report_msg<'tcx>(
438475 // Add visual separator before backtrace.
439476 err. note ( if extra_span { "BACKTRACE (of the first span):" } else { "BACKTRACE:" } ) ;
440477 }
478+
479+ let ( mut err, handler) = err. into_diagnostic ( ) . unwrap ( ) ;
480+
441481 // Add backtrace
442482 for ( idx, frame_info) in stacktrace. iter ( ) . enumerate ( ) {
443483 let is_local = machine. is_local ( frame_info) ;
444484 // No span for non-local frames and the first frame (which is the error site).
445485 if is_local && idx > 0 {
446- err. span_note ( frame_info . span , frame_info. to_string ( ) ) ;
486+ err. eager_subdiagnostic ( handler , frame_info. as_note ( machine . tcx ) ) ;
447487 } else {
448488 let sm = sess. source_map ( ) ;
449489 let span = sm. span_to_embeddable_string ( frame_info. span ) ;
450490 err. note ( format ! ( "{frame_info} at {span}" ) ) ;
451491 }
452492 }
453493
454- err . emit ( ) ;
494+ handler . emit_diagnostic ( & mut err ) ;
455495}
456496
457497impl < ' mir , ' tcx > MiriMachine < ' mir , ' tcx > {
0 commit comments