Implementing a foreign trait for a local generic type

Viewed 1190

I'm attempting to implement a trait from crate A for a trait from crate B using static dispatch. I'm wrapping the foreign trait, but am having trouble with the impl<T> line:

extern crate a;
extern crate b;

pub trait C: a::A {}

impl<T: C> b::B for T {}

The end result I am looking for is implementing b::B for implementors of trait C, using static dispatch.

I'm getting the following error:

error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
 --> c/src/lib.rs:3:1
  |
3 | impl<T: C> b::B for T {}
  | ^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
  |
  = note: only traits defined in the current crate can be implemented for a type parameter

I'm able to get around this by using dynamic dispatch — impl b::B for dyn C — but want to accomplish this with static dispatch.

I've already tried:

1 Answers

What I usually do is wrapping the foreign type in a struct (as opposed to introducing a new trait deriving from the foreign one):

extern crate a;
extern crate b;

pub struct C<T: a::A> {
    pub t: T,
}

impl<T: a::A> b::B for C<T> {}

This, however, sometimes requires some boilerplate to convert between C and the "normal" type.

This is sometimes called "NewType pattern" (as in https://github.com/Ixrec/rust-orphan-rules).

Related