You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While working through Chapter 9 -> 9.2 Closures -> 9.2.1 Capturing I found that execution of the following code snippet resulted in an error (as expected) when executed in the embedded playground:
letmut count = 0;// A closure to increment `count` could take either `&mut count`// or `count` but `&mut count` is less restrictive so it takes// that. Immediately borrows `count`.//// A `mut` is required on `inc` because a `&mut` is stored inside.// Thus, calling the closure mutates the closure which requires// a `mut`.letmut inc = || {
count += 1;println!("`count`: {}", count);};// Call the closure.inc();inc();// expect a borrow failure herelet _reborrow = &mut count;// ^ TODO: try uncommenting this line.
As expected, uncommenting the let _reborrow ... line resulted in an error:
Compiling playground v0.0.1 (/playground)
error[E0499]: cannot borrow `count` as mutable more than once at a time
--> src/main.rs:35:26
|
26 | let mut inc = || {
| -- first mutable borrow occurs here
27 | count += 1;
| ----- previous borrow occurs due to use of `count` in closure
...
35 | let _reborrow = &mut count;
| ^^^^^ second mutable borrow occurs here
...
54 | }
| - first borrow ends here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0499`.
error: Could not compile `playground`.
To learn more, run the command again with --verbose.
Executing the same code on my workstation did not result in an error and a cargo check of the code returned a clean result:
cargo check
Checking closures v0.1.0 (/<my_path>/rust_by_example/closures)
Finished dev [unoptimized + debuginfo] target(s) in 0.23s
I am running the following build: stable-x86_64-apple-darwin unchanged - rustc 1.33.0 (2aa4c46cf 2019-02-28). / rust 2018
Presumably some changes have been made to rustc v1.33 / 2018 whereby it recognizes that closure variable inc is not referenced again in the code following the two inc(); calls? I am pretty new to Rust, by I think that the compiler is smart enough to recognize that the new assignment to _reborrowed is safe in this situation?
I updated the code snippet on my workstation as shown below, and found that the complier generated an error (as expected):
letmut count = 0;// i32// a closure to increment `count` could take `&mut count` or// `count` but `&mut count` is less restrictive, so it takes// that(?). `count` is immediately borrowed.// `mut` is required on `inc` because a `&mut` is stored inside.// callint the closure mutates the closure which in-turn requires// a `mut`.letmut inc = || {// count: &mut i32
count += 1;println!("`count`: {}", count);};// Call the closure.inc();let _reborrow = &mut count;// new location!inc();
Error message:
error[E0499]: cannot borrow `count` as mutable more than once at a time
--> src/main.rs:48:21
|
40 | let mut inc = || {
| -- first mutable borrow occurs here
41 | // count: &mut i32
42 | count += 1;
| ----- first borrow occurs due to use of `count` in closure
...
48 | let _reborrow = &mut count;
| ^^^^^^^^^^ second mutable borrow occurs here
49 | inc();
| --- first borrow later used here
error: aborting due to previous error
I am pretty sure that this is the scenario that the page author wanted to illustrate, as this is the behaviour exhibited by the embedded playground (and also with edition = "2015"). The concern is that the example as written illustrates the author's intent in the playground, but not in the current stable release (1.33)/2018 of the rust toolchain.
The code example should probably(?) be enhanced to illustrate / compensate for the effects described above. Maybe something like this:
letmut count = 0;// A closure to increment `count` could take either `&mut count`// or `count` but `&mut count` is less restrictive so it takes// that. Immediately borrows `count`.//// A `mut` is required on `inc` because a `&mut` is stored inside.// Thus, calling the closure mutates the closure which requires// a `mut`.letmut inc = || {
count += 1;println!("`count`: {}", count);};// Call the closure.inc();// let _reborrow = &mut count; // error[E0499]: ...// ^ TODO: try uncommenting this line.inc();// let _reborrow = &mut count; // okay!// ^ TODO: try uncommenting this line.
Thanks for looking (and also for putting together such a great book).
The text was updated successfully, but these errors were encountered:
While working through
Chapter 9
->9.2 Closures
->9.2.1 Capturing
I found that execution of the following code snippet resulted in an error (as expected) when executed in the embedded playground:As expected, uncommenting the
let _reborrow ...
line resulted in an error:Executing the same code on my workstation did not result in an error and a
cargo check
of the code returned a clean result:I am running the following build: stable-x86_64-apple-darwin unchanged - rustc 1.33.0 (2aa4c46cf 2019-02-28). / rust 2018
Presumably some changes have been made to
rustc
v1.33 / 2018 whereby it recognizes that closure variableinc
is not referenced again in the code following the twoinc();
calls? I am pretty new to Rust, by I think that the compiler is smart enough to recognize that the new assignment to_reborrowed
is safe in this situation?I updated the code snippet on my workstation as shown below, and found that the complier generated an error (as expected):
Error message:
I am pretty sure that this is the scenario that the page author wanted to illustrate, as this is the behaviour exhibited by the embedded playground (and also with edition = "2015"). The concern is that the example as written illustrates the author's intent in the playground, but not in the current stable release (1.33)/2018 of the rust toolchain.
The code example should probably(?) be enhanced to illustrate / compensate for the effects described above. Maybe something like this:
Thanks for looking (and also for putting together such a great book).
The text was updated successfully, but these errors were encountered: