// normalize-stderr-test: "long-type-\d+" -> "long-type-hash" // rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream Option; } // Example stream pub struct Repeat(u64); impl<'a> Stream for &'a mut Repeat { type Item = &'a u64; fn next(self) -> Option { Some(&self.0) } } pub struct Map { stream: S, func: F, } impl<'a, A, F, T> Stream for &'a mut Map where &'a mut A: Stream, F: FnMut(<&'a mut A as Stream>::Item) -> T, { type Item = T; fn next(self) -> Option { match self.stream.next() { Some(item) => Some((self.func)(item)), None => None, } } } pub struct Filter { stream: S, func: F, } impl<'a, A, F, T> Stream for &'a mut Filter where for<'b> &'b mut A: Stream, // <---- BAD F: FnMut(&T) -> bool, { type Item = <&'a mut A as Stream>::Item; fn next(self) -> Option { while let Some(item) = self.stream.next() { if (self.func)(&item) { return Some(item); } } None } } pub trait StreamExt where for<'b> &'b mut Self: Stream, { fn mapx(self, func: F) -> Map where Self: Sized, for<'a> &'a mut Map: Stream, { Map { func: func, stream: self } } fn filterx(self, func: F) -> Filter where Self: Sized, for<'a> &'a mut Filter: Stream, { Filter { func: func, stream: self } } fn countx(mut self) -> usize where Self: Sized, { let mut count = 0; while let Some(_) = self.next() { count += 1; } count } } impl StreamExt for T where for<'a> &'a mut T: Stream {} fn identity(x: &T) -> &T { x } fn variant1() { let source = Repeat(10); // Here, the call to `mapx` returns a type `T` to which `StreamExt` // is not applicable, because `for<'b> &'b mut T: Stream`) doesn't hold. // // More concretely, the type `T` is `Map`, and // the where clause doesn't hold because the signature of the // closure gets inferred to a signature like `|&'_ Stream| -> &'_` // for some specific `'_`, rather than a more generic // signature. // // Why *exactly* we opt for this signature is a bit unclear to me, // we deduce it somehow from a reuqirement that `Map: Stream` I // guess. let map = source.mapx(|x: &_| x); let filter = map.filterx(|x: &_| true); //~^ ERROR the method } fn variant2() { let source = Repeat(10); // Here, we use a function, which is not subject to the vagaries // of closure signature inference. In this case, we get the error // on `countx` as, I think, the test originally expected. let map = source.mapx(identity); let filter = map.filterx(|x: &_| true); let count = filter.countx(); //~^ ERROR the method } fn main() {}