References in trait bounds

Hi,

I want to create arbitrary precision integer arithmetic, and for that an Integer trait.
I created the BigUInt struct, which is just a Vec.
Because of this, BigUInt can't implement Copy so I want to implement the operations on both &BigUInts and BigUInt.

So I want my Integer trait so that i can do operations on references as well like this:

fn foo<T: Integer>(a: T, n: u32) -> T {
    let b = a + &a;
    let c = &a + a;
    let d = &a + &a;
    let e = a + a;
}

So I want to bind my Integer trait like this:

use std::ops::Add;

pub trait Integer:
    Add<Self, Output = Self>
    + for<'a> Add<&'a Self, Output = Self>
    + where for<'a> &'a Self: Add<&'a Self, Output = Self>,
    for<'a> &'a Self: Add<Self, Output = Self>
    {}

But I get the error:
"the size for values of type Self cannot be known at compilation time"

How can I fix this?

Your error is easily fixed by adding Sized as a supertrait:

pub trait Integer: Sized + Add<Self, Output = Self> + for<'a> Add<&'a Self, Output = Self>
where
    for<'a> &'a Self: Add<&'a Self, Output = Self>,
    for<'a> &'a Self: Add<Self, Output = Self>,
{
}

Sized as a trait bound is implicitly added to every generic parameter, but not as an implicit supertrait, so you have to add it explicitly.

4 Likes

Thanks this worked!

Now I have the following problem:
If I define the Integer trait like this:

use std::ops::Add;

pub trait Integer:
    Add<Self, Output = Self>
    + for<'a> Add<&'a Self, Output = Self>
    + where for<'a> &'a Self: Add<&'a Self, Output = Self>,
    for<'a> &'a Self: Add<Self, Output = Self>
    {}

And try to use it:

fn foo<T: Integer>(a: T, b: T) -> T {
    a+b
}

I get the error

error[E0277]: cannot add `&'a T` to `&'a T`
   --> src/algstructs.rs:268:9
    |
268 | impl<T: Integer> PrimeFieldE<T> {
    |         ^^^^^^^ no implementation for `&'a T + &'a T`

If I remove the where clause from the Integer trait, the problem is gone, but then I can't write &a + &b.

This is a known issue where clauses are only elaborated for supertraits, and not other things · Issue #20671 · rust-lang/rust · GitHub

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.