Open
Description
#![feature(trusted_len)]
use std::iter::TrustedLen;
use std::marker::PhantomData;
pub struct MaybeTrusted<'a, I>(I, PhantomData<fn(&'a ()) -> &'a ()>);
impl<'a, I: Iterator> Iterator for MaybeTrusted<'a, I> {
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
/// This is safe, as a `'static` version of this struct can only be created
/// using a trusted iterator.
unsafe impl<I: Iterator> TrustedLen for MaybeTrusted<'static, I> {}
impl<I: TrustedLen> MaybeTrusted<'static, I> {
pub fn new(value: I) -> Self {
MaybeTrusted(value, PhantomData)
}
}
/// `I` might not implement `TrustedLen`, but that's ok,
/// because you can't get a `MaybeTrusted<'static, I>` from this.
pub fn not_trusted<I: Iterator, T>(i: I, f: impl for<'a> FnOnce(MaybeTrusted<'a, I>) -> T) -> T {
f(MaybeTrusted(i, PhantomData))
}
// In a separate crate:
struct Liar(usize);
impl Iterator for Liar {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
if self.0 < 10000 {
self.0 += 1;
Some(self.0)
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
// happy little accident, but ok, doesn't implemented `TrustedLen`.
let len = self.0.saturating_sub(10000);
(len, Some(len))
}
}
fn main() {
not_trusted(Liar(0), |iter| iter.collect::<Vec<_>>());
}
results in:
Segmentation fault (core dumped)