How to explain why the following code cannot be compiled?

⚓ Rust    📅 2025-12-23    👤 surdeus    👁️ 1      

surdeus

well, I am learning subtyping rules of rust, and I am encountering the idea "Invariant". What I understood of "Invariant" is that : Given a generic type F, for a subtype Sub and its super type Super, F<Sub> is not subtype of F<Super> and F<Sub> is not super type of F<Sub> either. Only if when Sub == Super, F<Sub> == F<Super>. And I want a concrete example to validate my thought. And I try to write some codes.

The first case that I wrote is :

fn foo<'a: 'b, 'b>(x: &'a mut &'a i32, y: &'a mut &'b i32) {
    *y = *x;
}

fn main() {
    let a = 123;
    {
        let b = 134;
        let mut a_r = &a;
        let mut x = &mut a_r;
        {
            let mut b_r = &b;
            let mut y = &mut b_r;
            foo(x, y);
            println!("{}", *x);
        }
    }
}

And it cannot be compiled which matches my thought.
But when I substitute foo(x, y) with *y = *x which is as following

fn foo<'a: 'b, 'b>(x: &'a mut &'a i32, y: &'a mut &'b i32) {
    *y = *x;
}

fn main() {
    let a = 123;
    {
        let b = 134;
        let mut a_r = &a;
        let mut x = &mut a_r;
        {
            let mut b_r = &b;
            let mut y = &mut b_r;
            // foo(x, y);
            *y = *x;
            println!("{}", *x);
        }
    }
}

It can be compiled now! why ? is there a special rule implemented for intra-function lifetime inference?

3 posts - 2 participants

Read full topic

🏷️ Rust_feed