I have encountered a certain behavior of the borrow checker that I find rather odd: if I have a &'a mut &'b mut T where 'b: 'a, T: 'b, it seems as though I should be able to treat it as just a &'b mut T, since I can guarantee that I have mutable access to the T for at least as long as 'b. So, in its simplest form, (I think) I should be able to make a function such as this:
fn f<'a, 'b: 'a, T: 'b>(x: &'a mut &'b mut T) -> &'b mut T { *x } However, the borrow checker doesn't like that, saying
error[E0623]: lifetime mismatch --> src/main.rs:6:5 | 5 | fn f<'a, 'b: 'a, T: 'b>(x: &'a mut &'b mut T) -> &'b mut T { | ----------------- | | | these two types are declared with different lifetimes... 6 | *x | ^^ ...but data from `x` flows into `x` here My primary question is, why?
My secondary question is, are there safe ways to work around this? I'm aware that I can cast it to a pointer and then turn it back into a reference, magically summoning whatever lifetime I want in the process, but that requires unsafe code. I would like to know if there are safe ways to do this, either in general or for specific circumstances (including circumstances in which specific unsafe code can be verified by the programmer to be safe).
As an example, my actual use case is an iterator that returns mutable references like std::slice::IterMut<'a, T> and that family of iterators; I have something along the lines of
struct IterMut<'a, T> { source: &'a mut MyContainer<T>, ... /* other data for iterating */ } impl<'a, T> Iterator for IterMut<'a, T> { type Item = &'a mut T; fn next(&mut self) -> Option<&'a mut T> { ... } } The problem is that inside the next method, I can only access the source reference through the &mut self, effectively creating a &mut &'a MyContainer<T>, which restricts my ability to borrow from source to the anonymous lifetime from &mut self, a la this question.
So in summary, why is this like this, and what steps can I take to avoid this problem?
'b: 'ameans that'bis at least as long as'a; i.e.'amay end before'b. see e.g. here. your function signature would work if you returned&'a mut T(i.e. the shorter lifetime, wherexis guaranteed to be valid).