Background: I am working on a project related to custom DST, and to construct them, I need their layout. So far, I have been able to figure out how to get the Layout for each category of DST as well as Sized type (the only required information being its Pointee::Metadata):
However, I can't get them to work generically as a trait because of how I've implemented dyn_layout. The ?Sized bound make it overlap with the implementation for all the previous one and refused by the compiler.
The question is: is there a better way to get a generic type's Layout? I only need to support the 3 built-in DST, but it would be great if extensible, so custom DST can also be supported.
Your implementations do not actually overlap thanks to them requiring incompatible associated bounds, however the compiler currently does not use this for checking overlaps, leading to your error. The current fix for this is to write a separate helper trait implemented for that associated type, and then write a single impl for your trait where the associated type is bounded by that helper trait.
#![feature(layout_for_ptr)]
#![feature(ptr_metadata)]
use core::alloc::Layout;
use core::ptr::Pointee;
fn layout_from_metadata<T: ?Sized>(metadata: <T as Pointee>::Metadata) -> Layout {
unsafe {
Layout::for_value_raw(std::ptr::from_raw_parts::<T>(
std::ptr::null::<()>(),
metadata,
))
}
}
Although, I’d have to do some digging whether or not for_raw_value is supposed to stay unsafe and if yes, what conditions one would need to actually check here.
I am not aware of any way the above layout_from_metadata would currently actually be unsound though.
Edit: Actually, I’m noticing some requirements w.r.t. overflow or sized larger than isize::MAX in the safety docs, too; those aren’t addressed above – but also they should be a non-issue in all use-cases where you’re actually planning to use this Layout.