How can I ensure that generic argument types are different?
05:33 05 May 2024

I have defined a trait (let's call it MyTrait) and implemented it for any type of tuple with two elements:

trait MyTrait {
  fn my_fn();
}

impl MyTrait for (T1, T2) {
  fn my_fn() {...}
}

However, I would like to ensure that the trait is implemented only if T1 and T2 are different concrete types. E.g. (i32, i64) is ok, but (i32, i32) is not. This should also be extensible to larger tuples (up to 16 elements). Is there a way to do so?

I have tried using a static assertions in the following way:

fn my_fn() {
   static OK: () = assert!(std::any::TypeId::of::() != std::any::TypeId::of::());
   ...
}

This results in an error:

error[E0401]: can't use generic parameters from outer item

I guess this is because the value of OK would be shared by all implementations, no matter what T1 and T2 are concretely?

I have also tried thinking of ways to express this through trait bounds (which seems a more robust approach) but couldn't find a way.

generics rust