X-Git-Url: https://git.ralfj.de/rust-101.git/blobdiff_plain/188b1ec1b8528e2326791feccc8077e15bd60182..2d40516a8393db1f27bb822ff95c71a1a9c82537:/solutions/src/callbacks.rs?ds=sidebyside diff --git a/solutions/src/callbacks.rs b/solutions/src/callbacks.rs index 93fcb17..2b0eeef 100644 --- a/solutions/src/callbacks.rs +++ b/solutions/src/callbacks.rs @@ -16,7 +16,7 @@ impl Callbacks { self.callbacks.push(cell); /*@*/ } - pub fn call(&self, val: i32) { + pub fn call(&mut self, val: i32) { for callback in self.callbacks.iter() { // We have to *explicitly* borrow the contents of a `RefCell`. //@ At run-time, the cell will keep track of the number of outstanding shared and mutable borrows, @@ -53,14 +53,19 @@ mod tests { let c = Rc::new(RefCell::new(Callbacks::new())); c.borrow_mut().register(|val| println!("Callback called: {}", val) ); - // If we change the two "borrow" below to "borrow_mut", you can get a panic even with a "call" that requires a - // mutable borrow. However, that panic is then triggered by our own, external `RefCell` (so it's kind of our fault), - // rather than being triggered by the `RefCell` in the `Callbacks`. { let c2 = c.clone(); - c.borrow_mut().register(move |val| c2.borrow().call(val+val) ); + c.borrow_mut().register(move |val| { + let mut guard = c2.borrow_mut(); + println!("Callback called with {}, ready to go for nested call.", val); + guard.call(val+val) + } ); } - c.borrow().call(42); + // We do a clone, and call `call` on that one. This makes sure that it's not our `RefCell` that complains about two mutable borrows, + // but rather the `RefCell` inside the `CallbacksMut`. + let mut c2: Callbacks = c.borrow().clone(); + drop(c); + c2.call(42); } } \ No newline at end of file