Why does Rust allow this code to compile despite the Invariance of &mut T?
⚓ Rust 📅 2026-02-11 👤 surdeus 👁️ 2fn f<'a, 'b>(n: &'a mut &'b mut i32) where 'a: 'b, 'b: 'a {}
fn x() -> &'static mut i32 {
todo!()
}
fn main() {
let mut n = x(); // n is &'static mut i32
f(&mut n);
}
Question: According to Rust's subtyping rules, &mut T is invariant over T. In this example, T is &'b mut i32.
When calling f(&mut n), since n is of type &'static mut i32, the invariant rule implies that f should expect the exact type &'a mut &'static mut i32. However, the function signature of f contains the constraint where 'a: 'b, 'b: 'a, which effectively forces 'a == 'b.
This means the call f(&mut n) would require the argument to satisfy the type &'static mut &'static mut i32. But &mut n (the reborrow of a local variable on the stack) clearly cannot have a 'static lifetime.
Given that &mut T is invariant, why does the compiler allow this code to compile instead of rejecting it due to a lifetime mismatch?
2 posts - 1 participant
🏷️ Rust_feed