Hi Guys,
I'm calling a method to return a mutable reference in a block. As my understanding, the mutable reference should be invalid when the block ends and I should be able to use immutable reference again.
However, the compiler refused.
#[derive(Debug)]
pub struct X<'a> {
data: &'a mut u64,
}
impl<'a: 'b, 'b> X<'a> {
pub fn as_xref(&'a mut self) -> &'b mut X {
self
}
}
fn main() {
let mut data: u64 = 5;
let mut wrapper = X{data: &mut data};
println!("{:?}", wrapper);
{
let r = wrapper.as_xref();
*r.data += 3;
}
println!("{:?}", wrapper);
}
The error is as below:
Compiling playground v0.0.1 (/playground)
error[E0502]: cannot borrow `wrapper` as immutable because it is also borrowed as mutable
--> src/main.rs:25:22
|
19 | let r = wrapper.as_xref();
| ------- mutable borrow occurs here
...
25 | println!("{:?}", wrapper);
| ^^^^^^^
| |
| immutable borrow occurs here
| mutable borrow later used here
|
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
When I tried to get the mutable reference with & operator, the thing is different and I don't understand why.
#[derive(Debug)]
pub struct X<'a> {
data: &'a mut u64,
}
impl<'a: 'b, 'b> X<'a> {
pub fn as_xref(&'a mut self) -> &'b mut X {
self
}
}
fn main() {
let mut data: u64 = 5;
let mut wrapper = X{data: &mut data};
println!("{:?}", wrapper);
{
let r = &mut wrapper;
*r.data += 3;
}
println!("{:?}", wrapper);
}
Compiling playground v0.0.1 (/playground)
Finished dev [unoptimized + debuginfo] target(s) in 0.44s
Running `target/debug/playground`
X { data: 5 }
X { data: 8 }