Unconstrained type parameter generics question

I'm trying to define a generic type that holds a Stream, and add a convenience method for constructing this type from something iterable that will use futures::stream::iter_ok() to convert the iterable object into a stream. Here's what I have

struct StreamHolder<S: Stream> {
    stream: S,
}

impl<S> StreamHolder<S>
where
    S: Stream,
{
    pub fn new(stream: S) -> Self {
        Self { stream }
    }
}

impl<I: IntoIterator> StreamHolder<IterOk<I::IntoIter, ()>>
where
    I: IntoIterator,
{
    pub fn from_iter(iter: I) -> Self {
        StreamHolder::new(futures01::stream::iter_ok::<_, ()>(iter))
    }
}

The goal is to be able to say something like:
let v = vec!["a", "b"];
let stream_holder = StreamHolder::from_iter(v);

But when I try to compile this I get:
error[E0207]: the type parameter I is not constrained by the impl trait, self type, or predicates
--> src/sources/socket/mod.rs:358:10
|
358 | impl<I: IntoIterator> StreamHolder<IterOk<I::IntoIter, ()>>
| ^ unconstrained type parameter

I'm not sure I understand correctly what you're intending, but it seems odd that you're implementing this method on a container over IterOk, rather than any arbitrary StreamHolder. I would expect a function like this:

impl<S> StreamHolder<S> // Maybe instead impl<S> StreamHolder<IterOk<S, ()>>
where
    S: Stream,
{
    pub fn from_iter<I: IntoIterator<Item=S>>(iter: I) -> Self {
        Self::new(futures01::stream::iter_ok::<_, ()>(iter))
    }
}

I think the I is unconstrained because the the type StreamHolder<IterOk<I::IntoIter...>> doesn't actually refer to I, it only refers to the associated type, which could be anything. (So why would you refer to I at all here, if you don't care about it?)

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.