Reputation: 20968
I'm trying to implement a num_to_rug
function, whch converts a generic number into a rug::Integer
.
(the purpose is to call Rug's primality test, Integer::from(n).is_probably_prime
)
This is easy to do for u32
and u64
, as Integer::from
is implemented for them:
impl PrimeQ<u32> {
fn num_to_rug(n: u32) -> Integer {
Integer::from(n)
}
}
impl PrimeQ<u64> {
fn num_to_rug(n: u64) -> Integer {
Integer::from(n)
}
}
Now I want to implement this function for any type that:
PrimeSieveTrait
Integer::from
implementedpub trait PrimeSieveTrait:
AddAssign + SubAssign + MulAssign + DivAssign + integer::Roots + PrimInt + FromPrimitive {}
impl<T> PrimeSieveTrait for T
where T:
AddAssign + SubAssign + MulAssign + DivAssign + integer::Roots + PrimInt + FromPrimitive {}
How do I modify the code below so it compiles?
impl<T: ?> PrimeQ<T> {
fn num_to_rug(n: T) -> Integer {
Integer::from(n)
}
}
Upvotes: 0
Views: 585
Reputation: 602735
If you literally want to use the From<T>
trait, then this cannot be expressed as an inline trait bound – you need to use a where
clause instead:
impl<T> PrimeQ<T>
where
T: PrimeSieveTrait,
Integer: From<T>,
{
fn num_to_rug(n: T) -> Integer {
Integer::from(n)
}
}
A better alternative would be to use the Into<Integer>
trait instead, in which case you only need trait bounds on T
:
impl<T: PrimeSieveTrait + Into<Integer>> PrimeQ<T> {
fn num_to_rug(n: T) -> Integer {
n.into()
}
}
(I would usually write this with a where
clause as well, as I find that more readable.)
More generally, the trait bound U: From<T>
implies T: Into<U>
because of a blanket implementation in the standard library. This means that using the trait bound T: Into<U>
as in the second code snippet above makes your function more general, and it's also more convenient to use, so it should be preferred over the From
trait bound.
Upvotes: 2