Reputation: 410
I would like to make a struct that implements a trait with default associated type and functions as well as specialized trait implementations. However, I'm getting an error when trying to construct an instance of the struct from the default implementation.
Here is some code showing what I'm trying to do. Try it on the Rust playground here.
#![allow(incomplete_features)]
#![feature(specialization)]
pub trait Data {
type Data;
fn new() -> Self;
}
pub struct MyStruct<T> {
pub data: <Self as Data>::Data,
}
// default implementation
impl<T> Data for MyStruct<T> {
default type Data = u64;
default fn new() -> Self {
MyStruct::<T> {data: 1u64}
}
}
// a specialized implementation
impl Data for MyStruct<i64> {
type Data = u32;
fn new() -> Self {
MyStruct::<i64> {data: 1u32}
}
}
This gives the error:
error[E0308]: mismatched types
--> src/lib.rs:16:30
|
14 | default type Data = u64;
| ------------------------ expected this associated type
15 | default fn new() -> Self {
16 | MyStruct::<T> {data: 1u64}
| ^^^^ expected associated type, found `u64`
|
= note: expected associated type `<MyStruct<T> as Data>::Data`
found type `u64`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to previous error
The error description is pretty generic and I'm not sure what I'm doing wrong. I'm aware that this is an incomplete feature for a reason but I get the feeling I am doing something wrong, not that this is an issue with the feature.
Upvotes: 0
Views: 283
Reputation: 59902
I think this is just a case of it being incomplete (and from the comments may not even support this case). This code is straight from the Specialization RFC (and from my understanding suggests it should work) but it fails with a similar error:
#![allow(incomplete_features)]
#![feature(specialization)]
trait Example {
type Output;
fn generate(self) -> Self::Output;
}
impl<T> Example for T {
default type Output = Box<T>;
default fn generate(self) -> Box<T> { Box::new(self) }
}
impl Example for bool {
type Output = bool;
fn generate(self) -> bool { self }
}
error[E0053]: method `generate` has an incompatible type for trait
--> src/lib.rs:11:34
|
6 | fn generate(self) -> Self::Output;
| ------------ type in trait
...
10 | default type Output = Box<T>;
| ----------------------------- expected this associated type
11 | default fn generate(self) -> Box<T> { Box::new(self) }
| ^^^^^^
| |
| expected associated type, found struct `Box`
| help: change the output type to match the trait: `<T as Example>::Output`
|
= note: expected fn pointer `fn(_) -> <T as Example>::Output`
found fn pointer `fn(_) -> Box<T>`
Upvotes: 1