rustc fails to optimize the enum Layout of V1 and V2 of the (real world) example type LazyRwLockGuard to 24 bytes.
In case of V1, this might be be due to #101567.
But the case of V2 seems to be a separate issue, as it is identical to V3 (which is optimized correctly), except for the ordering of the fields inside the Read enum variant.
(For clarity, RwLockReadGuard and RwLockWriteGuard each use 16 bytes and contain a niche).
use std::sync::*;
// could use 24 bytes, uses 32 (probably known issue, #101567)
pub enum LazyRwLockGuardV1<'a, T> {
Unlocked(&'a RwLock<T>),
Read {
lock: &'a RwLock<T>,
guard: RwLockReadGuard<'a, T>,
},
Write(RwLockWriteGuard<'a, T>),
}
// helper subtype (16 Bytes) so the main type figures out it's Niche correctly
pub enum LazyRwLockWriteGuard<'a, T> {
Unlocked(&'a RwLock<T>),
Write(RwLockWriteGuard<'a, T>),
}
// this type should now be 24 bytes, but unfortunately still uses 32
pub enum LazyRwLockGuardV2<'a, T> {
Read {
lock: &'a RwLock<T>,
guard: RwLockReadGuard<'a, T>,
},
NonRead(LazyRwLockWriteGuard<'a, T>),
}
// this type correctly uses 24 bytes
pub enum LazyRwLockGuardV3<'a, T> {
Read {
guard: RwLockReadGuard<'a, T>,
lock: &'a RwLock<T>, // fields reordered
},
NonRead(LazyRwLockWriteGuard<'a, T>),
}
godbolt repro
stackoverflow question
rustc fails to optimize the enum Layout of
V1andV2of the (real world) example typeLazyRwLockGuardto 24 bytes.In case of
V1, this might be be due to #101567.But the case of
V2seems to be a separate issue, as it is identical toV3(which is optimized correctly), except for the ordering of the fields inside theReadenum variant.(For clarity,
RwLockReadGuardandRwLockWriteGuardeach use 16 bytes and contain a niche).godbolt repro
stackoverflow question