0
fn f<'a: 'b, 'b>(x: &'a i32, mut y: &'b i32) -> &'b i32 {
    y = x;  
      
    y
}

let long_var = 1;
let long_lifetime = &long_var;
{
    let short_var = 2;
    let short_lifetime = &short_var; 
    // it works, why?
    let x = f(short_lifetime, long_lifetime); 
};

There is limitation 'a: 'b in the function f, so why let x = f(short_lifetime, long_lifetime); works?

wangliqiu
  • 369
  • 1
  • 9
  • Related: https://stackoverflow.com/questions/42637911/how-can-this-instance-seemingly-outlive-its-own-parameter-lifetime – E_net4 Mar 03 '23 at 11:35

2 Answers2

4

Because lifetimes in function parameters are bounds, not strict lifetimes. So when you call f(short_lifetime, long_lifetime), the compiler tries to find lifetimes 'a and 'b such that:

  • short_lifetime lives at least as long as 'a (but it may live longer),
  • long_lifetime lives at least as long as 'b (but it may live longer),
  • 'a is at least as long as 'b (but they may be equal),
  • the returned value lives at most as long as 'b (but it may live shorter).

One possible solution is to take 'a == 'b lasting from the function call to the first closing }. This fits all the above constraints (long_lifetime actually lives longer than 'b but that's allowed since the lifetimes are only bounds and not strict).

Jmb
  • 18,893
  • 2
  • 28
  • 55
1

'a: 'b reads 'a outlives 'b. So the lifetimes in your example are reversed, 'a is the long lifetime and 'b is the short one. The code compiles, because you can always cast a reference from a longer lifetime to a shorter lifetime (i.e. cast a reference &'a to &'b in your case). Read more in the reference

Jonas Fassbender
  • 2,371
  • 1
  • 3
  • 19