Generic Type Specialization Issue in a trait implementation


I have this code where I've written a generic scanner trait for a parser. The basic problem I have is summarized in the code below. My actual code is similar.

trait t{
    fn o<T>(&self, g: T);

struct h;

impl t for h{

    fn o<Vec<i32>>(&self, g: Vec<i32>){}

Then I get an error like this :

expected one of ,, :, =, or >

If however I type alias the complex type I don't get the error. But because of the way I need my code to behave I have to specialize it this way so there's no other alternative.
Is this a compiler issue or is there a syntactic way to do it?

You can't do this, you must implement the exact interface as specified in the trait.

Do you mean I can't have generic types for only specific functions within a trait?

I mean you can't specialize functions in this way, when you implement t, you must implement o as fn o<T>(&self, g: T), without specializing the type parameter. (in general you can't specialize anything right now, that's blocked in nightly under the specialization feature)

So one can't specialize the type parameter this way at all?

But if I do

impl t for h{

    fn o<i32>(&self, g: i32){}


type V = Vec<i32>;
impl t for h{

    fn o<V>(&self, g: V){}

I don't get any error.


Just to give a little context:

I need to implement a generic Scan trait but I wanted a particular scanner to take an
io::Read trait object which I have to encapsulate in Box.

So the compiler accepts o<Box> but not o<Box<dyn io::Read>> , so no nested <>.
But then I can't use the Read trait's methods inside my function.

Can you suggest some another way to do it without this construct?

Also mine is a stable version of Rust.

You're shadowing V, you can remove the type alias and it'll compile the same. The compiler should even give you a warning about it.

Box alone isn't a complete type, it's always Box<T>.

Box<dyn io::Read> implements io::Read so it should work without any specialization.

Thanks I understood the V shadowing part but I wanted to know why the compiler accepts o<Box>. Of course I could ignore implementing the trait for this particular scanner and have just have a method named o<Box<dyn io::Read>> but then I wouldn't be able to use this particular scanner as a trait object if ever I wanted to.


I got it! You're saying that any name for the type parameter I give will shadow the outer name. Is that what you are saying? But should using i32 not give me an error? Or is it just a wrapper?

The compiler accepts o<Box> because it's a valid generic name. Like fn do_stuff<Trait>(t: Trait), here Trait is just the name of a generic. Even i32 is a valid name but the compiler will ask you to make it pascal case.

If you really want to introduce some genericity you can make the trait generic or add an associated type.

Got it, got it, thanks so much.

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.