Open
Description
In Rust 2021 the borrow checker got extended to see through borrow paths when writing closures. I've been wondering how this is implemented, but it seems like it's basically just syntax sugar for individual manual borrows that get moved in. This however leads to worse codegen than when a move closure would've been possible. So you might end up with code that performs worse by accident:
pub struct Foo {
x: f32,
y: f32,
z: f32,
}
pub fn with_move(bar: &mut Foo) -> impl Fn() -> f32 + '_ {
move || bar.x + bar.y + bar.z
}
pub fn without_move(bar: &mut Foo) -> impl Fn() -> f32 + '_ {
|| bar.x + bar.y + bar.z
}
example::with_move:
mov rax, rdi
ret
example::without_move:
mov rax, rdi
lea rcx, [rsi + 4]
mov qword ptr [rdi], rsi
add rsi, 8
mov qword ptr [rdi + 8], rcx
mov qword ptr [rdi + 16], rsi
ret