Rollup merge of #114800 - RalfJung:transparent, r=cuviper

std: add some missing repr(transparent)

For some types we don't want to stably guarantee this, so hide the `repr` from rustdoc. This nice approach was suggested by `@thomcc.`
This commit is contained in:
Guillaume Gomez 2023-08-15 14:29:46 +02:00 committed by GitHub
commit f527d56c08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 26 additions and 18 deletions

View File

@ -82,12 +82,12 @@ use crate::str;
#[stable(feature = "core_c_str", since = "1.64.0")]
#[rustc_has_incoherent_inherent_impls]
#[lang = "CStr"]
// FIXME:
// `fn from` in `impl From<&CStr> for Box<CStr>` current implementation relies
// on `CStr` being layout-compatible with `[u8]`.
// 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.
// However, `CStr` layout is considered an implementation detail and must not be relied upon. We
// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
#[cfg_attr(not(doc), repr(transparent))]
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

View File

@ -110,12 +110,12 @@ impl crate::sealed::Sealed for OsString {}
/// [conversions]: super#conversions
#[cfg_attr(not(test), rustc_diagnostic_item = "OsStr")]
#[stable(feature = "rust1", since = "1.0.0")]
// FIXME:
// `OsStr::from_inner` current implementation relies
// on `OsStr` being layout-compatible with `Slice`.
// 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.
// However, `OsStr` layout is considered an implementation detail and must not be relied upon. We
// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
#[cfg_attr(not(doc), repr(transparent))]
pub struct OsStr {
inner: Slice,
}

View File

@ -1158,12 +1158,12 @@ impl FusedIterator for Ancestors<'_> {}
/// Which method works best depends on what kind of situation you're in.
#[cfg_attr(not(test), rustc_diagnostic_item = "PathBuf")]
#[stable(feature = "rust1", since = "1.0.0")]
// FIXME:
// `PathBuf::as_mut_vec` current implementation relies
// on `PathBuf` being layout-compatible with `Vec<u8>`.
// 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.
// However, `PathBuf` layout is considered an implementation detail and must not be relied upon. We
// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
#[cfg_attr(not(doc), repr(transparent))]
pub struct PathBuf {
inner: OsString,
}
@ -1983,12 +1983,12 @@ impl AsRef<OsStr> for PathBuf {
/// ```
#[cfg_attr(not(test), rustc_diagnostic_item = "Path")]
#[stable(feature = "rust1", since = "1.0.0")]
// FIXME:
// `Path::new` current implementation relies
// on `Path` being layout-compatible with `OsStr`.
// 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.
// However, `Path` layout is considered an implementation detail and must not be relied upon. We
// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
#[cfg_attr(not(doc), repr(transparent))]
pub struct Path {
inner: OsStr,
}

View File

@ -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) }
}

View File

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