about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-02-01 20:05:46 +0000
committerbors <bors@rust-lang.org>2022-02-01 20:05:46 +0000
commit2681f253bcdb31a274411d2be456e7c6a1c67d62 (patch)
tree95871f05db9a870432432e2031837cd6f85dbb4f
parentad88831cd50ffe9cb9006bbdcb7fc9d97142e410 (diff)
parent19db85d6cdd6eade43461dfa75318215c720444b (diff)
downloadrust-2681f253bcdb31a274411d2be456e7c6a1c67d62.tar.gz
rust-2681f253bcdb31a274411d2be456e7c6a1c67d62.zip
Auto merge of #93442 - yaahc:Termination-abstraction, r=Mark-Simulacrum
Change Termination::report return type to ExitCode

Related to https://github.com/rust-lang/rust/issues/43301

The goal of this change is to minimize the forward compatibility risks in stabilizing Termination. By using the opaque type `ExitCode` instead of an `i32` we leave room for us to evolve the API over time to provide what cross-platform consistency we can / minimize footguns when working with exit codes, where as stabilizing on `i32` would limit what changes we could make in the future in how we represent and construct exit codes.
-rw-r--r--library/std/src/process.rs31
-rw-r--r--library/std/src/rt.rs2
-rw-r--r--library/test/src/lib.rs3
3 files changed, 26 insertions, 10 deletions
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index e012594dd46..7d7e08a7149 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -1676,6 +1676,21 @@ impl ExitCode {
     pub const FAILURE: ExitCode = ExitCode(imp::ExitCode::FAILURE);
 }
 
+impl ExitCode {
+    // This should not be stabilized when stabilizing ExitCode, we don't know that i32 will serve
+    // all usecases, for example windows seems to use u32, unix uses the 8-15th bits of an i32, we
+    // likely want to isolate users anything that could restrict the platform specific
+    // representation of an ExitCode
+    //
+    // More info: https://internals.rust-lang.org/t/mini-pre-rfc-redesigning-process-exitstatus/5426
+    /// Convert an ExitCode into an i32
+    #[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
+    #[inline]
+    pub fn to_i32(self) -> i32 {
+        self.0.as_i32()
+    }
+}
+
 impl Child {
     /// Forces the child process to exit. If the child has already exited, an [`InvalidInput`]
     /// error is returned.
@@ -2016,20 +2031,20 @@ pub fn id() -> u32 {
 pub trait Termination {
     /// Is called to get the representation of the value as status code.
     /// This status code is returned to the operating system.
-    fn report(self) -> i32;
+    fn report(self) -> ExitCode;
 }
 
 #[unstable(feature = "termination_trait_lib", issue = "43301")]
 impl Termination for () {
     #[inline]
-    fn report(self) -> i32 {
+    fn report(self) -> ExitCode {
         ExitCode::SUCCESS.report()
     }
 }
 
 #[unstable(feature = "termination_trait_lib", issue = "43301")]
 impl<E: fmt::Debug> Termination for Result<(), E> {
-    fn report(self) -> i32 {
+    fn report(self) -> ExitCode {
         match self {
             Ok(()) => ().report(),
             Err(err) => Err::<!, _>(err).report(),
@@ -2039,14 +2054,14 @@ impl<E: fmt::Debug> Termination for Result<(), E> {
 
 #[unstable(feature = "termination_trait_lib", issue = "43301")]
 impl Termination for ! {
-    fn report(self) -> i32 {
+    fn report(self) -> ExitCode {
         self
     }
 }
 
 #[unstable(feature = "termination_trait_lib", issue = "43301")]
 impl<E: fmt::Debug> Termination for Result<!, E> {
-    fn report(self) -> i32 {
+    fn report(self) -> ExitCode {
         let Err(err) = self;
         eprintln!("Error: {:?}", err);
         ExitCode::FAILURE.report()
@@ -2055,7 +2070,7 @@ impl<E: fmt::Debug> Termination for Result<!, E> {
 
 #[unstable(feature = "termination_trait_lib", issue = "43301")]
 impl<E: fmt::Debug> Termination for Result<Infallible, E> {
-    fn report(self) -> i32 {
+    fn report(self) -> ExitCode {
         let Err(err) = self;
         Err::<!, _>(err).report()
     }
@@ -2064,7 +2079,7 @@ impl<E: fmt::Debug> Termination for Result<Infallible, E> {
 #[unstable(feature = "termination_trait_lib", issue = "43301")]
 impl Termination for ExitCode {
     #[inline]
-    fn report(self) -> i32 {
-        self.0.as_i32()
+    fn report(self) -> ExitCode {
+        self
     }
 }
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index 08e58257572..663537a05fa 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -142,7 +142,7 @@ fn lang_start<T: crate::process::Termination + 'static>(
     argv: *const *const u8,
 ) -> isize {
     let Ok(v) = lang_start_internal(
-        &move || crate::sys_common::backtrace::__rust_begin_short_backtrace(main).report(),
+        &move || crate::sys_common::backtrace::__rust_begin_short_backtrace(main).report().to_i32(),
         argc,
         argv,
     );
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index fad83094cdf..8fc2b4ed748 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -20,6 +20,7 @@
 #![feature(internal_output_capture)]
 #![feature(staged_api)]
 #![feature(termination_trait_lib)]
+#![feature(process_exitcode_placeholder)]
 #![feature(test)]
 #![feature(total_cmp)]
 
@@ -182,7 +183,7 @@ fn make_owned_test(test: &&TestDescAndFn) -> TestDescAndFn {
 /// Tests is considered a failure. By default, invokes `report()`
 /// and checks for a `0` result.
 pub fn assert_test_result<T: Termination>(result: T) {
-    let code = result.report();
+    let code = result.report().to_i32();
     assert_eq!(
         code, 0,
         "the test returned a termination value with a non-zero status code ({}) \