No, it's unsound. If tap doesn't actually initialize the passed-in buffer, then a.assume_init() is Undefined Behavior. You either need to mark tap_non_empty_uninit_vec() as unsafe and document what the tap should do (which essentially defines away the problem), or ensure by means of the type system that you get an initialized buffer back, e.g.:
pub fn tap_non_empty_uninit_vec<R>(len: usize, tap: impl FnOnce(NonEmpty<MaybeUninit<R>>) -> NonEmpty<R>) -> NonEmpty<R> {
let temp: NonEmpty<_> = core::iter::repeat_with(MaybeUninit::uninit)
.take(len)
.collect::<Vec<_>>()
.try_into()
.expect("len must be > 0");
tap(temp)
}
Also note that || MaybeUninit::uninit() is equivalent to MaybeUninit::uninit – there's no need to create a closure, because just the reference to the MaybeUninit::uninit function has the appropriate sugnature (fn() -> MaybeUninit<_>). It's also possible to avoid the mutable resize_with() by collecting an appropriately-sized iterator in the first place.