Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions library/core/src/ffi/c_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ use crate::str;
// When attribute privacy is implemented, `CStr` should be annotated as `#[repr(transparent)]`.
// Anyway, `CStr` representation and layout are considered implementation detail, are
// not documented and must not be relied upon.
// For now we just hide this from rustdoc, technically making our doc test builds rely on
// unspecified layout assumptions. We are std, so we can get away with that.
#[cfg_attr(not(doc), repr(transparent))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure this affects doc tests? I tried this on a new library and it compiled, but failed the assertion:

/// ```
/// assert!(cfg!(doc));
/// ```
pub struct Foo(u32);

I do expect your cfg will affect how rustdoc parses the source when it looks for doctests, but not the actual library or doctest build.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another way to see that doc tests are not affected:

/// ```
/// use lib::Foo;
/// use std::mem::align_of;
///
/// assert!(!cfg!(doc));
/// assert_eq!(align_of::<Foo>(), align_of::<u32>());
/// ```
#[cfg_attr(doc, repr(packed))]
pub struct Foo(u32);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I guess doctests are built with cfg(doctest)... nice! So this is actually a reasonable approach then.

pub struct CStr {
// FIXME: this should not be represented with a DST slice but rather with
// just a raw `c_char` along with some form of marker to make
Expand Down
3 changes: 3 additions & 0 deletions library/std/src/ffi/os_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ impl crate::sealed::Sealed for OsString {}
// When attribute privacy is implemented, `OsStr` should be annotated as `#[repr(transparent)]`.
// Anyway, `OsStr` representation and layout are considered implementation details, are
// not documented and must not be relied upon.
// For now we just hide this from rustdoc, technically making our doc test builds rely on
// unspecified layout assumptions. We are std, so we can get away with that.
#[cfg_attr(not(doc), repr(transparent))]
pub struct OsStr {
inner: Slice,
}
Expand Down
6 changes: 6 additions & 0 deletions library/std/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1164,6 +1164,9 @@ impl FusedIterator for Ancestors<'_> {}
// When attribute privacy is implemented, `PathBuf` should be annotated as `#[repr(transparent)]`.
// Anyway, `PathBuf` representation and layout are considered implementation detail, are
// not documented and must not be relied upon.
// For now we just hide this from rustdoc, technically making our doc test builds rely on
// unspecified layout assumptions. We are std, so we can get away with that.
#[cfg_attr(not(doc), repr(transparent))]
pub struct PathBuf {
inner: OsString,
}
Expand Down Expand Up @@ -1989,6 +1992,9 @@ impl AsRef<OsStr> for PathBuf {
// When attribute privacy is implemented, `Path` should be annotated as `#[repr(transparent)]`.
// Anyway, `Path` representation and layout are considered implementation detail, are
// not documented and must not be relied upon.
// For now we just hide this from rustdoc, technically making our doc test builds rely on
// unspecified layout assumptions. We are std, so we can get away with that.
#[cfg_attr(not(doc), repr(transparent))]
pub struct Path {
inner: OsStr,
}
Expand Down
10 changes: 8 additions & 2 deletions library/std/src/sys/wasi/fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,20 @@ pub struct WasiFd {
fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::Iovec] {
assert_eq!(mem::size_of::<IoSliceMut<'_>>(), mem::size_of::<wasi::Iovec>());
assert_eq!(mem::align_of::<IoSliceMut<'_>>(), mem::align_of::<wasi::Iovec>());
// SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout
// SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout.
// We decorate our `IoSliceMut` with `repr(transparent)` (see `io.rs`), and
// `crate::io::IoSliceMut` is a `repr(transparent)` wrapper around our type, so this is
// guaranteed.
unsafe { mem::transmute(a) }
}

fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::Ciovec] {
assert_eq!(mem::size_of::<IoSlice<'_>>(), mem::size_of::<wasi::Ciovec>());
assert_eq!(mem::align_of::<IoSlice<'_>>(), mem::align_of::<wasi::Ciovec>());
// SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout
// SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout.
// We decorate our `IoSlice` with `repr(transparent)` (see `io.rs`), and
// `crate::io::IoSlice` is a `repr(transparent)` wrapper around our type, so this is
// guaranteed.
unsafe { mem::transmute(a) }
}

Expand Down
2 changes: 2 additions & 0 deletions library/std/src/sys_common/wtf8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ impl Wtf8Buf {
/// Converts this `Wtf8Buf` into a boxed `Wtf8`.
#[inline]
pub fn into_box(self) -> Box<Wtf8> {
// SAFETY: relies on `Wtf8` being `repr(transparent)`.
unsafe { mem::transmute(self.bytes.into_boxed_slice()) }
}

Expand Down Expand Up @@ -511,6 +512,7 @@ impl Extend<CodePoint> for Wtf8Buf {
/// Similar to `&str`, but can additionally contain surrogate code points
/// if they’re not in a surrogate pair.
#[derive(Eq, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct Wtf8 {
bytes: [u8],
}
Expand Down