error: `T` does not live long enough

error - HRTB の機能制限』の GAT についての派生パターン。

このエラーは 、GAT に残る制限の一つ。

詳細

GAT のライフタイム引数は Self を境界づける場合が多い。そのため、このライフタイム引数が HRTB から与えられると、HRTB の制限により、Self'static から参照できなければならなくなる。これはとても厳しい制限となる。

サンプル

以下では、メソッド allSelf::Element<'_> の箇所で、GAT に暗黙の HRTB が使われている。そして、Element<'a> は境界条件 Self: 'a を持つ。そのため、all を実行する変数 array'static から参照できなければならない。しかし、array の型 T はその境界を持たない (境界を追加するとエラーは解消する)。


fn main() {
    assert!(all_positive(vec![1, 2, 3]));
}

fn all_positive<T>(array: T) -> bool
where
    T: for<'a> Array<Element<'a> = &'a i32>,
{
    array.all(|&x| x > 0)
}

trait Array {
    type Element<'a> where Self: 'a;

    fn get(&self, index: usize) -> Option<Self::Element<'_>>;

    fn all<F>(&self, f: F) -> bool
    where
        F: Fn(Self::Element<'_>) -> bool,
    {
        for i in 0.. {
            let Some(elm) = self.get(i) else { return true };
            if !f(elm) {
                return false;
            }
        }

        unreachable!();
    }
}

impl Array for Vec<i32> {
    type Element<'a> = &'a i32 where Self: 'a;

    fn get(&self, index: usize) -> Option<Self::Element<'_>> {
        (self as &[_]).get(index)
    }
}

error: `T` does not live long enough
 --> src\main.rs:9:5
  |
9 |     array.all(|&x| x > 0)
  |     ^^^^^^^^^^^^^^^^^^^^^