How to solve borrow checker with generics and operator traits

I am writing a struct named Operator that calculates and accumulates input structs.
Add and Mul operators are implemented for the input struct:

use std::ops::Add;
use std::ops::Mul;

struct MyInt {
    val: u32,
}

impl Add<&MyInt> for &MyInt {
    type Output = MyInt;
    fn add(self, rhs: &MyInt) -> Self::Output {
        MyInt {
            val: self.val + rhs.val,
        }
    }
}

impl Mul<&MyInt> for &MyInt {
    type Output = MyInt;
    fn mul(self, rhs: &MyInt) -> Self::Output {
        MyInt {
            val: self.val * rhs.val,
        }
    }
}

struct Operator {
    x: MyInt,
}

impl Operator {
    fn step(&mut self, x: &MyInt) {
        self.x = &self.x + x;
        self.x = &self.x * x;
    }
}

fn main() {
    let mut operator = Operator {
        x: MyInt { val: 0 },
    };
    for i in 0..10 {
        let i = MyInt { val: i };
        operator.step(&i);
    }
    println!("{}", operator.x.val);
}

The above code works fine.

Next, I replaced Operator with generics code. It takes a type parameter T instead of MyInt.
I put some explicit lifetimes to solve some compile errors:

struct Operator2<T> {
    x: T,
}

impl<'a, 'b, T> Operator2<T>
where
    &'a T: 'a + 'b + Add<&'b T, Output = T> + Mul<&'b T, Output = T>,
{
    fn step(&'a mut self, x: &'b T) {
        self.x = &self.x + x;
        self.x = &self.x * x;
    }
}

It does not work:

error[E0506]: cannot assign to `self.x` because it is borrowed
  --> src/main.rs:47:9
   |
42 | impl<'a, 'b, T> Operator2<T>
   |      -- lifetime `'a` defined here
...
47 |         self.x = &self.x + x;
   |         ^^^^^^   -------
   |         |        |
   |         |        borrow of `self.x` occurs here
   |         |        requires that `self.x` is borrowed for `'a`
   |         assignment to borrowed `self.x` occurs here

error[E0506]: cannot assign to `self.x` because it is borrowed
  --> src/main.rs:48:9
   |
42 | impl<'a, 'b, T> Operator2<T>
   |      -- lifetime `'a` defined here
...
47 |         self.x = &self.x + x;
   |                  -------
   |                  |
   |                  borrow of `self.x` occurs here
   |                  requires that `self.x` is borrowed for `'a`
48 |         self.x = &self.x * x;
   |         ^^^^^^ assignment to borrowed `self.x` occurs here

How to fix the above generics code?

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.