You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Cannot transmute between ZST and zero-sized generic array #98104
I expected this to compile, because [T; 0] is always zero-sized.
Instead, it fails to compile with this error:
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> src/lib.rs:6:14
|
6 | unsafe { ::core::mem::transmute::<(), GenericZst<T>>(()) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: source type: `()` (0 bits)
= note: target type: `GenericZst<T>` (size can vary because of T)
For more information about this error, try `rustc --explain E0512`.
error: could not compile `playground` due to previous error
I would argue that this should not be considered a bug, but that it works as intended. I started tackling this in #114009, and it is definitely possible to implement this. However, it is unclear whether we can stabilize this in its current state and whether it wouldn't require an RFC.
The compiler currently handles most type-layout aspects in a compound way. That is, size, alignment, abi, etc. of a type is tracked in a single Layout object (or LayoutS, fwiw). If any of the layout properties cannot be determined, none of the properties is made available. On the flip-side, this means a layout property can only be used by the compiler if all layout properties are well defined.
In this situation that means that the compiler can only consider the size of the generic array if its alignment is also known. Since the alignment of generic arrays is not fixed, the compiler will also refuse to reason about its size.
There is a feature-flag transmute_generic_consts (#109929) which untangles size-calculations from layout-calculations (used in several places, not just transmute). It uses a SizeSkeleton structure that allows calculating type-sizes independent of their layout. Furthermore, it even allows comparing type-sizes of non-fixed generics through simple type-comparisons. However, there is no agreement on whether this can be stabilized as it is. @lcnr raised concerns and mentioned transmutability (#99571) as possible alternative.
From a user perspective I can understand that this transmute should be valid rust code. However, I can also see that layout calculations might have cascading effects. I could easily get transmutes work for zero-sized generic arrays (see #114009). However, for true transmute support this would need to be extended to propagate through compound types with such arrays, or through newtypes, etc. And then it might also affect calculations of repr(transparent) (which also considers zero-sized fields, but is also affected by alignment), or nonnull_layout_guaranteed (which propagates its optimization through newtypes).
Maybe someone from the compiler team can comment on possible future plans for this. But as an outsider, I feel like putting effort into implementing this just to be blocked by transmute_generic_consts seems a bit wasted. Is there a future for SizeSkeleton? Is it possible to implement extensions of SizeSkeleton without the feature flag? Does an implementation of said transmute extensions need an RFC first?
Activity
dvdhrm commentedon Jul 24, 2023
I would argue that this should not be considered a bug, but that it works as intended. I started tackling this in #114009, and it is definitely possible to implement this. However, it is unclear whether we can stabilize this in its current state and whether it wouldn't require an RFC.
The compiler currently handles most type-layout aspects in a compound way. That is, size, alignment, abi, etc. of a type is tracked in a single
Layoutobject (orLayoutS, fwiw). If any of the layout properties cannot be determined, none of the properties is made available. On the flip-side, this means a layout property can only be used by the compiler if all layout properties are well defined.In this situation that means that the compiler can only consider the size of the generic array if its alignment is also known. Since the alignment of generic arrays is not fixed, the compiler will also refuse to reason about its size.
There is a feature-flag
transmute_generic_consts(#109929) which untangles size-calculations from layout-calculations (used in several places, not just transmute). It uses aSizeSkeletonstructure that allows calculating type-sizes independent of their layout. Furthermore, it even allows comparing type-sizes of non-fixed generics through simple type-comparisons. However, there is no agreement on whether this can be stabilized as it is. @lcnr raised concerns and mentioned transmutability (#99571) as possible alternative.From a user perspective I can understand that this transmute should be valid rust code. However, I can also see that layout calculations might have cascading effects. I could easily get transmutes work for zero-sized generic arrays (see #114009). However, for true transmute support this would need to be extended to propagate through compound types with such arrays, or through newtypes, etc. And then it might also affect calculations of
repr(transparent)(which also considers zero-sized fields, but is also affected by alignment), ornonnull_layout_guaranteed(which propagates its optimization through newtypes).Maybe someone from the compiler team can comment on possible future plans for this. But as an outsider, I feel like putting effort into implementing this just to be blocked by
transmute_generic_constsseems a bit wasted. Is there a future forSizeSkeleton? Is it possible to implement extensions ofSizeSkeletonwithout the feature flag? Does an implementation of said transmute extensions need an RFC first?Rollup merge of rust-lang#114009 - dvdhrm:pr/transmzst, r=pnkfelix
compiler: allow transmute of ZST arrays with generics
Rollup merge of rust-lang#114009 - dvdhrm:pr/transmzst, r=pnkfelix
Unrolled build for rust-lang#114009