@@ -8,6 +8,7 @@ use rand::SeedableRng;
8
8
use rustc_hir:: def_id:: DefId ;
9
9
use rustc:: ty:: layout:: { LayoutOf , Size } ;
10
10
use rustc:: ty:: { self , TyCtxt } ;
11
+ use rustc_mir:: interpret:: InterpErrorInfo ;
11
12
12
13
use crate :: * ;
13
14
@@ -205,64 +206,65 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) ->
205
206
}
206
207
return Some ( return_code) ;
207
208
}
208
- Err ( mut e) => {
209
- // Special treatment for some error kinds
210
- let msg = match e. kind {
211
- InterpError :: MachineStop ( ref info) => {
212
- let info = info
213
- . downcast_ref :: < TerminationInfo > ( )
214
- . expect ( "invalid MachineStop payload" ) ;
215
- match info {
216
- TerminationInfo :: Exit ( code) => return Some ( * code) ,
217
- TerminationInfo :: PoppedTrackedPointerTag ( item) =>
218
- format ! ( "popped tracked tag for item {:?}" , item) ,
219
- TerminationInfo :: Abort =>
220
- format ! ( "the evaluated program aborted execution" ) ,
221
- }
222
- }
223
- err_unsup ! ( NoMirFor ( ..) ) => format ! (
224
- "{}. Did you set `MIRI_SYSROOT` to a Miri-enabled sysroot? You can prepare one with `cargo miri setup`." ,
225
- e
226
- ) ,
227
- InterpError :: InvalidProgram ( _) =>
228
- bug ! ( "This error should be impossible in Miri: {}" , e) ,
229
- _ => e. to_string ( ) ,
230
- } ;
231
- e. print_backtrace ( ) ;
232
- if let Some ( frame) = ecx. stack ( ) . last ( ) {
233
- let span = frame. current_source_info ( ) . unwrap ( ) . span ;
209
+ Err ( e) => report_err ( & ecx, e) ,
210
+ }
211
+ }
234
212
235
- let msg = format ! ( "Miri evaluation error: {}" , msg) ;
236
- let mut err = ecx. tcx . sess . struct_span_err ( span, msg. as_str ( ) ) ;
237
- let frames = ecx. generate_stacktrace ( None ) ;
238
- err. span_label ( span, msg) ;
239
- // We iterate with indices because we need to look at the next frame (the caller).
240
- for idx in 0 ..frames. len ( ) {
241
- let frame_info = & frames[ idx] ;
242
- let call_site_is_local = frames
243
- . get ( idx + 1 )
244
- . map_or ( false , |caller_info| caller_info. instance . def_id ( ) . is_local ( ) ) ;
245
- if call_site_is_local {
246
- err. span_note ( frame_info. call_site , & frame_info. to_string ( ) ) ;
247
- } else {
248
- err. note ( & frame_info. to_string ( ) ) ;
249
- }
250
- }
251
- err. emit ( ) ;
252
- } else {
253
- ecx. tcx . sess . err ( & msg) ;
213
+ fn report_err < ' tcx , ' mir > (
214
+ ecx : & InterpCx < ' mir , ' tcx , Evaluator < ' tcx > > ,
215
+ mut e : InterpErrorInfo < ' tcx > ,
216
+ ) -> Option < i64 > {
217
+ // Special treatment for some error kinds
218
+ let msg = match e. kind {
219
+ InterpError :: MachineStop ( ref info) => {
220
+ let info = info. downcast_ref :: < TerminationInfo > ( ) . expect ( "invalid MachineStop payload" ) ;
221
+ match info {
222
+ TerminationInfo :: Exit ( code) => return Some ( * code) ,
223
+ TerminationInfo :: PoppedTrackedPointerTag ( item) =>
224
+ format ! ( "popped tracked tag for item {:?}" , item) ,
225
+ TerminationInfo :: Abort => format ! ( "the evaluated program aborted execution" ) ,
254
226
}
227
+ }
228
+ err_unsup ! ( NoMirFor ( ..) ) => format ! (
229
+ "{}. Did you set `MIRI_SYSROOT` to a Miri-enabled sysroot? You can prepare one with `cargo miri setup`." ,
230
+ e
231
+ ) ,
232
+ InterpError :: InvalidProgram ( _) => bug ! ( "This error should be impossible in Miri: {}" , e) ,
233
+ _ => e. to_string ( ) ,
234
+ } ;
235
+ e. print_backtrace ( ) ;
236
+ if let Some ( frame) = ecx. stack ( ) . last ( ) {
237
+ let span = frame. current_source_info ( ) . unwrap ( ) . span ;
255
238
256
- for ( i, frame) in ecx. stack ( ) . iter ( ) . enumerate ( ) {
257
- trace ! ( "-------------------" ) ;
258
- trace ! ( "Frame {}" , i) ;
259
- trace ! ( " return: {:?}" , frame. return_place. map( |p| * p) ) ;
260
- for ( i, local) in frame. locals . iter ( ) . enumerate ( ) {
261
- trace ! ( " local {}: {:?}" , i, local. value) ;
262
- }
239
+ let msg = format ! ( "Miri evaluation error: {}" , msg) ;
240
+ let mut err = ecx. tcx . sess . struct_span_err ( span, msg. as_str ( ) ) ;
241
+ let frames = ecx. generate_stacktrace ( None ) ;
242
+ err. span_label ( span, msg) ;
243
+ // We iterate with indices because we need to look at the next frame (the caller).
244
+ for idx in 0 ..frames. len ( ) {
245
+ let frame_info = & frames[ idx] ;
246
+ let call_site_is_local = frames
247
+ . get ( idx + 1 )
248
+ . map_or ( false , |caller_info| caller_info. instance . def_id ( ) . is_local ( ) ) ;
249
+ if call_site_is_local {
250
+ err. span_note ( frame_info. call_site , & frame_info. to_string ( ) ) ;
251
+ } else {
252
+ err. note ( & frame_info. to_string ( ) ) ;
263
253
}
264
- // Let the reported error determine the return code.
265
- return None ;
254
+ }
255
+ err. emit ( ) ;
256
+ } else {
257
+ ecx. tcx . sess . err ( & msg) ;
258
+ }
259
+
260
+ for ( i, frame) in ecx. stack ( ) . iter ( ) . enumerate ( ) {
261
+ trace ! ( "-------------------" ) ;
262
+ trace ! ( "Frame {}" , i) ;
263
+ trace ! ( " return: {:?}" , frame. return_place. map( |p| * p) ) ;
264
+ for ( i, local) in frame. locals . iter ( ) . enumerate ( ) {
265
+ trace ! ( " local {}: {:?}" , i, local. value) ;
266
266
}
267
267
}
268
+ // Let the reported error determine the return code.
269
+ return None ;
268
270
}
0 commit comments