HRTB: Concrete type bounded by a trait containing lifetime type parameter vs bounded by only a lifetime type parameter

一世执手 提交于 2020-02-04 03:58:26

问题


This is actually an offshoot of this SO question.

Consider the following code:

trait Trait<'b> {
    fn func(&'b self) {}
}

struct Struct {}

impl<'s> Trait<'s> for Struct {}

fn test<'s, T:'s>(t: T)
where
    T: Trait<'s>,
{
    t.func();
}

It fails, as the compiler sees that t lives for less than the 's and 's is set by the caller (i.e longer than the stack-frame of the func) and traits are invariant over type parameters. However, if I introduce HRTB (Higher Rank Trait Bounds) here, the code compiles:

fn test<T>(t: T)
where
    T: for<'s> Trait<'s>,
{
    t.func();
}

Now, the trait Trait<'s> is implemented for all possible lifetimes 's represents and accordingly the right one gets picked by the compiler.

But then why the following code fails ?

struct Temp<'a> {
    x: &'a i32,
}

fn test<T>(t: T)
where
    for<'s> T: 's,
{
}

fn main() {
    let d = 1i32;
    test(Temp { x: &d });
}

It gives the error:

error[E0597]: `d` does not live long enough
  --> src/main.rs:13:20
   |
13 |     test(Temp { x: &d });
   |     ---------------^^---
   |     |              |
   |     |              borrowed value does not live long enough
   |     argument requires that `d` is borrowed for `'static`
14 | }
   | - `d` dropped here while still borrowed

What is the difference here? Conceptually, I found the earlier example same as this one. Why it is expected that the concrete type T should only be/contain reference(s) with 'static lifetime(s) ?

来源:https://stackoverflow.com/questions/59701560/hrtb-concrete-type-bounded-by-a-trait-containing-lifetime-type-parameter-vs-bou

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!