Closed
Description
STR
#![feature(unboxed_closures)]
trait IteratorExt2<A> {
fn inspect2<F>(self, f: F) -> Inspect<A, Self, F> where F: FnMut(&A);
}
struct Inspect<A, I, F> where I: Iterator<A>, F: FnMut(&A) {
iter: I,
f: F,
}
fn main() {
let xs = [1u, 2, 3, 4];
// Trigger
let mut n = 0; // Err
//let mut n = 0u; // Ok
let ys = xs.iter()
.map(|&x| x)
.inspect2(|_| n += 1)
//~^ error: unable to infer enough type information about `closure`; type annotations required
//.inspect2(|&mut: _| n += 1) // This doesn't work either (same error as above)
.collect::<Vec<uint>>();
// NOTE: This constrains `n` to be `uint`
assert_eq!(n, xs.len());
assert_eq!(xs[], ys[]);
}
impl<A, I> IteratorExt2<A> for I where I: Iterator<A> {
fn inspect2<F>(self, f: F) -> Inspect<A, I, F> where F: FnMut(&A) {
Inspect {
iter: self,
f: f,
}
}
}
impl<A, I, F> Inspect<A, I, F> where I: Iterator<A>, F: FnMut(&A) {
#[inline]
fn do_inspect(&mut self, elt: Option<A>) -> Option<A> {
match elt {
Some(ref a) => (self.f)(a),
None => ()
}
elt
}
}
impl<A, I, F> Iterator<A> for Inspect<A, I, F> where I: Iterator<A>, F: FnMut(&A) {
fn next(&mut self) -> Option<A> {
let next = self.iter.next();
self.do_inspect(next)
}
fn size_hint(&self) -> (uint, Option<uint>) {
self.iter.size_hint()
}
}
Version
The code under main is actually a test (see test_inspect
in libcoretest/iter.rs
) that was passing with the boxed version of Inspect
, but after moving Inspect
to unboxed closures (as seen above) compiling that test now errors due to a type inference failure.
To fix the compilation n
had to be type annotated: let mut n = 0u
, however this shouldn't be necessary because assert_eq!(n, xs.len())
should already force n
to be uint
.
TL;DR This should compile because it has enough type information, but for some reason it doesn't.