From 0694435650adbd5965a30a14771bc142919bbfe4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 19 Apr 2019 17:25:27 +0200 Subject: [PATCH] implement exit implement exit code via new error kind --- rust-version | 2 +- src/fn_call.rs | 6 +++++- src/lib.rs | 14 ++++++++++---- tests/run-pass/exit.rs | 3 +++ 4 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 tests/run-pass/exit.rs diff --git a/rust-version b/rust-version index f0c4e551b3a..fae9b1d599a 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -130dc3e7dac132cf30272ccf4541b512828e2108 +9224be5fa39f6170f6e046342976efee5453a1ff diff --git a/src/fn_call.rs b/src/fn_call.rs index ae6aff10ac2..2f827510aa5 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -69,11 +69,15 @@ fn emulate_foreign_item( let link_name = link_name.get().trim_end_matches("$UNIX2003"); let tcx = &{this.tcx.tcx}; - // First: functions that could diverge. + // First: functions that diverge. match link_name { "__rust_start_panic" | "panic_impl" => { return err!(MachineError("the evaluated program panicked".to_string())); } + "exit" => { + let code = this.read_scalar(args[0])?.to_i32()?; + return err!(Exit(code)); + } _ => if dest.is_none() { return err!(Unimplemented( format!("can't call diverging foreign function: {}", link_name), diff --git a/src/lib.rs b/src/lib.rs index 3dbe922999d..683eee0cb7a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -242,6 +242,13 @@ pub fn eval_main<'a, 'tcx: 'a>( } } Err(mut e) => { + // Special treatment for some error kinds + let msg = match e.kind { + InterpError::Exit(code) => std::process::exit(code), + InterpError::NoMirFor(..) => + format!("{}. Did you set `MIRI_SYSROOT` to a Miri-enabled sysroot? You can prepare one with `cargo miri setup`.", e), + _ => e.to_string() + }; e.print_backtrace(); if let Some(frame) = ecx.stack().last() { let block = &frame.mir.basic_blocks()[frame.block]; @@ -251,11 +258,10 @@ pub fn eval_main<'a, 'tcx: 'a>( block.terminator().source_info.span }; - let e = e.to_string(); - let msg = format!("constant evaluation error: {}", e); + let msg = format!("Miri evaluation error: {}", msg); let mut err = struct_error(ecx.tcx.tcx.at(span), msg.as_str()); let frames = ecx.generate_stacktrace(None); - err.span_label(span, e); + err.span_label(span, msg); // We iterate with indices because we need to look at the next frame (the caller). for idx in 0..frames.len() { let frame_info = &frames[idx]; @@ -269,7 +275,7 @@ pub fn eval_main<'a, 'tcx: 'a>( } err.emit(); } else { - ecx.tcx.sess.err(&e.to_string()); + ecx.tcx.sess.err(&msg); } for (i, frame) in ecx.stack().iter().enumerate() { diff --git a/tests/run-pass/exit.rs b/tests/run-pass/exit.rs new file mode 100644 index 00000000000..d93f0045377 --- /dev/null +++ b/tests/run-pass/exit.rs @@ -0,0 +1,3 @@ +fn main() { + std::process::exit(0) +} -- 2.44.0