num-traits
num-traits copied to clipboard
`struct` built on top of `pub trait Num` can't compile if `pub trait Num` doesn't impl `Debug`
#[test]
fn test_debug_trait_impl() {
use num_traits::Num;
use std::ops::Add;
pub struct LengthNArrayOfTypeT<const N: usize, T: Num>([T; N]);
impl<const N: usize, T: Num + Clone> Add for LengthNArrayOfTypeT<N, T> {
type Output = Self;
fn add(self, rhs: Self) -> Self {
LengthNArrayOfTypeT(
self.0
.iter()
.zip(rhs.0.iter())
.map(|(a, b)| a.clone() + b.clone())
.collect::<Vec<T>>()
.try_into()
.unwrap(),
)
}
}
}
is an example of code that can't compile because of this issue.
You should add T: Debug if you need it, just as you have for Clone. The compiler even suggests that!
help: consider further restricting this bound
|
6 | impl<const N: usize, T: Num + Clone + std::fmt::Debug> Add for LengthNArrayOfTypeT<N, T> {
| +++++++++++++++++
The place your example encounters this doesn't have anything to do with being a numeric type. The error is from your Vec<T> to [T; N] conversion .try_into().unwrap(), which wants to debug-print its potential Result::Err (containing the original value) when unwrapped. You could make that .try_into().ok().unwrap() to get an Option unwrap instead, especially since you know in this case that the length will never actually mismatch.
Or you could rewrite this to update the value in-place:
fn add(mut self, rhs: Self) -> Self {
for (a, b) in std::iter::zip(&mut self.0, rhs.0) {
*a = a.clone() + b;
}
self
}
And with T: AddAssign (or T: NumAssign), you wouldn't even need the clone.
The compiler even suggests that!
I know. I started needing to add it everywhere, so I started looking into different approaches.
The error is from your
Vec<T>to[T; N]conversion.try_into().unwrap(), which wants to debug-print its potentialResult::Err(containing the original value) when unwrapped. You could make that.try_into().ok().unwrap()to get anOptionunwrap instead, especially since you know in this case that the length will never actually mismatch.
Thank you for the suggestion.
You could define your own extended trait:
trait MyNum: num_traits::Num + Clone + Debug {}
impl<T> MyNum for T where T: num_traits::Num + Clone + Debug {}