These are chat archives for rust-lang/rust

Mar 2017
Mar 11 2017 18:04
Hello everyone!
What should my struct X implement for the following trait bounds to be satisfied?
std::vec::Vec<X> : std::iter::Iterator?
I get a compilation error trying to call .enumerate() on a Vec
Aleksey Kladov
Mar 11 2017 18:19
You need to call .enumerate() on the iterator, and not on the vector directly. if xs: Vec<X>, then you need either xs.into_iter().enumerate() or xs.iter().enumerate()
Mar 11 2017 18:30
oh, I see, my problem was trying to call iter on a slice
Robey Pointer
Mar 11 2017 19:28
I have a really dumb question: I often get the error message expected type parameter, found struct -- but for whatever reason, these words don't map for me... can anyone explain what it means in a longer sentence?
Mike Lubinets
Mar 11 2017 20:47
@robey show the code where compiler shows this error please
Robey Pointer
Mar 11 2017 22:12
@mersinvald i get it in a lot of situations where i can't figure out why it wants an extra type parameter... here's one simplified case that caused me to ask again:
pub fn make3<
  In: Stream<Item = Bytes, Error = io::Error>,
  Out: Stream<Item = Vec<Bytes>, Error = io::Error>
>(s: In) -> Out {

fn ok(x: Bytes) -> Vec<Bytes> { vec![ x ] }
32 |
   |   ^^^^^^^^^ expected type parameter, found struct `futures::stream::Map`
(i tried adding a type parameter in a few places, to ward off evil, but gave up after a few... i don't think the error message means what it looks like)
Jonas Platte
Mar 11 2017 22:15
@robey What you are trying to do unfortunately isn't possible in current stable rust, let me try to explain....
Robey Pointer
Mar 11 2017 22:16
i'm on nightly, if that would help (i needed that to get return type inference)
Jonas Platte
Mar 11 2017 22:19
When you declare a function with a generic parameter (like s: In in your example), you give the user the ability to call your function with any type that implements whatever traits you have chosen to constrain that parameter. This is formally known as universal quantification: "this function is valid for all types that satisfy these constraints (implement traits A, B, C)"
What you want for your return value, and what one usually wants for their generic return values is something different, where there is one concrete type returned by the function, but you don't want to expose that type as part as your interface and instead just name how that type behaves, through traits again. This is called existential quantification: "there exists a type that satisfies these constraints (implements traits D and E)"
The latter is possible in nightly Rust to some extent, through the feature conservative_impl_trait.
Jonas Platte
Mar 11 2017 22:26
Here's the RFC if you want to know all the details. If you search for "rust impl trait" in the search engine of your choice, you will also find a lot of discussion about it. But the basic usage looks like this:
fn foo() -> impl MyTrait { ... }
Robey Pointer
Mar 11 2017 22:50
Yeah I should have explained that I already know about return type inference and am using impl Trait elsewhere
In this case I'm simplifying an example where I want to create a From for converting a stream of bytes into a stream of byte vectors
Robey Pointer
Mar 11 2017 22:57
Since it will generate the function based on In, it should be able to infer the return type at generation time, and confirm that it matches Out
Instead, I get an error that implies I need to add a type parameter but I'm not sure where or if the error is just confusing
Jonas Platte
Mar 11 2017 23:04
No, you don't need to add anything. I think what the compiler is saying is that it expected the last expression in your function body to be of type Out (the type parameter) but found the concrete Map type in futures::stream.
@robey Does it not work when you change -> Out to impl Stream<Item = Vec<Bytes>, Error = io::Error>?
(and remove Out as a type parameter)