@@ -1417,6 +1417,15 @@ impl From<fs::File> for Stdio {
1417
1417
/// For proper error reporting of failed processes, print the value of `ExitStatus` or
1418
1418
/// `ExitStatusError` using their implementations of [`Display`](crate::fmt::Display).
1419
1419
///
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
+ ///
1420
1429
/// [`status`]: Command::status
1421
1430
/// [`wait`]: Child::wait
1422
1431
//
@@ -1649,8 +1658,16 @@ impl fmt::Display for ExitStatusError {
1649
1658
#[ unstable( feature = "exit_status_error" , issue = "84908" ) ]
1650
1659
impl crate :: error:: Error for ExitStatusError { }
1651
1660
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
1654
1671
///
1655
1672
/// Numeric values used in this type don't have portable meanings, and
1656
1673
/// different platforms may mask different amounts of them.
@@ -1661,52 +1678,78 @@ impl crate::error::Error for ExitStatusError {}
1661
1678
/// [`SUCCESS`]: ExitCode::SUCCESS
1662
1679
/// [`FAILURE`]: ExitCode::FAILURE
1663
1680
///
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 }
1667
1698
///
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
+ /// ```
1669
1707
#[ derive( Clone , Copy , Debug ) ]
1670
- #[ unstable ( feature = "process_exitcode_placeholder " , issue = "48711 " ) ]
1708
+ #[ stable ( feature = "process_exitcode " , since = "1.60.0 " ) ]
1671
1709
pub struct ExitCode ( imp:: ExitCode ) ;
1672
1710
1673
- #[ unstable ( feature = "process_exitcode_placeholder " , issue = "48711 " ) ]
1711
+ #[ stable ( feature = "process_exitcode " , since = "1.60.0 " ) ]
1674
1712
impl ExitCode {
1675
- /// The canonical ExitCode for successful termination on this platform.
1713
+ /// The canonical ` ExitCode` for successful termination on this platform.
1676
1714
///
1677
1715
/// Note that a `()`-returning `main` implicitly results in a successful
1678
1716
/// termination, so there's no need to return this from `main` unless
1679
1717
/// you're also returning other possible codes.
1680
- #[ unstable ( feature = "process_exitcode_placeholder " , issue = "48711 " ) ]
1718
+ #[ stable ( feature = "process_exitcode " , since = "1.60.0 " ) ]
1681
1719
pub const SUCCESS : ExitCode = ExitCode ( imp:: ExitCode :: SUCCESS ) ;
1682
1720
1683
- /// The canonical ExitCode for unsuccessful termination on this platform.
1721
+ /// The canonical ` ExitCode` for unsuccessful termination on this platform.
1684
1722
///
1685
1723
/// If you're only returning this and `SUCCESS` from `main`, consider
1686
1724
/// instead returning `Err(_)` and `Ok(())` respectively, which will
1687
1725
/// 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 " ) ]
1689
1727
pub const FAILURE : ExitCode = ExitCode ( imp:: ExitCode :: FAILURE ) ;
1690
1728
}
1691
1729
1692
1730
impl 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
1694
1732
// all usecases, for example windows seems to use u32, unix uses the 8-15th bits of an i32, we
1695
1733
// likely want to isolate users anything that could restrict the platform specific
1696
1734
// representation of an ExitCode
1697
1735
//
1698
1736
// 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
+ ) ]
1701
1743
#[ inline]
1744
+ #[ doc( hidden) ]
1702
1745
pub fn to_i32 ( self ) -> i32 {
1703
1746
self . 0 . as_i32 ( )
1704
1747
}
1705
1748
}
1706
1749
1707
- #[ unstable ( feature = "process_exitcode_placeholder " , issue = "48711 " ) ]
1750
+ #[ stable ( feature = "process_exitcode " , since = "1.60.0 " ) ]
1708
1751
impl From < u8 > for ExitCode {
1709
- /// Construct an exit code from an arbitrary u8 value.
1752
+ /// Construct an `ExitCode` from an arbitrary u8 value.
1710
1753
fn from ( code : u8 ) -> Self {
1711
1754
ExitCode ( imp:: ExitCode :: from ( code) )
1712
1755
}
@@ -2049,26 +2092,27 @@ pub fn id() -> u32 {
2049
2092
/// standard library's runtime for convenience. Other runtimes are not required
2050
2093
/// to provide similar functionality.
2051
2094
#[ cfg_attr( not( test) , lang = "termination" ) ]
2052
- #[ unstable ( feature = "termination_trait_lib" , issue = "43301 " ) ]
2095
+ #[ stable ( feature = "termination_trait_lib" , since = "1.60.0 " ) ]
2053
2096
#[ rustc_on_unimplemented(
2054
2097
message = "`main` has invalid return type `{Self}`" ,
2055
2098
label = "`main` can only return types that implement `{Termination}`"
2056
2099
) ]
2057
2100
pub trait Termination {
2058
2101
/// Is called to get the representation of the value as status code.
2059
2102
/// This status code is returned to the operating system.
2103
+ #[ stable( feature = "termination_trait_lib" , since = "1.60.0" ) ]
2060
2104
fn report ( self ) -> ExitCode ;
2061
2105
}
2062
2106
2063
- #[ unstable ( feature = "termination_trait_lib" , issue = "43301 " ) ]
2107
+ #[ stable ( feature = "termination_trait_lib" , since = "1.60.0 " ) ]
2064
2108
impl Termination for ( ) {
2065
2109
#[ inline]
2066
2110
fn report ( self ) -> ExitCode {
2067
2111
ExitCode :: SUCCESS . report ( )
2068
2112
}
2069
2113
}
2070
2114
2071
- #[ unstable ( feature = "termination_trait_lib" , issue = "43301 " ) ]
2115
+ #[ stable ( feature = "termination_trait_lib" , since = "1.60.0 " ) ]
2072
2116
impl < E : fmt:: Debug > Termination for Result < ( ) , E > {
2073
2117
fn report ( self ) -> ExitCode {
2074
2118
match self {
@@ -2078,14 +2122,14 @@ impl<E: fmt::Debug> Termination for Result<(), E> {
2078
2122
}
2079
2123
}
2080
2124
2081
- #[ unstable ( feature = "termination_trait_lib" , issue = "43301 " ) ]
2125
+ #[ stable ( feature = "termination_trait_lib" , since = "1.60.0 " ) ]
2082
2126
impl Termination for ! {
2083
2127
fn report ( self ) -> ExitCode {
2084
2128
self
2085
2129
}
2086
2130
}
2087
2131
2088
- #[ unstable ( feature = "termination_trait_lib" , issue = "43301 " ) ]
2132
+ #[ stable ( feature = "termination_trait_lib" , since = "1.60.0 " ) ]
2089
2133
impl < E : fmt:: Debug > Termination for Result < !, E > {
2090
2134
fn report ( self ) -> ExitCode {
2091
2135
let Err ( err) = self ;
@@ -2094,15 +2138,15 @@ impl<E: fmt::Debug> Termination for Result<!, E> {
2094
2138
}
2095
2139
}
2096
2140
2097
- #[ unstable ( feature = "termination_trait_lib" , issue = "43301 " ) ]
2141
+ #[ stable ( feature = "termination_trait_lib" , since = "1.60.0 " ) ]
2098
2142
impl < E : fmt:: Debug > Termination for Result < Infallible , E > {
2099
2143
fn report ( self ) -> ExitCode {
2100
2144
let Err ( err) = self ;
2101
2145
Err :: < !, _ > ( err) . report ( )
2102
2146
}
2103
2147
}
2104
2148
2105
- #[ unstable ( feature = "termination_trait_lib" , issue = "43301 " ) ]
2149
+ #[ stable ( feature = "termination_trait_lib" , since = "1.60.0 " ) ]
2106
2150
impl Termination for ExitCode {
2107
2151
#[ inline]
2108
2152
fn report ( self ) -> ExitCode {
0 commit comments