there's an unstable feature unsized_locals, which allows you to "unbox" the DST, but on stable, you need to use a different trait for the type erasure, the vtable of FnOnce simply cannot do.
EDIT:
unsized_locals is removed, usized_fn_params still exists, but it doesn't work, see previous post by @quinedot
the problem with dyn FnOnce() is the vtable is complete unusable for user defined type: you cannot implement/delegate it, you cannot consume it either. so including a dyn FnOnce tail in a custom DST doesn't make much sense.
In light of your solution, I agree, and the below nit is moot for this topic IMO.
The metadata for a UserDef<dyn FnOnce()> is the same as that for a Box<dyn FnOnce()>, so "all" you have to do[1] is move the type-erased value into a new Box-compatible allocation and use Box::from_raw, correctly juggling all destructor calls.
Moving the type-erased value is still somewhat questionable, I haven't thought that through in depth. But I believe this has all been possible on stable for quite awhile now, since any time one has been able to soundly deduce how to decompose and recompose dyn pointers and had ManuallyDrop available. wrapping_byte_add in particular removes any chance of not being able to deal with the wide pointers at runtime.
(I did finish a POC, but don't recommend using it in light of your solution, so didn't bother posting it.)
without unstable, apparently incomplete features âŠī¸