/// The idea of this function is convert from a Vec of some time to an empty Vec of another type, reusing the heap allocation
fn reuse_vec<T, U>(mut v: Vec<T>) -> Vec<U> {
const {
assert!(size_of::<T>() == size_of::<U>());
assert!(align_of::<T>() == align_of::<U>());
}
v.clear();
v.into_iter().map(|_| unreachable!()).collect()
}
pub struct Foo<'a> {
owned: String,
borrowed: &'a str,
}
struct StaticFoo {
owned: String,
borrowed: MaybeUninit<&'static str>,
}
fn without_lifetime(foos: Vec<Foo>) -> Vec<StaticFoo> {
foos.into_iter()
.map(|f| StaticFoo {
owned: f.owned,
borrowed: MaybeUninit::uninit(),
})
.collect()
}
// The presence of MaybeUnit::uninit() tells the compiler that it’s OK to have anything there, so it can choose to leave whatever &str was in the original Foo struct. This means that it’s valid to produce a StaticFoo with the same in-memory representation as the Foo that it replaces, allowing it to eliminate the loop