Closed
Description
fn call_rec(n: uint, f: |uint| -> uint) -> uint {
if n == 0 { return 1 }
f(call_rec(n - 1, f)) // A
// let tmp = call_rec(n - 1, f); f(tmp) // B
// (|x| f(x))(call_rec(n - 1, f)) // C
// let tmp = call_rec(n - 1, |x| f(x)); f(tmp) // D
}
fn main() {
let mut y = 0u;
let f = |x| { y += x; y };
println!("{}", call_rec(5, f));
}
A
("Obvious" code.)
<anon>:4:23: 4:24 error: cannot move out of `f` because it is borrowed
<anon>:4 f(call_rec(n - 1, f)) // A
^
<anon>:4:5: 4:6 note: borrow of `f` occurs here
<anon>:4 f(call_rec(n - 1, f)) // A
^
B
(Use a temporary.)
<anon>:5:35: 5:36 error: use of moved value: `f`
<anon>:5 let tmp = call_rec(n - 1, f); f(tmp) // B
^
<anon>:5:31: 5:32 note: `f` moved here because it has type `|uint| -> uint`, which is a non-copyable stack closure (capture it in a new closure, e.g. `|x| f(x)`, to override)
<anon>:5 let tmp = call_rec(n - 1, f); f(tmp) // B
^
C
(Reborrow f
for the outer call.)
Incorrectly compiles & runs.
D
(Reborrow f
for the inner call.)
Correctly compiles & runs.
It seems that A
, B
and C
should all be essentially equivalent, and thus should all not compile, because f
is moved into the recursive call before the outer call (and hence that outer call should be disallowed), and thus the reborrowing in C
should be illegal (it is reborrowing the moved-from f
).
This may just disappear once these closures are removed.
Metadata
Metadata
Assignees
Labels
No labels