Rust generic AddAssign with references

Viewed 1999

A while ago I looked into writing a generic iterator for the Fibonacci sequence that could accept both primitive numbers as well as custom types (such as bignums). After failing to get a version working for both the primitive types and bignums, I stumbled upon this question:

How to write a trait bound for adding two references of a generic type?

Which used so called Higher Ranked Trait Bounds to solve the problem with this particular issue.

Now however, I'm trying to use a similar strategy to use the *_assign operators instead. In particular, I'm trying to get something similar to this working:

use std::ops::{Add, AddAssign};

fn add_test<'a, T>(x: &'a T, y: &'a T) -> T
where
    for<'b> &'b T: Add<Output = T>,
{
    x + y
}

fn add_assign_test<'a, T>(x: &'a mut T, y: &'a T) -> T
where
    for<'b> &'b mut T: AddAssign<&'b T>,
    T: Clone,
{
    x += y;
    x.clone()
}

fn main() {
    println!("add_test()={}", add_test(&1, &2));
    println!("add_assign_test()={}", add_assign_test(&mut 2, &2));
}

add_test() works as expected but I'm unable to get add_assign_test() to work in a similar way. The errors I'm getting suggest that there might not actually exist an implementation for this kind of behaviour on the primitive types:

error[E0277]: the trait bound `for<'b> &'b mut _: std::ops::AddAssign<&'b _>` is not satisfied
  --> src/main.rs:21:38
   |
21 |     println!("add_assign_test()={}", add_assign_test(&mut 2, &2));
   |                                      ^^^^^^^^^^^^^^^ no implementation for `&'b mut _ += &'b _`
   |
   = help: the trait `for<'b> std::ops::AddAssign<&'b _>` is not implemented for `&'b mut _`
   = note: required by `add_assign_test`

I could create a macro that creates implementations for these operators that actually takes references to the primitive types, but that seems a little wasteful. Is there any other way to achieve the same effect?

2 Answers
Related