Associated types used in generic structs


#1

Why doesn’t the compiler infer the associated type from the implementation on the type itself when it’s handling it inside another generic?

See https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=fbf1e513af79f65d0dd6e62e3e4091ce

for compilation failure. This should not pose a problem as far as I can say. The <THaver as HasSomething>::TSomething should clearly be inferred to be a usize at this point.


#2

This question should’ve been posted on users.rust-lang.org.

This has nothing to do with inference.

When you write generic code, it needs to be valid for all possible types within the bounds you specify. The only thing that can be generically concluded from <THaver as HasSomething>::TSomething is that it’s Copy + PartialEq, as you specified in the trait definition. There are many types that are Copy + PartialEq and most of them are no usize. I can impl HasSomething for another type (say File), set type TSomething = i32, and then construct a Runner<File> and this must still work.

Maybe you meant to write impl Runner<String> instead of impl<THaver> Runner<THaver> where THaver: HasSomething?


#3

Of course, but associated type traits can only be applied to a type once only no?

That means that the compiler should be able to infer the associated type for the generic parameter on each use.

If you implemented HasSomething for say File with something else than usize you would get an error on use for the line where it’s passed in. e.g. https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b425dba86d6d3e44e2288d6b60e58604

As for the implementation, this type of generic trait was used to allow “backends” to implement something on top of an abstracted generic code that also needed a user-side generic. It works fine with Trait passed along that way, but I was wondering why the compiler couldn’t infer the type here and check it for each use case.

AFAIK generics can only be instantiated compile time no?


#4

I think you might be confusing generics with templates. With generics, your code is type-checked once, generically, and then instantiated for every different use. This is called monomorphization. No errors may occur at monomorphization time. In order to pass type checking, your code needs to support all possible implementations.


#5

Oh, that explains it. I wonder tho if it would be technically possible to do this particular check for associated types. I mean you could actually collect the allowed associated type as you process the generic and then when it’s used you would limit to only those instantiations where it makes sense.

This is academic at this point of course.


#6

No, because dependent crates might implement the traits you define in your crate.


#7

Ah right. thanks for taking the time! Sorry about the mis-posting to wrong forum.


#8