note: due to current limitations in the borrow checker, this implies a `'static` lifetime
『E0597 - HRTB の機能制限』の GAT についての派生パターン。
このエラーは 、GAT に残る制限の一つ。
GAT のライフタイム引数は Self
を境界づける場合が多い。そのため、このライフタイム引数が HRTB から与えられると、前述の HRTB の制限により、Self
を 'static
から参照できなければならなくなる。これはとても厳しい制限となる。
以下では、関数 average
の T::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, | ^^^^^^^^^^^^^^^^^