Hi.
I've been working on a generic function so different types that implement differently the same traits can call it, since the behavior of this exact function is shared by the types.
To put an example:
pub(self) trait Double {
type Output;
#[must_use]
/// Performs the point-doubling operation over the
/// coordinates which this trait has been implemented
/// for.
fn double(self) -> Self::Output;
}
/// This struct implements: `Add`, `Identity`, `Double` and `Clone`.
pub struct A { /*fields*/};
/// This struct implements: `Add`, `Identity`, `Double` and `Clone`.
pub struct B { /*fields*/};
Add, Identity and Double are implemented differently for both structs.
Now I want to define a function that gets a gen argument (which can be one of both
declared above and executes the same code when an object of type A
or B
calls it.
pub fn double_and_add<'b, T>(point: T, scalar: &'b Scalar) -> T
where T: Add + Identity + Double + Clone {
let mut N: T = point.clone();
let mut n = scalar.clone();
let mut Q: T = T::identity();
while n != Scalar::zero() {
if !n.is_even() {
Q = &Q + &N;
};
N = N.double();
n = n.half();
}
Q
}
So at this point, I'm getting the following error:
mismatched types
expected type parameter, found associated type
note: expected type `T`
found type `<T as std::ops::Add>::Output`rustc(E0308)
edwards.rs(45, 17): expected type parameter, found associated type
I understand that the result of the addition implementation has the type
<T as std::ops::Add>::Output
but since the addition implementation is as declared down, i was expecting to get the type T
as the result.
// Add impl for A and B:
impl<'a, 'b> Add<&'b EdwardsPoint> for &'a A {
type Output = A;
/// Add two EdwardsPoints and give the resulting `EdwardsPoint`.
/// This implementation is specific for curves with `a = -1` as Doppio is.
/// [Source: 2008 Hisil–Wong–Carter–Dawson],
/// (http://eprint.iacr.org/2008/522), Section 3.1.
#[inline]
fn add(self, other: &'b A) -> A {
// Implementation-....
}
}
So at this point, I don't know how I can deal with that. Anyone has any ideas? I know I can implement this differently, but I wanted to try to do it like this, so I want to solve the problem, not implement that on a complete different way since I can do it by myself.
Thank you so much.