Rust is creating copy instead of moving
I've seen this pattern in many crates
fn modify(mut self) -> Self {
//do some stuff to alter it
self // return the same object
}
It looks noice. self is moved in and moved out and novice user like me thinks that no copy is made. but in reality, 3 copies are made
struct Massive {
a: [i128; 10000],
}
impl Massive {
#[inline(always)]
fn stupid(mut self) -> Self {
println!("{:?}", &mut self.a[1] as *mut i128);
//do some stuff to alter it
self.a[1] += 23;
self.a[4] += 24;
//return the same object
self
}
}
fn main() {
let mut f = Massive { a: [10i128; 10000] };
println!("{:?}", &mut f.a[1] as *mut i128);
let mut f2 = f.stupid();
println!("{:?}", &mut f2.a[1] as *mut i128);
}
this outputs
0x7ffd78dfdf18
0x7ffd78dafd18
0x7ffd78dd6e18
which are all different which suggest that 3 different copies are made. At first, I thought different pointers are cause of different variables and data they point must have stable address but as you can see that content have different address as well which means rust is making copy of this large object each time which is very inefficient.
I can just pass &mut self in my own code but that doesn't give you noice chaining like api like this
Massive::new()
.setA()
.setB()
.setC()
and many other crates out of my control use this type of API
With all this ownership information and move semantics, why is rust creating 3 copies ?
I ran the code with
[profile.release]
opt-level = 3
lto = true
panic = "abort"
❯ cargo run --release
but it still print 3 different addresses. inlining also doesn't help
Is this bug ? is copy elision not implement in Rust ?