Skip to content

Commit f527d56

Browse files
authoredAug 15, 2023
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.`
2 parents f0987ab + fe1a034 commit f527d56

File tree

5 files changed

+26
-18
lines changed

5 files changed

+26
-18
lines changed
 

Diff for: ‎library/core/src/ffi/c_str.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,12 @@ use crate::str;
8282
#[stable(feature = "core_c_str", since = "1.64.0")]
8383
#[rustc_has_incoherent_inherent_impls]
8484
#[lang = "CStr"]
85-
// FIXME:
8685
// `fn from` in `impl From<&CStr> for Box<CStr>` current implementation relies
8786
// on `CStr` being layout-compatible with `[u8]`.
88-
// When attribute privacy is implemented, `CStr` should be annotated as `#[repr(transparent)]`.
89-
// Anyway, `CStr` representation and layout are considered implementation detail, are
90-
// not documented and must not be relied upon.
87+
// However, `CStr` layout is considered an implementation detail and must not be relied upon. We
88+
// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
89+
// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
90+
#[cfg_attr(not(doc), repr(transparent))]
9191
pub struct CStr {
9292
// FIXME: this should not be represented with a DST slice but rather with
9393
// just a raw `c_char` along with some form of marker to make

Diff for: ‎library/std/src/ffi/os_str.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,12 @@ impl crate::sealed::Sealed for OsString {}
110110
/// [conversions]: super#conversions
111111
#[cfg_attr(not(test), rustc_diagnostic_item = "OsStr")]
112112
#[stable(feature = "rust1", since = "1.0.0")]
113-
// FIXME:
114113
// `OsStr::from_inner` current implementation relies
115114
// on `OsStr` being layout-compatible with `Slice`.
116-
// When attribute privacy is implemented, `OsStr` should be annotated as `#[repr(transparent)]`.
117-
// Anyway, `OsStr` representation and layout are considered implementation details, are
118-
// not documented and must not be relied upon.
115+
// However, `OsStr` layout is considered an implementation detail and must not be relied upon. We
116+
// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
117+
// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
118+
#[cfg_attr(not(doc), repr(transparent))]
119119
pub struct OsStr {
120120
inner: Slice,
121121
}

Diff for: ‎library/std/src/path.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -1158,12 +1158,12 @@ impl FusedIterator for Ancestors<'_> {}
11581158
/// Which method works best depends on what kind of situation you're in.
11591159
#[cfg_attr(not(test), rustc_diagnostic_item = "PathBuf")]
11601160
#[stable(feature = "rust1", since = "1.0.0")]
1161-
// FIXME:
11621161
// `PathBuf::as_mut_vec` current implementation relies
11631162
// on `PathBuf` being layout-compatible with `Vec<u8>`.
1164-
// When attribute privacy is implemented, `PathBuf` should be annotated as `#[repr(transparent)]`.
1165-
// Anyway, `PathBuf` representation and layout are considered implementation detail, are
1166-
// not documented and must not be relied upon.
1163+
// However, `PathBuf` layout is considered an implementation detail and must not be relied upon. We
1164+
// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
1165+
// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
1166+
#[cfg_attr(not(doc), repr(transparent))]
11671167
pub struct PathBuf {
11681168
inner: OsString,
11691169
}
@@ -1983,12 +1983,12 @@ impl AsRef<OsStr> for PathBuf {
19831983
/// ```
19841984
#[cfg_attr(not(test), rustc_diagnostic_item = "Path")]
19851985
#[stable(feature = "rust1", since = "1.0.0")]
1986-
// FIXME:
19871986
// `Path::new` current implementation relies
19881987
// on `Path` being layout-compatible with `OsStr`.
1989-
// When attribute privacy is implemented, `Path` should be annotated as `#[repr(transparent)]`.
1990-
// Anyway, `Path` representation and layout are considered implementation detail, are
1991-
// not documented and must not be relied upon.
1988+
// However, `Path` layout is considered an implementation detail and must not be relied upon. We
1989+
// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
1990+
// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
1991+
#[cfg_attr(not(doc), repr(transparent))]
19921992
pub struct Path {
19931993
inner: OsStr,
19941994
}

Diff for: ‎library/std/src/sys/wasi/fd.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,20 @@ pub struct WasiFd {
1616
fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::Iovec] {
1717
assert_eq!(mem::size_of::<IoSliceMut<'_>>(), mem::size_of::<wasi::Iovec>());
1818
assert_eq!(mem::align_of::<IoSliceMut<'_>>(), mem::align_of::<wasi::Iovec>());
19-
// SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout
19+
// SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout.
20+
// We decorate our `IoSliceMut` with `repr(transparent)` (see `io.rs`), and
21+
// `crate::io::IoSliceMut` is a `repr(transparent)` wrapper around our type, so this is
22+
// guaranteed.
2023
unsafe { mem::transmute(a) }
2124
}
2225

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

Diff for: ‎library/std/src/sys_common/wtf8.rs

+2
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ impl Wtf8Buf {
459459
/// Converts this `Wtf8Buf` into a boxed `Wtf8`.
460460
#[inline]
461461
pub fn into_box(self) -> Box<Wtf8> {
462+
// SAFETY: relies on `Wtf8` being `repr(transparent)`.
462463
unsafe { mem::transmute(self.bytes.into_boxed_slice()) }
463464
}
464465

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

0 commit comments

Comments
 (0)