@@ -1417,6 +1417,15 @@ impl From<fs::File> for Stdio {
14171417/// For proper error reporting of failed processes, print the value of `ExitStatus` or
14181418/// `ExitStatusError` using their implementations of [`Display`](crate::fmt::Display).
14191419///
1420+ /// # Differences from `ExitStatus`
1421+ ///
1422+ /// `ExitCode` is intended for terminating the currently running process, via
1423+ /// the `Termination` trait, in contrast to [`ExitStatus`], which represents the
1424+ /// termination of a child process. These APIs are separate due to platform
1425+ /// compatibility differences and their expected usage; it is not generally
1426+ /// possible to exactly reproduce an ExitStatus from a child for the current
1427+ /// process after the fact.
1428+ ///
14201429/// [`status`]: Command::status
14211430/// [`wait`]: Child::wait
14221431//
@@ -1649,8 +1658,16 @@ impl fmt::Display for ExitStatusError {
16491658#[ unstable( feature = "exit_status_error" , issue = "84908" ) ]
16501659impl crate :: error:: Error for ExitStatusError { }
16511660
1652- /// This type represents the status code a process can return to its
1653- /// parent under normal termination.
1661+ /// This type represents the status code the current process can return
1662+ /// to its parent under normal termination.
1663+ ///
1664+ /// `ExitCode` is intended to be consumed only by the standard library (via
1665+ /// [`Termination::report()`]), and intentionally does not provide accessors like
1666+ /// `PartialEq`, `Eq`, or `Hash`. Instead the standard library provides the
1667+ /// canonical `SUCCESS` and `FAILURE` exit codes as well as `From<u8> for
1668+ /// ExitCode` for constructing other arbitrary exit codes.
1669+ ///
1670+ /// # Portability
16541671///
16551672/// Numeric values used in this type don't have portable meanings, and
16561673/// different platforms may mask different amounts of them.
@@ -1661,52 +1678,78 @@ impl crate::error::Error for ExitStatusError {}
16611678/// [`SUCCESS`]: ExitCode::SUCCESS
16621679/// [`FAILURE`]: ExitCode::FAILURE
16631680///
1664- /// **Warning**: While various forms of this were discussed in [RFC #1937],
1665- /// it was ultimately cut from that RFC, and thus this type is more subject
1666- /// to change even than the usual unstable item churn.
1681+ /// # Differences from `ExitStatus`
1682+ ///
1683+ /// `ExitCode` is intended for terminating the currently running process, via
1684+ /// the `Termination` trait, in contrast to [`ExitStatus`], which represents the
1685+ /// termination of a child process. These APIs are separate due to platform
1686+ /// compatibility differences and their expected usage; it is not generally
1687+ /// possible to exactly reproduce an ExitStatus from a child for the current
1688+ /// process after the fact.
1689+ ///
1690+ /// # Examples
1691+ ///
1692+ /// `ExitCode` can be returned from the `main` function of a crate, as it implements
1693+ /// [`Termination`]:
1694+ ///
1695+ /// ```
1696+ /// use std::process::ExitCode;
1697+ /// # fn check_foo() -> bool { true }
16671698///
1668- /// [RFC #1937]: https://github.com/rust-lang/rfcs/pull/1937
1699+ /// fn main() -> ExitCode {
1700+ /// if !check_foo() {
1701+ /// return ExitCode::from(42);
1702+ /// }
1703+ ///
1704+ /// ExitCode::SUCCESS
1705+ /// }
1706+ /// ```
16691707#[ derive( Clone , Copy , Debug ) ]
1670- #[ unstable ( feature = "process_exitcode_placeholder " , issue = "48711 " ) ]
1708+ #[ stable ( feature = "process_exitcode " , since = "1.60.0 " ) ]
16711709pub struct ExitCode ( imp:: ExitCode ) ;
16721710
1673- #[ unstable ( feature = "process_exitcode_placeholder " , issue = "48711 " ) ]
1711+ #[ stable ( feature = "process_exitcode " , since = "1.60.0 " ) ]
16741712impl ExitCode {
1675- /// The canonical ExitCode for successful termination on this platform.
1713+ /// The canonical ` ExitCode` for successful termination on this platform.
16761714 ///
16771715 /// Note that a `()`-returning `main` implicitly results in a successful
16781716 /// termination, so there's no need to return this from `main` unless
16791717 /// you're also returning other possible codes.
1680- #[ unstable ( feature = "process_exitcode_placeholder " , issue = "48711 " ) ]
1718+ #[ stable ( feature = "process_exitcode " , since = "1.60.0 " ) ]
16811719 pub const SUCCESS : ExitCode = ExitCode ( imp:: ExitCode :: SUCCESS ) ;
16821720
1683- /// The canonical ExitCode for unsuccessful termination on this platform.
1721+ /// The canonical ` ExitCode` for unsuccessful termination on this platform.
16841722 ///
16851723 /// If you're only returning this and `SUCCESS` from `main`, consider
16861724 /// instead returning `Err(_)` and `Ok(())` respectively, which will
16871725 /// return the same codes (but will also `eprintln!` the error).
1688- #[ unstable ( feature = "process_exitcode_placeholder " , issue = "48711 " ) ]
1726+ #[ stable ( feature = "process_exitcode " , since = "1.60.0 " ) ]
16891727 pub const FAILURE : ExitCode = ExitCode ( imp:: ExitCode :: FAILURE ) ;
16901728}
16911729
16921730impl ExitCode {
1693- // This should not be stabilized when stabilizing ExitCode, we don't know that i32 will serve
1731+ // This is private/perma-unstable because ExitCode is opaque; we don't know that i32 will serve
16941732 // all usecases, for example windows seems to use u32, unix uses the 8-15th bits of an i32, we
16951733 // likely want to isolate users anything that could restrict the platform specific
16961734 // representation of an ExitCode
16971735 //
16981736 // More info: https://internals.rust-lang.org/t/mini-pre-rfc-redesigning-process-exitstatus/5426
1699- /// Convert an ExitCode into an i32
1700- #[ unstable( feature = "process_exitcode_placeholder" , issue = "48711" ) ]
1737+ /// Convert an `ExitCode` into an i32
1738+ #[ unstable(
1739+ feature = "process_exitcode_internals" ,
1740+ reason = "exposed only for libstd" ,
1741+ issue = "none"
1742+ ) ]
17011743 #[ inline]
1744+ #[ doc( hidden) ]
17021745 pub fn to_i32 ( self ) -> i32 {
17031746 self . 0 . as_i32 ( )
17041747 }
17051748}
17061749
1707- #[ unstable ( feature = "process_exitcode_placeholder " , issue = "48711 " ) ]
1750+ #[ stable ( feature = "process_exitcode " , since = "1.60.0 " ) ]
17081751impl From < u8 > for ExitCode {
1709- /// Construct an exit code from an arbitrary u8 value.
1752+ /// Construct an `ExitCode` from an arbitrary u8 value.
17101753 fn from ( code : u8 ) -> Self {
17111754 ExitCode ( imp:: ExitCode :: from ( code) )
17121755 }
@@ -2049,26 +2092,27 @@ pub fn id() -> u32 {
20492092/// standard library's runtime for convenience. Other runtimes are not required
20502093/// to provide similar functionality.
20512094#[ cfg_attr( not( test) , lang = "termination" ) ]
2052- #[ unstable ( feature = "termination_trait_lib" , issue = "43301 " ) ]
2095+ #[ stable ( feature = "termination_trait_lib" , since = "1.60.0 " ) ]
20532096#[ rustc_on_unimplemented(
20542097 message = "`main` has invalid return type `{Self}`" ,
20552098 label = "`main` can only return types that implement `{Termination}`"
20562099) ]
20572100pub trait Termination {
20582101 /// Is called to get the representation of the value as status code.
20592102 /// This status code is returned to the operating system.
2103+ #[ stable( feature = "termination_trait_lib" , since = "1.60.0" ) ]
20602104 fn report ( self ) -> ExitCode ;
20612105}
20622106
2063- #[ unstable ( feature = "termination_trait_lib" , issue = "43301 " ) ]
2107+ #[ stable ( feature = "termination_trait_lib" , since = "1.60.0 " ) ]
20642108impl Termination for ( ) {
20652109 #[ inline]
20662110 fn report ( self ) -> ExitCode {
20672111 ExitCode :: SUCCESS . report ( )
20682112 }
20692113}
20702114
2071- #[ unstable ( feature = "termination_trait_lib" , issue = "43301 " ) ]
2115+ #[ stable ( feature = "termination_trait_lib" , since = "1.60.0 " ) ]
20722116impl < E : fmt:: Debug > Termination for Result < ( ) , E > {
20732117 fn report ( self ) -> ExitCode {
20742118 match self {
@@ -2078,14 +2122,14 @@ impl<E: fmt::Debug> Termination for Result<(), E> {
20782122 }
20792123}
20802124
2081- #[ unstable ( feature = "termination_trait_lib" , issue = "43301 " ) ]
2125+ #[ stable ( feature = "termination_trait_lib" , since = "1.60.0 " ) ]
20822126impl Termination for ! {
20832127 fn report ( self ) -> ExitCode {
20842128 self
20852129 }
20862130}
20872131
2088- #[ unstable ( feature = "termination_trait_lib" , issue = "43301 " ) ]
2132+ #[ stable ( feature = "termination_trait_lib" , since = "1.60.0 " ) ]
20892133impl < E : fmt:: Debug > Termination for Result < !, E > {
20902134 fn report ( self ) -> ExitCode {
20912135 let Err ( err) = self ;
@@ -2094,15 +2138,15 @@ impl<E: fmt::Debug> Termination for Result<!, E> {
20942138 }
20952139}
20962140
2097- #[ unstable ( feature = "termination_trait_lib" , issue = "43301 " ) ]
2141+ #[ stable ( feature = "termination_trait_lib" , since = "1.60.0 " ) ]
20982142impl < E : fmt:: Debug > Termination for Result < Infallible , E > {
20992143 fn report ( self ) -> ExitCode {
21002144 let Err ( err) = self ;
21012145 Err :: < !, _ > ( err) . report ( )
21022146 }
21032147}
21042148
2105- #[ unstable ( feature = "termination_trait_lib" , issue = "43301 " ) ]
2149+ #[ stable ( feature = "termination_trait_lib" , since = "1.60.0 " ) ]
21062150impl Termination for ExitCode {
21072151 #[ inline]
21082152 fn report ( self ) -> ExitCode {
0 commit comments