I had written the bad code(I think) like this:
struct Type<T> {
x: T,
}
let mut a = Type{x: 5};
let b = &mut a;
{
let c = b;
}
// println!("{:?}", a); it can't work
It can compile, but I can't access a after out of inner scope , because a is borrowed as mutable. Then I try it by b, as we can see, b has been moved, and also can't by c, it end out of inner scope.So I can't use a any longer, Resource Type{x:5} has been cleared or still there?
And I change mutable to immutable as follow, it can access resource.
#[derive(Debug)]
struct Type<T> {
x: T,
}
let a = Type{x: 5};
let b = &a;
{
let c = b;
}
println!("{:?}", a);
I am not really sure if the below writeup is correct so please do correct me if I am wrong.
#[derive(Debug)]
struct Type<T> {
x: T,
}
let mut a = Type{x: 5};
// a is now owned
let b = &mut a;
// a is now mutably borrowed and stored as a reference in b
{
let c = b;
// b is now moved to c and therefore the variable b is "cleared" of content
}
// the lifetime of c is over therefore the borrow of a should end and a should be accessible again
Is this some sort of compiler bug or did I misunderstand lifetimes and borrows?
Thanks, I also think borrow of a end and it can be accessed again, but when I try, complier don't allow. I 'am not sure a is cleared or it still there ?
a
is definitely not cleared, a
is borrowed from.
Lifetimes in Rust are currently tied to lexical scopes. When you borrow a reference and assign it to a variable, the borrow must have a lifetime at least as long as the variable's scope. There's no way (yet) to end a borrow "early" by dropping or moving it.
{
let mut a = Type{x: 5};
let b = &mut a; // <-+- borrow starts here
{ // |
let c = b; // |
} // |
} // <-+- and ends here, no matter what happens in between
This problem is explained in detail, along with some proposed future solutions, in @nikomatsakis’s recent articles on non-lexical lifetimes.
1 Like
That means the original example would need to be written as the following?
#[derive(Debug)]
struct Type<T> {
x: T,
}
let mut a = Type{x: 5};
{
let b = &mut a;
{
let c = b;
}
}
Yes, you can shorten the borrow of a
by limiting the scope of b
.