Closed
Description
Consider the following code (play):
#![feature(existential_type)]
fn main() {
let y = choose(vec![1, 2, 3, 4].into_iter());
for (i, elem) in y.enumerate() {
println!("processing y[{}]: {:?}", i, elem);
}
}
existential type MaybeWrapped<I>: Iterator<Item = usize>;
fn choose<I: Iterator<Item = usize>>(x: I) -> MaybeWrapped<I> {
// If you switch to variant below, it works.
// return Wrapped(x);
return x.collect::<Vec<usize>>().into_iter();
}
/// Trivial wrapper around an iterator.
struct Wrapped<I: Iterator>(I);
impl<I: Iterator> Iterator for Wrapped<I> {
type Item = I::Item;
fn next(&mut self) -> Option<I::Item> { self.0.next() }
}
The compiler errors, with the diagnostic
error[E0091]: type parameter `I` is unused
--> src/main.rs:10:31
|
10 | existential type MaybeWrapped<I>: Iterator<Item = usize>;
| ^ unused type parameter
error: aborting due to previous error
But it should not be illegal to leave a type parameter unused. It is useful, from the view-point of the implementor, to have the option of returning concrete types that do not use the given type.
(Also, I find the diagnostic itself a bit less helpful than it could be; when I first read it, I thought it was complaining about not seeing I
on the trait-bound in existential type <NAME>: <TRAIT_BOUND>
; I needed @eddyb to point out to me that the issue is in the body of fn choose
itself.)