I accidentally overrode subtraction


#1

I’m currently trying to make a Vector trait, for doing linear algebra. I’d like users to be able to subtract a usize from a vector or to subtract a vector from a usize. It’s easy to make it possible to subtract a usize from a Vector: I make my Vector trait extend Sub<usize, Output=usize>. While trying to make it possible to subtract a Vector from a usize, I got myself into the following situation:

use std::ops::Sub;

trait Vector {}

fn my_fn<V: Vector>()
where
    usize: Sub<V, Output=V>,
{
    1usize - 0usize;
}

Surprisingly (to me), I got the following error:

error[E0308]: mismatched types
 --> src/lib.rs:9:14
  |
9 |     1usize - 0usize;
  |              ^^^^^^ expected type parameter, found usize
  |
  = note: expected type `V`
             found type `usize`

Some questions that I have:

  • What is the name for the thing that I have done, where I seem to have “overridden” Sub<usize, Output=usize> with Sub<V, Output=V>?
  • Is there a way to rewrite the code above so that I can subtract V from usize to get a V, but so that I can still subtract a usize from a usize to get another usize?
  • Why doesn’t the code above compile? Since Vector is in my crate and usize does not implement Vector, it seems like usize - usize and usize - Vector should be able to coexist peacefully.
  • Is there another way that I could ensure that my Vector trait can be subtracted from a usize?

#2

This looks to be the same issue as https://users.rust-lang.org/t/lend-me-your-google-fu-on-the-issue-tracker/


#3

Hi @vitalyd, thanks very much! The topic that you linked is exactly what I was looking for! The solution given there is to write <usize as Sub<usize>>::sub(1usize - 0usize). It’s a bit silly but, hey, it works.