diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index e7eecf7540a..8b8bda2e6b4 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1475,6 +1475,7 @@ impl fmt::Display for RefMut<'_, T> { #[lang = "unsafe_cell"] #[stable(feature = "rust1", since = "1.0.0")] #[repr(transparent)] +#[cfg_attr(not(bootstrap), repr(no_niche))] // rust-lang/rust#68303. pub struct UnsafeCell { value: T, } diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 1fd70e1a1b0..c8865a8f1b3 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -138,6 +138,7 @@ #![feature(const_type_id)] #![feature(const_caller_location)] #![feature(assoc_int_consts)] +#![cfg_attr(not(bootstrap), feature(no_niche))] // rust-lang/rust#68303 #[prelude_import] #[allow(unused)] diff --git a/src/test/ui/layout/unsafe-cell-hides-niche.rs b/src/test/ui/layout/unsafe-cell-hides-niche.rs new file mode 100644 index 00000000000..4ca3f7a1aad --- /dev/null +++ b/src/test/ui/layout/unsafe-cell-hides-niche.rs @@ -0,0 +1,32 @@ +// For rust-lang/rust#68303: the contents of `UnsafeCell` cannot +// participate in the niche-optimization for enum discriminants. This +// test checks that an `Option>` has the same +// size in memory as an `Option>` (namely, 8 bytes). + +// run-pass + +#![feature(no_niche)] + +use std::cell::UnsafeCell; +use std::mem::size_of; +use std::num::NonZeroU32 as N32; + +struct Wrapper(T); + +#[repr(transparent)] +struct Transparent(T); + +#[repr(no_niche)] +struct NoNiche(T); + +fn main() { + assert_eq!(size_of::>>(), 8); + assert_eq!(size_of::>>(), 4); + assert_eq!(size_of::>>(), 8); + assert_eq!(size_of::>>(), 4); + assert_eq!(size_of::>>(), 8); + assert_eq!(size_of::>>(), 8); + + assert_eq!(size_of::>>(), 8); + assert_eq!(size_of::>>(), 8); +}