HRTB: конкретный тип, ограниченный признаком, содержащим параметр типа времени жизни, и ограниченный только параметром типа времени жизни - PullRequest
2 голосов
/ 12 января 2020

Это на самом деле ответвление этого 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 временем жизни (ями)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...