How to force trait implementors to support references

Hi,
I'm trying to implement a detailed custom trait. I will have two implementations, maybe more. I need to be sure that I won't miss any of the functions for other types.

I know that I can have tests checking that, but I'd like to have this checked in the trait.

The std::ops::BitOr trait has just one function fn bitor(self, rhs: Self) -> Self.

Let's talk only about u8.

It looks like for working with references, we need to implement four different versions like (https://doc.rust-lang.org/std/ops/trait.BitOr.html):

impl BitOr<u8> for u8
impl<'_> BitOr<&'_ u8> for u8
impl<'a> BitOr<u8> for &'a u8
impl<'_, '_> BitOr<&'_ u8> for &'_ u8

If I make my own trait, I can only require that the implementors should implement the BitOr with:

trait Ugh:
    BitOr
{}

It would be great to have this kind of reference stuff in the list of traits.

My question is: how can I ensure that the implementors of my trait will implement all four versions of the different calls with references?

thanks,
Szymon

You can add where bounds that use Self.

trait Ugh
where
    Self: BitOr,
    for<'a> &'a Self: BitOr,
{
    ...
}

Thanks,

now I have this:


trait Ugh: Sized
where
    Self: BitOr<Self>,
    for<'a> &'a Self: BitOr<Self>,
    for<'a> Self: BitOr<&'a Self>,
    for<'a> &'a Self: BitOr<&'a Self>,
{
}

It works nicely. And combined with impl_op_ex! is great. However, I wanted to automate things a little bit, as I want to add some more operators.

I have tried this:


trait BitOrTrait: Sized
where
    Self: BitOr<Self>,
    for<'a> &'a Self: BitOr<Self>,
    for<'a> Self: BitOr<&'a Self>,
    for<'a> &'a Self: BitOr<&'a Self>,
{}

trait Ugh: Sized + BitOrTrait
{
}

but then I get:

157 | trait Ugh: Sized + BitOrTrait
    |                    ^^^^^^^^^^ no implementation for `&'a Self | Self`

I have also tried moving it to a macro like:

macro_rules! add_trait_ops {
    ($op:literal) => {
        Self: $op <Self>,
        for<'a> &'a Self: $op <Self>,
        for<'a> Self: $op <&'a Self>,
        for<'a> &'a Self: $op <&'a Self>
    };
}

trait Ugh: Sized
where
    add_trait_ops!(BitOr)
{
}

but then I always have errors like unexpected token right after the macro call (regardless if I place there , or ;).

Is there a way to automate it? Macro would be the best.

thanks

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.