Emulate reborrowing for user types.
Given a &'a
[mutable] reference of a &'b
view over some owned object,
reborrowing it means getting an active &'a
view over the owned object,
which renders the original reference inactive until it's dropped, at which point
the original reference becomes active again.
derive
: This imports a derive macro helper for implementing reborrow for user
types. It can be used with a Ref/RefMut
pair of structs/tuple structs with
the same member names, one containing shared references and the other mutable
references. The shared variant must be Copy
, and the macro is used on the
mutable variant and generates the relevant traits for both types.
This fails to compile since we can't use a non-Copy
value after it's moved.
```rust
fn takesmutoption(o: Option<&mut i32>) {}
let mut x = 0;
let o = Some(&mut x);
takesmutoption(o); // o
is moved here,
takesmutoption(o); // so it can't be used here.
```
This can be worked around by unwrapping the option, reborrowing it, and then wrapping it again. ```rust fn takesmutoption(o: Option<&mut i32>) {}
let mut x = 0;
let mut o = Some(&mut x);
takesmutoption(o.asmut().map(|r| &mut **r)); // "Reborrowing" the Option
takesmutoption(o.asmut().map(|r| &mut **r)); // allows us to use it later on.
drop(o); // can still be used here
```
Using this crate, this can be shortened to ```rust use reborrow::ReborrowMut;
fn takesmutoption(o: Option<&mut i32>) {}
let mut x = 0;
let mut o = Some(&mut x);
takesmutoption(o.rbmut()); // "Reborrowing" the Option
takesmutoption(o.rbmut()); // allows us to use it later on.
drop(o); // can still be used here
```
The derive macro can be used with structs or tuple structs, and generates
the trait definitions for Reborrow
and ReborrowMut
.
```rust mod shared { #[derive(Clone, Copy)] pub struct I32Ref<'a, 'b> { pub i: i32, pub j: &'a i32, pub k: &'b i32, }
#[derive(Clone, Copy)]
pub struct I32TupleRef<'a, 'b>(pub i32, pub &'a i32, pub &'b i32);
}
struct I32RefMut<'a, 'b> { #[copy] // #[copy] means that the field should be copied instead of reborrowed. i: i32, j: &'a mut i32, k: &'b mut i32, }
pub struct I32TupleRefMut<'a, 'b>( #[copy] i32, // #[copy] means that the field should be copied instead of reborrowed. &'a mut i32, &'b mut i32, ); ```