0

I've got the following trait:

pub trait EventHandler<T: Stream<U>, U: Read + Write + AsRawFd> {
    fn on_data_received(&mut self, stream: T, buffer: Vec<u8>);
    fn on_stream_closed(&mut self, id: u32);
}

I've tried the following:

pub type StreamList = LinkedList<Stream> produces:

error: wrong number of type arguments: expected 1, found 0

and pub type StreamList = LinkedList<Stream<T: Read + Write + AsRawFd>> produces:

error: expected one of '!', '(', '+', ',', '::', '<', or '>', found ':'

What is the proper syntax for using Stream as a type parameter?

nathansizemore
  • 3,028
  • 7
  • 39
  • 63
  • @Shepmaster Edited question, but maybe I'm missing something? Using it like you have in your example is the second option I tried and is in my question. Not sure where I'm going wrong...? – nathansizemore Nov 23 '15 at 04:34
  • 1
    @Shepmaster Turns out, `Read, White`, etc... is needed for the question because it has to do with how aliases were made – nathansizemore Nov 23 '15 at 05:07
  • Good to know, you may want to [edit] your question to include that those specific traits are required and no other traits cause the same problem (and show what else you tried that doesn't work). And to clarify, my example was to show a smaller reproduction *of the same problem*, not trying to show how to fix it :-) – Shepmaster Nov 23 '15 at 14:09

2 Answers2

2

Syntactically, I think this is what you want:

trait OuterTrait<T> {
    fn use_type_parameter(t: T);
}

trait InnerTrait {}

type CombinedTypeOne<T: InnerTrait> = Option<OuterTrait<T>>;
type CombinedTypeTwo<T> where T: InnerTrait = Option<OuterTrait<T>>;

fn main() {}

In a larger sense, this makes sense. When you define a type, it has to either completely know what type it is, or have type parameters and be fully specified at the use site. In your example, the type StreamList acts like it is completely specified. However, the right-hand side says "put in any concrete type", so you'd need to rectify the two.

Beyond that, the trait constraint goes on the "declaration" part of the alias, not the "definition" part. This mirrors how trait and function definitions work.

However, the first example has this warning:

warning: trait bounds are not (yet) enforced in type definitions [E0122]
    type CombinedTypeOne<T: InnerTrait> = Option<OuterTrait<T>>;
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The detailed explanation for E0122.

I believe that the second example has the same underlying problem, but the warning is missing — I'd guess this is a bug that should be reported. I think that overall, this means you cannot do what you want yet.


Additionally, you are trying to use a trait as a type (represented above as Option<OuterTrait>. Although conceptually possible, I don't know how to actually construct an object that looks like that. It's more likely you want something like

type CombinedTypeOne<T, U: OuterTrait<T>> = Option<U>;
type CombinedTypeTwo<T, U> where U: OuterTrait<T> = Option<U>;

but that complains about unused type parameters. I can't reason through if the error makes sense or is a side-effect of the fact that this feature isn't enforced yet:

error: type parameter `T` is unused [E0091]
    type CombinedTypeOne<T, U: OuterTrait<T>> = Option<U>;
                                                ^~~~~~~~~
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • I think I may be reaching for something that isn't available yet with trait objects. Thanks for the in-depth explanation :) – nathansizemore Nov 24 '15 at 04:32
0

Answer was found from this question.

pub trait StreamIo: Read + Write + AsRawFd {}
pub type StreamList = LinkedList<Stream<StreamIo>>;
Community
  • 1
  • 1
nathansizemore
  • 3,028
  • 7
  • 39
  • 63
  • 1
    Note that this is *entirely* different from `LinkedList where T: Stream, U: Read + Write + AsRawFd`. In your example both `Stream` and `StreamIo` are used as trait objects. It is highly unlikely that you'll be able to construct a value of such type. For example, you won't be able to pass `LinkedList` where `SomeStream: Stream` and `Something: Read + Write + AsRawFd` to where your `StreamList` is expected. – Vladimir Matveev Nov 23 '15 at 06:57
  • @VladimirMatveev And, I found this out now that I'm trying to use it. Thanks for taking the time to comment on this :) – nathansizemore Nov 23 '15 at 14:06