'Using Rust empty type as a generic bound

How do I constraint a Rust generic type to an empty type? I need to create a type with optional value, so that if the generic type is (), it does not use any memory. Here's a simple example - Data could be a i32, () (4 bytes) or it could be i32, i32 (8 bytes). There is an add() for both cases. I get this error (which makes sense, but not sure how to avoid it). I need to handle all valid numeric types.

error[E0119]: conflicting implementations of trait `std::ops::Add` for type `Data<(), ()>`
...
note: upstream crates may add a new impl of trait `num_traits::Num` for type `()` in future versions
use num_traits::Num;

trait MyNumericType: Num {}
impl<T: Num> MyNumericType for T {}

struct Data<T1: MyNumericType, T2> {
    a: T1,
    b: T2,
}

impl<T: MyNumericType> Add for Data<T, ()> {
    type Output = Self;

    fn add(self, other: Self) -> Self {
        Self {
            a: self.a + other.a,
            b: (),
        }
    }
}

impl<T: MyNumericType> Add for Data<T, T> {
    type Output = Self;

    fn add(self, other: Self) -> Self {
        Self {
            a: self.a + other.a,
            b: self.b + other.b,
        }
    }
}


impl<T1: MyNumericType,T2> Data<T1, T2>  {
    fn new(a: T1, b: T2) -> Self {
        Self { a, b }
    }
}

fn main() {
    let r1 = Data::new(1, 2) + Data::new(3, 4);
    let r2 = Data::new(1, ()) + Data::new(2, ());
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source