Where does reference doucment that the default lifetime trait bound in return position of impl trait is `'static`

trait MyTrait{
    fn convert(&self)->i32;
}
impl MyTrait for &i32{
    fn convert(&self)->i32{
        0
    }
}
fn show()->impl MyTrait{
    let i = 0;
    let rf = &i;
    rf
}

The compiler reports an error that:

| -- opaque type requires that i is borrowed for 'static

However, in rust reference, I don't find the relevant section that documents the lifetime trait bound in opaque type is defaulted to 'static. Where can I find the documents?

Regardless of what defaults are in effect, this code is wrong. You are trying to return a reference to a local, which would be immediately dangling. No signature and no lifetime annotations can make this code compile.

impl Trait in return position isn't always 'static.

Compare:

trait MyTrait<'a> {
    fn convert(&'a self) -> i32;
}
impl<'a> MyTrait<'a> for &i32{
    fn convert(&'a self) -> i32 {
        0
    }
}
fn show<'a>(rf: &'a i32) -> impl MyTrait<'a> {
    rf
}

(Playground)

You need the explicit lifetime with impl Trait (as in impl Trait + 'a) for it to be able to "capture" any lifetime, if it doesn't appear otherwise in it.


Generally, the lifetime bounds in impl work differently than in dyn. (I think)

Yeah, the problem is that you're returning a reference to a local variable.

Anyway, to understand where the error comes from: The meaning of "this type is 'a" is "this type has no lifetime annotations shorter than 'a". Since your return type has no lifetime annotations, it has no lifetime annotations shorter than 'static. This makes it 'static.

2 Likes

Yes, I know a local borrowing cannot be returned. This is not the question, I was asking what the default lifetime trait bound of an opaque type is in the return position, this is my subject.

The implementation of MyTrait<'a> for &'b i32 requires that 'b: 'a, then rf has type &'a i32, implementing MyTrait<'a> for &'a i32 requires 'a: 'a, which does not conflict, hence rf can be returned. However, in my case, I asked where the 'static trait bound was sourced from.

I know, but unfortunately, the code being incorrect precludes any useful discussion about other such things. The fact that you are trying to return a reference to a local may generate all sorts of spurious errors and make it look like there's a "default" (which in fact there isn't).

If you want to ask about the behavior of impl Trait, you should come up with an example that is correct and doesn't confuse the compiler.

I think the question is quite reasonable. It's non-trivial why the compiler chooses to talk about 'static in the error message.

2 Likes

I had the same question before, about official documentations on lifetime rules on impl Trait.

And the history of impl Trait is fairly complicated, like:

And some quotes from RFC2071:

Similarly to impl Trait under RFC 1951, existential type implicitly captures all generic type parameters in scope.
However, as in 1951, lifetime parameters must be explicitly annotated.

So 1951-expand-impl-trait is what you're asking for.

Update: oh wait, there is a working group for it 👋 Welcome - Impl trait initiative .

2 Likes

After a quick browse, my answer to the OP would be "the reference doesn't properly document this (RPIT lifetime capture) at all."

Some relevant citations as to how they do work are

And for the example at hand, no lifetimes are captured, which means that the RPIT satisfies a 'static bound.


  1. chase the citations for more details ↩ī¸Ž

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.