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?
A generic lifetime parameter imposes a lifetime constraint on the reference(s) and the return value(s) of a function.
Lifetimes are what the Rust compiler uses to keep track of how long references are valid for. Checking references is one of the borrow checker's main responsibilities. Lifetimes help the borrow checker ensure that you never have invalid references.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With