Why can I not borrow &mut x
multiple times when using is_mut_t
. But it's fine with is_mut_specific
?
#[cfg(test)]
mod test {
use std::marker::PhantomData;
#[test]
fn test_wc() {
struct Test<T>{ phantom_data: PhantomData<T>}
impl <T> Test<T> {
fn new() -> Self {
Test { phantom_data: PhantomData }
}
fn is_mut_t(&mut self, i: T) {}
fn is_mut_specific(&mut self, i: &mut i32) {}
}
let mut x = 5;
let mut t: Test<&mut i32> = Test::new();
t.is_mut_specific(&mut x);
t.is_mut_specific(&mut x);
// t.is_mut_t(&mut x);
// t.is_mut_t(&mut x);
}
}
Let's give names for lifetimes (using imaginary syntax):
#[cfg(test)]
mod test {
use std::marker::PhantomData;
#[test]
fn test_wc() {
struct Test<T> { phantom_data: PhantomData<T> }
impl<T> Test<T> {
fn new() -> Self {
Test { phantom_data: PhantomData }
}
fn is_mut_t<'a>(&'a mut self, i: T) {}
fn is_mut_specific<'b, 'c>(&'b mut self, i: &'c mut i32) {}
}
let mut x = 5;
let mut t: Test<&'d mut i32> = Test::new();
(&'e mut t).is_mut_specific::<'e, 'f>(&'f mut x);
(&'g mut t).is_mut_specific::<'g, 'h>(&'h mut x);
// (&'i mut t).is_mut_t::<'i>(&'j mut x);
// (&'k mut t).is_mut_t::<'k>(&'l mut x);
}
}
Each occurrence of T
is replaced by &'d mut i32
. Can you spot the problem?
When we say &mut i32
in the signature, that gets assigned a generic lifetime that can be any.
But when we say T
, that must be exactly the same as T
. And that includes the same lifetime. But if we borrow x
for 'd
, we cannot borrow it again in 'd
, which means at least as long as t
exists.