Impl trait with generic function for generic struct

#1

Hi!

I’m trying to implement something like this:

trait MyMarker {}

trait Trait {
  fn foo<T: MyMarker>(&self, a: StructA<T>) -> Self;
}

struct StructA<T: MyMarker>;

struct StructB<T: MyMarker>;

impl<T: MyMarker> Trait for StructB<T> {
  fn foo(&self, _: StructA<T>) -> StructB<T> {
    ...
  }
}

So my problem is that I need that T of StructA<T> in impl Trait is the same as the T in StructB. I thought I could ensure this by not shadowing the type parameter at foo. However the compiler complains now about missign type parameters at foo.
Is that even possible?

0 Likes

#2

Hi, I know two ways to do it:
make Trait generic

trait Trait<T: MyMarker> {
    fn foo(&self, a: StructA<T>) -> Self;
}
impl<T: MyMarker> Trait<T> for StructB<T> {
    fn foo(&self, _: StructA<T>) -> StructB<T> {
        unimplemented!()
    }
}

or assiociated type

trait Trait {
    type Marker: MyMarker;
    fn foo(&self, a: StructA<Self::Marker>) -> Self;
}
impl<T: MyMarker> Trait for StructB<T> {
    type Marker = T;
    fn foo(&self, _: StructA<Self::Marker>) -> StructB<T> {
        unimplemented!()
    }
}

this one is just a bonus, it’s not really useful in your case but sometimes weird stuff can inspire great things

trait Trait
where Self: MyMarker + Sized {
    fn foo(b: &StructB<Self>, a: StructA<Self>) -> StructB<Self>;
}
impl<T: MyMarker> Trait for T {
    fn foo(_: &StructB<T>, _: StructA<T>) -> StructB<T> {
        unimplemented!()
    }
}
0 Likes

#3

Thank you for your advice. I run into some trubble with the associated type but the generic trait works well. Even if my code is now full of impl<'a, A, B, V, C> Trait<'a, A, V> for Struct<A, B, C> and so on because the underlying library I use already makes heavy use of generics aswell.

Off topic: I’m using sophia which I want to promote a little bit. It is an inspiring crate for handling Linked Data with only a few downloads and is still WIP. However, it shows what new possibilities arise from using Rust for Semantic Web.

0 Likes