@@ -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,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
89109pub 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
457500impl < ' mir , ' tcx > MiriMachine < ' mir , ' tcx > {
0 commit comments