This code here (A) works:
struct Object {
x: u8
}
struct Iter<'a> {
link: &'a Object
}
impl<'a> Iterator for Iter<'a> {
type Item = u8;
fn next(&mut self) -> Option<Self::Item> {
let _: &'a Object = self.link;
None
}
}
However, changing link
to become a mutable reference like so (B):
struct Iter<'a> {
link: &'a mut Object
}
gives a compiler error:
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
--> src\lib.rs:14:29
|
14 | let _: &'a Object = self.link;
| ^^^^^^^^^
|
note: ...the reference is valid for the lifetime `'a` as defined here...
--> src\lib.rs:10:6
|
10 | impl<'a> Iterator for Iter<'a> {
| ^^
note: ...but the borrowed content is only valid for the anonymous lifetime defined here
--> src\lib.rs:13:13
|
13 | fn next(&mut self) -> Option<Self::Item> {
| ^^^^^^^^^
If I understand things correctly, this is because in (A) the let _ ...
line just creates another copy of the reference and is able to preserve 'a
, while in (B) it has to do a reborrow with the anonymous next
lifetime '1
of self
, which prevents the let
assignment from happening.
Three questions:
- Is my understanding so far correct?
- If I transmuted that lifetime would that be sound? I'd argue it should be, since
link
guarantees the pointer as exactly the lifetime I'm asking for, andself
isn't being used anymore. Admittedly my real example is more complex, but even then, if I stopped usingself
after obtaining the link there should be no aliasing happening and lifetimes should be correct, right? - Is there a way to fix (B) without unsafe code?