简体   繁体   中英

What is the meaning of 'a: 'a in generic lifetime parameters?

I have a strange piece of code:

#![allow(unused)]

fn f<'a>() {}
fn g<'a: 'a>() {}

fn main() {
    // let pf = f::<'static> as fn(); // (7)
    let pg = g::<'static> as fn();    // (8)
    //print!("{}", pf == pg);
}

The 7th line cannot be compiled if it is uncommented (with the error below), but the 8th line can be compiled.

error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
 --> src/main.rs:7:18
  |
7 |     let pf = f::<'static> as fn(); // (7)
  |                  ^^^^^^^
  |
note: the late bound lifetime parameter is introduced here
 --> src/main.rs:3:6
  |
3 | fn f<'a>() {}
  |      ^^

What is the meaning of 'a: 'a in line 4?

I have found nothing in the rust documentation to confirm, but it seems that <'a: 'a> is short to qualify the output lifetime of the function (cf lifetime output in the documentation).

Here are some tests that seem confirm that:

#![allow(unused)]

fn f<'a>() {}
fn g<'a: 'a>() {}
fn h<'a: 'a>() -> &'a i32 { &5 }
fn i<'a>() -> &'a i32 { &6 }

fn tst1<'b>() {
   let w:&'b i32 = &6;
   //let pj = f::<'b> as fn();
   let pk = i::<'b> as fn() -> &'b i32;
}

fn tst2<'b>() {
   let pr = g::<'b> as fn();
}
fn main() {
    //let pf = f::<'static> as fn(); // (7)
    let pg = g::<'static> as fn();    // (8)
    let ph = h::<'static> as fn() -> &'static i32;
    let pi = i::<'static> as fn() -> &'static i32;

    //print!("{}", pf == pg);
}

This compile with Rustc 1.41.1. It's possible that recent updates impact this.

As you could see, let pi and let pk compile for fn i<'a>() , but not let pf nor let pj for fn f<'a>() . The fn i<'a>() only differs from fn f<'a>() as the former returns a value thus implying a output liftetime for the function.

The tst1 and tst2 verify this with inner lifetime of a function.

It cannot be 100% sure without documentation reference, but it seems that if you don't specify a output to your function, you still have, for function's pointers, to have a defined output lifetime, and <'a: 'a> seems implying that.

Regarding dtolnay quizz thanks to @Konstantin W, it seems that output lifetime of the function become earlier bounded with <'a: 'a> and the compiler doesn't scream in that case when assigning the 'static lifetime at the pointer assignation.

If that's the case, let pi and let pk compile for fn i<'a>() probably because the i function is fully defined in input like output then lifetime assignation could be done at pointer assignation ( or the specified output implies earlier bounding for both input and output timeline , but I've a hard time believing that). Maybe an undocumented rust lifetime Elision rule too.

The a in 'a is just a name. You could call it 'mylifetime or 'golden_eternal_braid if you want to. The meaining of any lifetime parameter in that position is just to declare it. Lifetimes other than 'static are not defined globaly, so you can't declare a function as

fn f(param: &'a SomeType) {} // error

... but if you declare it, you can:

fn f<'a>(param: &'a SomeType) {} // ok

Of course, you could just as well leave that lifetime to be infered, declaring the function as

fn f(param: &SomeType) {}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM