Traits from base of newtype

Is there a clean and easy way to access the traits from the base type in a newtype? I've got something that works, but it feels awkward: Playground

Can you explain more about your original problem, what exactly are you trying to achieve? I think the usual pattern would be to reimplement the trait for the newtype, like this:
Playground

Yeah, re-implementing the base traits would technically achieve my goals, but would lead to using a macro throughout my crate to repetitively reimplement base traits. What I was originally aiming for was:

pub trait Foo {}
pub trait Bar {}
pub trait Baz {}

pub struct A {}
impl Foo for A {}

type B1 = A;
impl Bar for B1 {}

type B2 = A;
impl Baz for B2 {}

Such that A has just the trait Foo, B1 has Foo and Bar, and B2 has Foo and Baz.

Conceptually Bar and Baz are different versions of a solve process, so they logically should stay separate. They only require a few associated types and const definitions from A, so I just want the easiest way to manage that.

Really what I should probably do is to give the new B structs the associated type A and just use phantom data...

pub struct B1<A: Foo> { _: PhantomData<A>, }

GHC Haskell has a language extension, GeneralizedNewtypeDeriving, that lets a newtype "inherit" a chosen subset of the typeclass instances (= trait impls in Rust) of the wrapped type. But Rust has no such language-level mechanism and it's fundamentally not possible to implement something equivalent for arbitrary traits using only proc macros; you really need compiler support.

Ahh, ok. So I'll just need to do things manually, one way or another. I guess it'll just come down to what leads to the least repetition and ease of use/maintenance.

It's a known wish. You can see an RFC proposing a direction to help simplify this over in

1 Like

Oh wow, 2.5+ years on that. But it sure would be helpful in a handful of situations. And the delegate <stuff> to self.<field> syntax is nice and straightforward.

I only skimmed, but it appears to target items of a trait, rather than the trait itself. Would delegate Trait to self.<field> be able to allow using the fully qualified <Self as Trait>::trait_item?

Using my existing macros to implement the base traits on the new structs seems to be the cleanest option. Turned out to be a good chance to learn how to use #[macro_use] with nested modules.

Which brings me to: Some of the inputs to each macro are already imported types from external crates, which I provide as $T:ty. Is it possible to pass $T:ident instead and use that to both import the type and also to work as the type in the trait impl?

The one I'm pretty sure can't be done is to pass an integer to be concatenated onto a type name. Such as passing 3 and having the macro result in Vector3 and Matrix3 being imported and used... My workaround was to attach nalgebra's named dims as a type of the trait so that I can do type Vector = VectorN<T, <D as Dim>::Dim>.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.