note: due to current limitations in the borrow checker, this implies a `'static` lifetime

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

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

詳細

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

サンプル

以下では、関数 averageT::IntStream<'a> の箇所で、GAT に HRTB が使われている。そして、IntStream<'a>Self: 'a の境界を持つ。そのため、T'static から参照できなければならない。しかし、変数 vp&vec を含んでおり、この境界を満足できない。


use std::slice::Iter;

fn main() {
    let vec = vec![1, 2, 3];
    let vp = IntVecPointer(&vec);
    average::<IntVecPointer>(vp);
}

trait IntCollection {
    type IntStream<'a>: Iterator<Item = &'a i32> where Self: 'a;
    fn int_stream(&self) -> Self::IntStream<'_>;
}

struct IntVecPointer<'v>(&'v Vec<i32>);
impl<'v> IntCollection for IntVecPointer<'v> {
    type IntStream<'a> = Iter<'a, i32> where Self: 'a;
    fn int_stream(&self) -> Self::IntStream<'_> {
        self.0.iter()
    }
}

fn average<T>(arg: T) -> f32
where
    T: IntCollection,
    for<'a> T::IntStream<'a>: ExactSizeIterator,
{
    let stream = arg.int_stream();
    let len = stream.len();
    let sum = stream.sum::<i32>();
    sum as f32 / len as f32
}

error[E0597]: `vec` does not live long enough
  --> src\main.rs:5:28
   |
4  |     let vec = vec![1, 2, 3];
   |         --- binding `vec` declared here
5  |     let vp = IntVecPointer(&vec);
   |                            ^^^^ borrowed value does not live long enough
6  |     average::<IntVecPointer>(vp);
   |     ---------------------------- argument requires that `vec` is borrowed for `'static`
7  | }
   | - `vec` dropped here while still borrowed
   |
note: due to current limitations in the borrow checker, this implies a `'static` lifetime
  --> src\main.rs:25:31
   |
25 |     for<'a> T::IntStream<'a>: ExactSizeIterator,
   |                               ^^^^^^^^^^^^^^^^^