Hi. I've managed to tie myself into a generics knot. All my reasoning says the below should compile, but it gives me an error that the impl for AnotherC should be returning a Type, not a Struct. I can't see what I've got wrong.
This is all ending up a bit complex, though and I wonder if there's a more rust-y way to achieve what I want. I have objects 'A's that identified by ids 'B's that are essentially different newtypes around strings most of the time. I have events 'C's that aggregate together to build objects 'A's. I want to enforce that an event 'C' that will aggregate to a given type of object 'A' can only take an appropriate id type 'B'.
Thanks for any help/advice.
trait A {
fn get_string() -> String {
"Hi. I'm an A".to_string()
}
}
trait B<T: A> {
fn get_string() -> String {
"Hi. Iam a B".to_string()
}
}
trait C<T: A> {
fn get_thing<Y: B<T>>(&self) -> Y;
}
struct AnA {}
impl A for AnA{}
struct SomeB{}
impl B<AnA> for SomeB{}
struct AnotherC {
thing: SomeB,
}
impl C<AnA> for AnotherC {
fn get_thing<SomeB>(&self) -> SomeB{
self.thing
}
}
fn main() {
let c = AnotherC {
thing: SomeB{}
};
println!("{}", c.get_thing());
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:30:9
|
29 | fn get_thing<SomeB>(&self) -> SomeB{
| ----- ----- expected `SomeB` because of return type
| |
| this type parameter
30 | self.thing
| ^^^^^^^^^^ expected type parameter `SomeB`, found struct `SomeB`
|
= note: expected type parameter `SomeB` (type parameter `SomeB`)
found struct `SomeB` (struct `SomeB`)
error[E0282]: type annotations needed
--> src/main.rs:38:22
|
38 | println!("{}", c.get_thing());
| ^^^^^^^^^ cannot infer type for type parameter `Y` declared on the associated function `get_thing`
|
help: consider specifying the type argument in the method call
|
38 | println!("{}", c.get_thing::<Y>());
| ^^^^^
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0282, E0308.
For more information about an error, try `rustc --explain E0282`.
error: could not compile `playground`
To learn more, run the command again with --verbose.