Skip to content

Commit

Permalink
Seal the CommandExt, OsStrExt and OsStringExt traits
Browse files Browse the repository at this point in the history
  • Loading branch information
Amanieu committed Feb 10, 2021
1 parent 07194ff commit bfd1ccf
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 30 deletions.
8 changes: 8 additions & 0 deletions library/std/src/ffi/os_str.rs
Expand Up @@ -76,6 +76,10 @@ pub struct OsString {
inner: Buf,
}

/// Allows extension traits within `std`.
#[unstable(feature = "sealed", issue = "none")]
impl crate::sealed::Sealed for OsString {}

/// Borrowed reference to an OS string (see [`OsString`]).
///
/// This type represents a borrowed reference to a string in the operating system's preferred
Expand All @@ -100,6 +104,10 @@ pub struct OsStr {
inner: Slice,
}

/// Allows extension traits within `std`.
#[unstable(feature = "sealed", issue = "none")]
impl crate::sealed::Sealed for OsStr {}

impl OsString {
/// Constructs a new empty `OsString`.
///
Expand Down
8 changes: 8 additions & 0 deletions library/std/src/lib.rs
Expand Up @@ -582,3 +582,11 @@ include!("keyword_docs.rs");
// is unconditional, so the unstable feature needs to be defined somewhere.
#[unstable(feature = "restricted_std", issue = "none")]
mod __restricted_std_workaround {}

mod sealed {
/// This trait being unreachable from outside the crate
/// prevents outside implementations of our extension traits.
/// This allows adding more trait methods in the future.
#[unstable(feature = "sealed", issue = "none")]
pub trait Sealed {}
}
8 changes: 8 additions & 0 deletions library/std/src/process.rs
Expand Up @@ -498,6 +498,10 @@ pub struct Command {
inner: imp::Command,
}

/// Allows extension traits within `std`.
#[unstable(feature = "sealed", issue = "none")]
impl crate::sealed::Sealed for Command {}

impl Command {
/// Constructs a new `Command` for launching the program at
/// path `program`, with the following default configuration:
Expand Down Expand Up @@ -1375,6 +1379,10 @@ impl From<fs::File> for Stdio {
#[stable(feature = "process", since = "1.0.0")]
pub struct ExitStatus(imp::ExitStatus);

/// Allows extension traits within `std`.
#[unstable(feature = "sealed", issue = "none")]
impl crate::sealed::Sealed for ExitStatus {}

impl ExitStatus {
/// Was termination successful? Signal termination is not considered a
/// success, and success is defined as a zero exit status.
Expand Down
19 changes: 6 additions & 13 deletions library/std/src/sys/unix/ext/process.rs
Expand Up @@ -6,20 +6,16 @@ use crate::ffi::OsStr;
use crate::io;
use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use crate::process;
use crate::sealed::Sealed;
use crate::sys;
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};

mod private {
/// This trait being unreachable from outside the crate
/// prevents other implementations of the `ExitStatusExt` trait,
/// which allows potentially adding more trait methods in the future.
#[stable(feature = "none", since = "1.51.0")]
pub trait Sealed {}
}

/// Unix-specific extensions to the [`process::Command`] builder.
///
/// This trait is sealed: it cannot be implemented outside the standard library.
/// This is so that future additional methods are not breaking changes.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait CommandExt {
pub trait CommandExt: Sealed {
/// Sets the child process's user ID. This translates to a
/// `setuid` call in the child process. Failure in the `setuid`
/// call will cause the spawn to fail.
Expand Down Expand Up @@ -193,7 +189,7 @@ impl CommandExt for process::Command {
/// This trait is sealed: it cannot be implemented outside the standard library.
/// This is so that future additional methods are not breaking changes.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait ExitStatusExt: private::Sealed {
pub trait ExitStatusExt: Sealed {
/// Creates a new `ExitStatus` from the raw underlying `i32` return value of
/// a process.
#[stable(feature = "exit_status_from", since = "1.12.0")]
Expand Down Expand Up @@ -228,9 +224,6 @@ pub trait ExitStatusExt: private::Sealed {
fn into_raw(self) -> i32;
}

#[stable(feature = "none", since = "1.51.0")]
impl private::Sealed for process::ExitStatus {}

#[stable(feature = "rust1", since = "1.0.0")]
impl ExitStatusExt for process::ExitStatus {
fn from_raw(raw: i32) -> Self {
Expand Down
11 changes: 9 additions & 2 deletions library/std/src/sys/windows/ext/ffi.rs
Expand Up @@ -53,6 +53,7 @@
#![stable(feature = "rust1", since = "1.0.0")]

use crate::ffi::{OsStr, OsString};
use crate::sealed::Sealed;
use crate::sys::os_str::Buf;
use crate::sys_common::wtf8::Wtf8Buf;
use crate::sys_common::{AsInner, FromInner};
Expand All @@ -61,8 +62,11 @@ use crate::sys_common::{AsInner, FromInner};
pub use crate::sys_common::wtf8::EncodeWide;

/// Windows-specific extensions to [`OsString`].
///
/// This trait is sealed: it cannot be implemented outside the standard library.
/// This is so that future additional methods are not breaking changes.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait OsStringExt {
pub trait OsStringExt: Sealed {
/// Creates an `OsString` from a potentially ill-formed UTF-16 slice of
/// 16-bit code units.
///
Expand Down Expand Up @@ -92,8 +96,11 @@ impl OsStringExt for OsString {
}

/// Windows-specific extensions to [`OsStr`].
///
/// This trait is sealed: it cannot be implemented outside the standard library.
/// This is so that future additional methods are not breaking changes.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait OsStrExt {
pub trait OsStrExt: Sealed {
/// Re-encodes an `OsStr` as a wide character sequence, i.e., potentially
/// ill-formed UTF-16.
///
Expand Down
19 changes: 6 additions & 13 deletions library/std/src/sys/windows/ext/process.rs
Expand Up @@ -4,17 +4,10 @@

use crate::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
use crate::process;
use crate::sealed::Sealed;
use crate::sys;
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};

mod private {
/// This trait being unreachable from outside the crate
/// prevents other implementations of the `ExitStatusExt` trait,
/// which allows potentially adding more trait methods in the future.
#[stable(feature = "none", since = "1.51.0")]
pub trait Sealed {}
}

#[stable(feature = "process_extensions", since = "1.2.0")]
impl FromRawHandle for process::Stdio {
unsafe fn from_raw_handle(handle: RawHandle) -> process::Stdio {
Expand Down Expand Up @@ -85,7 +78,7 @@ impl IntoRawHandle for process::ChildStderr {
/// This trait is sealed: it cannot be implemented outside the standard library.
/// This is so that future additional methods are not breaking changes.
#[stable(feature = "exit_status_from", since = "1.12.0")]
pub trait ExitStatusExt: private::Sealed {
pub trait ExitStatusExt: Sealed {
/// Creates a new `ExitStatus` from the raw underlying `u32` return value of
/// a process.
#[stable(feature = "exit_status_from", since = "1.12.0")]
Expand All @@ -99,12 +92,12 @@ impl ExitStatusExt for process::ExitStatus {
}
}

#[stable(feature = "none", since = "1.51.0")]
impl private::Sealed for process::ExitStatus {}

/// Windows-specific extensions to the [`process::Command`] builder.
///
/// This trait is sealed: it cannot be implemented outside the standard library.
/// This is so that future additional methods are not breaking changes.
#[stable(feature = "windows_process_extensions", since = "1.16.0")]
pub trait CommandExt {
pub trait CommandExt: Sealed {
/// Sets the [process creation flags][1] to be passed to `CreateProcess`.
///
/// These will always be ORed with `CREATE_UNICODE_ENVIRONMENT`.
Expand Down
11 changes: 9 additions & 2 deletions library/std/src/sys_common/os_str_bytes.rs
Expand Up @@ -6,6 +6,7 @@ use crate::ffi::{OsStr, OsString};
use crate::fmt;
use crate::mem;
use crate::rc::Rc;
use crate::sealed::Sealed;
use crate::str;
use crate::sync::Arc;
use crate::sys_common::bytestring::debug_fmt_bytestring;
Expand Down Expand Up @@ -232,8 +233,11 @@ impl Slice {
}

/// Platform-specific extensions to [`OsString`].
///
/// This trait is sealed: it cannot be implemented outside the standard library.
/// This is so that future additional methods are not breaking changes.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait OsStringExt {
pub trait OsStringExt: Sealed {
/// Creates an [`OsString`] from a byte vector.
///
/// See the module documentation for an example.
Expand All @@ -258,8 +262,11 @@ impl OsStringExt for OsString {
}

/// Platform-specific extensions to [`OsStr`].
///
/// This trait is sealed: it cannot be implemented outside the standard library.
/// This is so that future additional methods are not breaking changes.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait OsStrExt {
pub trait OsStrExt: Sealed {
#[stable(feature = "rust1", since = "1.0.0")]
/// Creates an [`OsStr`] from a byte slice.
///
Expand Down

0 comments on commit bfd1ccf

Please sign in to comment.