One can write something like the following, in which an associated type is populated by a concrete implementation that then uses that associated type within a method:
use num;
use std::marker::PhantomData;
trait MyTrait {
type Type: num::Unsigned;
fn do_something(val: <Self as MyTrait>::Type) -> <Self as MyTrait>::Type;
}
struct U32Type {}
impl MyTrait for U32Type {
type Type = u32;
fn do_something(val: <Self as MyTrait>::Type) -> <Self as MyTrait>::Type {
val & (10 as Self::Type)
}
}
struct MyStruct <T>
where T: MyTrait
{
marker_t: PhantomData<T>,
}
impl <T> MyStruct <T>
where T: MyTrait
{
fn foo(val: T::Type) -> T::Type{
T::do_something(val)
}
}
fn main() {
let a: u32 = MyStruct::<U32Type>::foo(10u32);
println!("Value {}", a);
}
Looking at the above, it seems to me that U32Type.do_something()
does not specify anything that is not directly inferable from the type system. As such, I would have thought I could specify a default implementation on the trait itself. The following is an attempt to do that (with the additional trait bounds I would have thought necessary for the generic case):
use num;
use std::ops::BitAnd;
use std::marker::PhantomData;
trait MyTrait {
type Type: num::Unsigned + BitAnd;
fn do_something(val: <Self as MyTrait>::Type) -> <Self as MyTrait>::Type {
val & (10 as <Self as MyTrait>::Type)
}
}
struct U32Type {}
impl MyTrait for U32Type {
type Type = u32;
}
struct MyStruct <T>
where T: MyTrait
{
marker_t: PhantomData<T>,
}
impl <T> MyStruct <T>
where T: MyTrait
{
fn foo(val: T::Type) -> T::Type{
T::do_something(val)
}
}
fn main() {
let a: u32 = MyStruct::<U32Type>::foo(10u32);
println!("Value {}", a);
}
Unfortunately, this does not work - the compiler fails with the complaint that the output of do_something
is of type <<Self as MyTrait>::Type as std::ops::BitAnd>::Output
as well as about the non-primitive cast within do_something
.
Is this something that is possible with some correct set of trait bounds (say), or is it something that one cannot do? If the latter, can anybody clarify what the problem is?