Why is a lifetime needed when implementing a trait for a reference type if the lifetime is not used in Rust <1.31?

I implement a trait for a reference type using Rust older than 1.31. Why does Rust want an explicit lifetime when I tell it what reference type I am implementing the trait for?

Here is a simple example. The Inches structure, the implementation of the Add attribute for &Inches and the function that uses this implementation.

Initial example

(Rust playground link)

 use std::ops::Add; struct Inches(i32); // this would work: impl<'b> Add for &'b Inches impl Add for &Inches { type Output = Inches; fn add(self, other: &Inches) -> Inches { let &Inches(x) = self; let &Inches(y) = other; Inches(x + y) } } // lifetime specifier needed here because otherwise // 'total = hilt + blade' doesn't know whether 'total' should live // as long as 'hilt', or as long as 'blade'. fn add_inches<'a>(hilt: &'a Inches, blade: &'a Inches) { let total = hilt + blade; let Inches(t) = total; println!("length {}", t); } fn main() { let hilt = Inches(10); let blade = Inches(20); add_inches(&hilt, &blade); } 

Compilation fails with the following error:

 error: missing lifetime specifier [E0106] impl Add for &Inches { ^~~~~~~ 

I add a missing lifetime indicator (still not compiling)

 // was: impl Add for &Inches { impl Add for &'b Inches { ... } 

Compilation Error:

 error: use of undeclared lifetime name ''b' [E0261] impl Add for &'b Inches { 

I declare a lifetime on impl (now it compiles)

(Rust playground link)

 // was: impl Add for &'b Inches { impl<'b> Add for &'b Inches { ... } 

It finally compiles correctly.

My question

Why don't &Inches in impl Add for &Inches have a lifetime specifier? What problem is solved by telling the compiler that this Add method is for &Inches with some indefinite non-static lifetime 'b , and then never refers to this lifetime elsewhere?

+9
source share
1 answer

Rust 1.31 and higher

The reason is simple: it was not implemented before Rust 1.31.

Now the original example is compiled, and you can write impl Add for &Inches instead of impl<'b> Add for &'b Inches . This is due to the fact that 1.31.0 stabilized the new rules of life .

To rust 1.31

If you look at the RFC for a lifetime choice, you will see that your use case should be covered:

 impl Reader for BufReader { ... } // elided impl<'a> Reader for BufReader<'a> { .. } // expanded 

However, I tried on the playground and it does not work . The reason is that it is not yet implemented .

I typed Rust source code for such cases, but surprisingly there are few. I could only find this series of implementations for Add on native types:

 impl Add<u8> for u8 impl<'a> Add<u8> for &'a u8 impl<'a> Add<&'a u8> for u8 impl<'a, 'b> Add<&'a u8> for &'b u8 

As you can see, all times of life here are obvious; no retirement.

I believe that for your specific problem you will have to stick with an explicit lifetime until the RFC implementation is complete!

+9
source

All Articles