std::slice::Iter not fufilling Iterator trait bound

I have the following struct and impl block:

pub(crate) struct VM<'a, I> where I: Iterator<Item = &'a u8>, {
    pub(crate) ip: Peekable<I>,
    ...
}

impl<'a, I> VM<'a, I> where I: Iterator<Item = &'a u8>, {
    pub(crate) fn new(chunk: &'a Chunk) -> Self {
        Self {ip: chunk.code.iter().peekable(), ...}
    }
    ...
}

where chunk.code is Vec<u8>.

The compiler raises the following error:

note: expected struct Peekable<I>
    found struct Peekable<std::slice::Iter<'_, u8>>

It was my understanding that std::slice::Iter implements the Iterator trait, so why won't it be accepted by the trait bound?

When you write a generic parameter I that way, you're letting the caller choose an arbitrary I that meets the constraints. So the function is required to return their choice of Self = VM<'a, I>, but your code only returns the specific kind where I = std::slice::Iter<'_, u8>.

Do you expect to work with different kinds of I? If not, then that probably shouldn't be a type parameter at all, and just use ip: Peekable<std::slice::Iter<'a, u8>> all the time.

Or you could make new more specific, like one of these:

pub(crate) fn new(chunk: &'a Chunk) -> VM<'a, std::slice::Iter<'a, u8>> { ... }
// or opaque
pub(crate) fn new(chunk: &'a Chunk) -> VM<'a, impl Iterator<Item = &'a u8>> { ... }
2 Likes

I see now. I was misusing the generic parameter simply as a way to specify a type, but did not actually intend to use generics at all. I do not expect to work with different I, therefore I have followed your suggestion and removed the parameter, using Peekable<std::slice::Iter<'a, u8>>.

Thank you for your help!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.