I just found out that the following code compiles in Rust 21 (used to not compile in 18)
fn get_func (i: &mut i32) -> impl Fn() -> i32 + '_ {
|| *i
}
Is there an implicit move of i
involved ? If so, then why does the following code compile too?
fn get_func (i: &mut i32) -> impl Fn() -> i32 + '_ {
let f = || *i;
println!("{:?}", i); // was expecting here to give borrow of moved variable error, `&mut` doesnt implement `Copy` trait
f
}
Or instead is it implicitly moving (copying in this case) the value being pointed to? But then the following code should compile, which doesn't -- indicating it's moving the reference.
fn get_func (i: &mut i32) -> impl Fn() -> i32 {
|| *i
}
let f = { let ii = &*i; move || *ii };
. but I cannot find this new behavior documented anywhere... Maybe from rfc/2229: References to structs would be made more precise by reborrowing fields... – Harrimanprintln!()
) howprintln!()
can access the mut referencei
whilef
refers to it. Both the closure andprintln!()
are reborrowing, and thus downgrading the mutable reference to two shared referenes. This is allowed, similar to how it's allowed to invokefoo(&x.foo, &x.bar)
wherex
is&mut FooBar
. play.rust-lang.org/… – Airedalemove || *i
, the example is compiled and behaves in the same way with versions 2018 and 2021. – Hobgoblini
, instead of reborrow. In the second example, it is smart to "defer" the move to the end of the function. – Anthe