How to make the following code run?(somthing about lifetime)

fn my_add<'a, T: Add<Output = T>>(a: &'a T, b: &'a T) -> T
where
    T: Add<&'a T, Output = T>,
    &'a T: Add<&'a T, Output = T>,
{
    let c = a + b;
    let d = &c + b;
    d + c
}

T doesn't implement Clone and Copy trait.

What is stopping it from running? Can you show us the full error you get from the compiler and what you've tried to make it work?

fn my_add<'a, T: Add<Output = T>>(a: &'a T, b: &'a T) -> T
    |           -- lifetime `'a` defined here
...
150 |     let c = a + b;
    |         - binding `c` declared here
151 |     let d = &c + b;
    |             ^^----
    |             |
    |             borrowed value does not live long enough
    |             requires that `c` is borrowed for `'a`
152 |     d + c
153 | }
    | - `c` dropped here while still borrowed

Lifetime parameters of a function mean a lifetime the caller gets to pick, which will necessarily outlive the entire function. You can never refer to a local variable with a reference of that lifetime, which is what your program is trying to do with &c.

The solution is to use HRTBs to ask for Add independent of the exact lifetime:

use std::ops::Add;

fn my_add<T>(a: &T, b: &T) -> T
where
    T: Add<Output = T>,
    for<'a> &'a T: Add<Output = T>,
{
    let c = a + b;
    let d = &c + b;
    d + c
}

This bound says: β€œFor any possible lifetime, which we will call 'a, it should be possible to Add together &'a Ts and get a T.”

4 Likes

Thank you!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.