I'm looking for some advice on how to best deal with data structures that are mostly generic, but occasionally need specialised implementations depending on type.

Here's a toy example of something I've been working with:

```
use std::ops::Add;
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
struct Point2<T> {
x: T,
y: T,
}
impl<T: Add<T, Output = T>> Add for Point2<T> {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self { x: self.x + rhs.x, y: self.y + rhs.y }
}
}
```

I'd then like to ensure that when dealing with `f32`

or `f64`

, that no nan values are present.

Ideally I'd be able to add something like the following (which doesn't compile due to conflict with existing definition):

```
impl Add for Point2<f32> {
type Output = Self;
fn add(self, rhs: Self) -> Self {
assert!(!rhs.x.is_nan() && !rhs.y.is_nan());
Self { x: self.x + rhs.x, y: self.y + rhs.y }
}
}
```

The best alternative I could see was to implement the trait for every numeric type, e.g.:

```
use std::ops::Add;
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
struct Point2<T> {
x: T,
y: T,
}
impl Add for Point2<f32> {
type Output = Self;
fn add(self, rhs: Self) -> Self {
assert!(!rhs.x.is_nan());
Self { x: self.x + rhs.x, y: self.y + rhs.y }
}
}
impl Add for Point2<i32> {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self { x: self.x + rhs.x, y: self.y + rhs.y }
}
}
```

This looks like quite an implementation burden (i.e. a mostly repeated implementation for every numeric type), where the core of the functionality is the same.

It wouldn't be too bad with macros, but I'm wondering whether I'm missing a better approach, whether through some language features, or an entirely different design for the above (or whether macros are the generally accepted way to achieve this).