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
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>
.