0

Here is my original code, which works:

pub trait Arith {
    fn square(x: &Self) -> Self;
}

impl Arith for i32 {
     fn square(x: &i32) -> i32 {
         x * x
     }
}

impl Arith for f32 {
    fn square(x: &f32) -> f32 {
        x * x
    }
}

I would like do it in a generic way:

pub trait Arith where Self: Sized + Mul<&Self, Output = Self> {
    fn square(x: &Self) -> Self {
        x * x
    }
}

It seems that I run into some lifetime annotation issues:

error[E0637]: `&` without an explicit lifetime name cannot be used here
 --> src/main.rs:7:41
  |
7 | pub trait Arith where Self: Sized + Mul<&Self, Output = Self> {
  |                                         ^ explicit lifetime name needed here
  |
help: consider introducing a higher-ranked lifetime here with `for<'a>`
 --> src/main.rs:7:37
  |
7 | pub trait Arith where Self: Sized + Mul<&Self, Output = Self> {
  |                                     ^

error[E0311]: the parameter type `Self` may not live long enough
 --> src/main.rs:7:37
  |
7 | pub trait Arith where Self: Sized + Mul<&Self, Output = Self> {
  |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the reference type `&Self` does not outlive the data it points at

Some errors have detailed explanations: E0311, E0637.
For more information about an error, try `rustc --explain E0311`.

I tried several ways as the compiler suggested and couldn't get it to work. I prefer the function call looks like Arith::square(&x).

Yan Zhu
  • 4,036
  • 3
  • 21
  • 37

1 Answers1

0

Based suggestion from @JaredSmith. The following code works for me:

pub trait Arith
{
    fn square(x: &Self) -> Self
    where
        Self: Sized,
        for<'a> &'a Self: Sized+Mul<&'a Self, Output=Self>,
    {
        x * x
    }
}

impl Arith for i32 { }
impl Arith for f32 { }

Yan Zhu
  • 4,036
  • 3
  • 21
  • 37