Is there a way to add std::ops::Add implementation for i32

I created a struct CustomNum that has an i32 value and added impl for Add. So now I can do

let mut x = CustomNum(5);
x = x + 3_i32;

Can 3_i32 + x where x:CustomNum be implemented?

Edit: The following is wrong, as pointed out by leudz.

No. Rust's orphan rules prevent it because neither the type i32 nor the trait Add are defined in your crate. If one of them were, then it would be possible.

You can reverse the order of the operands, or add a method to i32 using a custom trait to do the same though:

impl MyTrait for i32{
     fn add_custom(&self, rhs: CustomNum) -> CustomNum{
       rhs + self
  }
}

Please format your code according to the pinned post.

```
Your code
```

You can't implement it like that, because as @m51 already pointed out, it violates Rust's orphan rules:
impl std::ops::Add<Foo> for i32 { //err
    ...
}

Since both of them are defined externally. This could possibly have been mitigated if we had specialization since 1.0, but now there is little that can be done about this. It may be logical to use a newtype depending on the situation, such as how certain linear algebra libraries have newtype angle structs:

struct Deg(f32);
struct Rad(f32);

Please see @leudz's answer. The orphan rules have been relaxed (and I guess I may have forgotten?) since last I remember, so it is possible to implement that trait.

@m51 @OptimisticPeach The orphan rules were relaxed.

@benoy Something like this?

fn main() {
    let mut x = CustomNum(5);
    x = x + 3;
    x = 3 + x;
}
6 Likes

This works because there are no generic impls of Add in std (which is where Add and i32 are defined), so Add<CustomNum> is treated as a local trait. If std had something like this

impl<U: CanBeAddedToI32> Add<U> for i32 {...}

it would not work (because implementing CanBeAddedToI32 for CustomNum would be a coherence violation).

3 Likes