Thanks for your link. I have read that document. I have certain issues with the document and the relevant conclusion in your answers.
- Seems that "Supporting prefixes" and your conclusion:
the lifetime of a reborrow will be capped by the first shared reference if there is one, and otherwise by the shortest (outermost) lifetime.
does not apply to the simple case, consider the first example in the document
let x: &'x i32 = ...;
let y: &'y i32 = &*x;
If we were to use "Supporting prefixes" to think about this example, the path would be *x
because x
is a shared reference, so we just stop at *x
, which would mean 'y == 'x
, your conclusion would also have the same result. However, the example says 'x:'y
- Seems there is something wrong with the second example of the document, the comment says
Therefore, we would add one reborrow constraint: that 'a: 'c
. This constraint ensures that as long as r_c
is in use, the borrow of foo
remains in force, but the borrow of r_a
(which has the lifetime 'b
) can expire.
Recall the example
let mut foo: i32 = 22;
let mut r_a: &'a i32 = &'a foo;
let r_b: &'b &'a i32 = &'b r_a;
let r_c: &'c i32 = &'c **r_b;
// What is considered borrowed here?
use(r_c);
According to the "Supporting prefixes" criteria, the path should be **r_b
because *r_b
is a shared reference, so what is the relevant lifetime that will be used in the constraint to 'c
? This will be the third issue, however, according to the context of the whole document, I suppose it is the lifetime of value represented by *r_b
(not sure), but *r_b
will acquire the reference r_a
whose lifetime is 'a
that is used in the comment
Therefore, we would add one reborrow constraint: that 'a: 'c
.
The wrong is exact in the last sentence
This constraint ensures that as long as r_c
is in use, the borrow of foo
remains in force, but the borrow of r_a
(which has the lifetime 'b
) can expire.
r_a
anyway has the lifetime 'a
, why does it say 'b
? Seems it should say r_b
can expire.
- According to the "Supporting prefixes" criterial, the document didn't clearly specify which lifetime will be used in the reborrow constraint. The lifetime seems to need to be determined by the form of the eventual path, I think
Consider such two contrast example
let mut foo: i32 = 22;
let r_a: &'a mut i32 = &'a mut foo;
let r_b: &'b mut i32 = &'b mut *r_a;
In this example, the lifetime in the reborrow constraint for lifetime 'b
is 'a
that is the lifetime of r_a
, the eventual path in the supporting prefixes is r_a
, which is a named variable.
Then, we consider the example whose eventual path is a DereferenceExpression
let mut foo: i32 = 22;
let mut r_a: &'a i32 = &'a foo;
let r_b: &'b &'a i32 = &'b r_a;
let r_c: &'c i32 = &'c **r_b;
Again, the eventual path in this example for r_c
is **r_b
, so what stuff in the path whose lifetime will determine the constraint? Is the reference designated by *r_b
or the named variable r_b
? It seems *r_b
whose lifetime is 'a
.
So, for the third issue, I have the conclusion that
If the eventual path is a named variable, the lifetime of the variable determines the reborrow constraint
If the path is a DereferenceExpression, the lifetime of the value designated by the operand of the DereferenceExpression determines the reborrow constraint
Is this conclusion correct? For example
let mut i = 0;
let mrf:&'a mut i32 = &'a mut i;
let rrmrf:&'b &'a mut i32 = &'b mrf;
let e:&'c &'_ mut i32 = &*rrmrf;
The eventual path of e
is just *rrmrf
since rrmrf
is a shared reference, since it is a DereferenceExpression, the constraint to the lifetime of e
should be determined by rrmrf
? Namely, 'b :'c