Why does Rust allow this code to compile despite the Invariance of &mut T?

⚓ Rust    📅 2026-02-11    👤 surdeus    👁️ 2      

surdeus

fn 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

Read full topic

🏷️ Rust_feed