]> git.lizzy.rs Git - rust.git/commitdiff
implement exit
authorRalf Jung <post@ralfj.de>
Fri, 19 Apr 2019 15:25:27 +0000 (17:25 +0200)
committerRalf Jung <post@ralfj.de>
Sun, 21 Apr 2019 10:36:17 +0000 (12:36 +0200)
implement exit code via new error kind

rust-version
src/fn_call.rs
src/lib.rs
tests/run-pass/exit.rs [new file with mode: 0644]

index f0c4e551b3a5804143d913fa9de0e5036fc9526d..fae9b1d599a424000608c34bbf0c768a5e54d8c3 100644 (file)
@@ -1 +1 @@
-130dc3e7dac132cf30272ccf4541b512828e2108
+9224be5fa39f6170f6e046342976efee5453a1ff
index ae6aff10ac209728a85fb244e787fd19cf757709..2f827510aa5d032c42f8084e34349f9756fcc296 100644 (file)
@@ -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),
index 3dbe922999dabcc77a2be19bc4a407ec77243be5..683eee0cb7a381862f61f876d026d75b20711418 100644 (file)
@@ -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 (file)
index 0000000..d93f004
--- /dev/null
@@ -0,0 +1,3 @@
+fn main() {
+    std::process::exit(0)
+}