Rust free unwrap for vec of newtypes

Viewed 375

If I have the following program:

struct Foo {
    a: usize,
    b: usize,
}

struct Bar(Foo);

fn unwrap_bars(bars: Vec<Bar>) -> Vec<Foo> {
  bars.into_iter().map(|b| b.0).collect()
}

Will unwrap_bars be compiled to an identity function? If it is not compiled to an identity function then how could I write unwrap_bars so that I keep the newtype abstraction while allowing free unwrapping of a collection of Bars?

I assume that a newtype wrapper like Bar compiles directly to Foo without adding any extra memory indirection.

1 Answers

No, I doubt your function would result in an identity function(I looked at the generated assembly and there was definitely an allocation). This would though:

fn unwrap_bars(mut bars : Vec<Bar>) -> Vec<Foo> {
    unsafe {
        let ptr = bars.as_mut_ptr() as *mut Foo;
        let len = bars.len();
        let cap = bars.capacity();
        std::mem::forget(bars);     // to prevent destructor being called
        Vec::from_raw_parts(ptr, len, cap)
    }
}
Related