Thanks everyone for their valuable feedback.
I have been working on a library solution and wanted to finish writing the first version of it. My suggested changes to the stdlib and compiler were not feasible, but luckily using the existing type system similar ergonomics at the call site can be achieved. With more type abstractions simple declarations of pinned initialized types are also written completely without unsafe code. I would really appreciate some feedback for this library but I am unsure, if this is the right place for it. Here is the GH repo: GitHub - y86-dev/pinned-init
@chrefr your arguments are right, the problem of pointer transformation is difficult to handle with &mut, because the origin of that pointer might not be aware of the initialization.
My current problems with my library are (it is not yet finished):
- transmuting
SomeStruct<false>toSomeStruct<true>is only sound, if both have the same layout and i was not able to find such a guarantee and i opened an issue in the UCG repo. If I want to support even more flexible initialization, it might also be a good idea to require#[repr(C)]on the structs that need to be pin initialized. This way using the initialized variant of a type would be even more ergonomic, because the type is equivalent, not just some wrapper (seeStaticUninit<T, true>). But this requirement then would disallow the use ofBox,Arc,Rcand many more, because they are not#[repr(C)]. It is possible to write a customReprC{Box/Arc/Rc}, but that feels a little hacky and might be a source for unnecessary bugs. - adding parameters to the initialization, when my proc macro implements my
PinnedInittrait, it would need to also know the correct type for the paramter (which would be a new associated type). This might result in parameters like this:((), (), ((), ((), String)), *mut i32, ())which are very unergonomic. I might be able to create a trait which would enable conversion of(String, *mut i32)to the preivious type, but i havent tested that yet.
While writing this library, i also found pin-init, another library trying to achieve the same thing, but i ended up writing my own library, because storing not initialized types is not really possible (you could store the init closure, but that requires dyn) and initialization is not checked by the type system like my crate does it.