Это на самом деле ответвление этого SO вопроса.
Рассмотрим следующий код:
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();
}
Сбой, так как компилятор видит, что t
живет меньше, чем 's
и 's
устанавливается вызывающей стороной (т.е. длиннее стека фрейма func
) и черты являются инвариантными по отношению к параметрам типа. Однако, если я введу здесь HRTB (границы черт с более высоким рангом), код скомпилируется:
fn test<T>(t: T)
where
T: for<'s> Trait<'s>,
{
t.func();
}
Теперь черта Trait<'s>
реализована для всех возможных времен жизни, которые представляет 's
, и, соответственно, получает правильный выбирается компилятором.
Но тогда почему следующий код не работает?
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 });
}
Выдает ошибку:
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
В чем здесь разница? Концептуально я нашел предыдущий пример такой же, как этот. Почему ожидается, что конкретный тип T
должен быть только / содержать ссылку (ии) с 'static
временем жизни (ями)?