I'm trying to write a function like the following in Rust:
fn double_and_square<'a, T>(x: &'a T) > /*whatever the output type of `&t * &t` is*/ {
let t = x + x;
&t * &t
}
And I want it to work on types where T
is nonCopy
.
Basically, I need to specify not only that &'a T
implements Add
(easy), but also that a reference to its output type with the lifetime of local variable t
implements Mul
.
Attempt #1 (no lifetime specified for the intermediate type):
fn double_and_square<'a, T>(x: &'a T) > <&<&'a T as Add>::Output as Mul>::Output
where &'a T: Add, &<&'a T as Add>::Output: Mul {
let t = x + x;
&t * &t
}
Results in the following compiler error:
error[E0106]: missing lifetime specifier

 where &'a T: Add, &<&'a T as Add>::Output: Mul {
 ^ expected lifetime parameter
Attempt #2 (alright, I'll add a lifetime specifier):
fn double_and_square<'a, 'b, T>(x: &'a T) > <&'b <&'a T as Add>::Output as Mul>::Output
where &'a T: Add, &'b <&'a T as Add>::Output: Mul {
let t = x + x;
&t * &t
}
Results in the following compiler error:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements

 let t = x + x;
 ^

note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body

 / fn double_and_square<'a, 'b, T>(x: &'a T) > <&'b <&'a T as Add>::Output as Mul>::Output
  where &'a T: Add, &'b <&'a T as Add>::Output: Mul {
  let t = x + x;
  &t * &t
  }
 _^
note: ...so that expression is assignable (expected &T, found &'a T)

 let t = x + x;
 ^
note: but, the lifetime must be valid for the lifetime 'b as defined on the function body

 / fn double_and_square<'a, 'b, T>(x: &'a T) > <&'b <&'a T as Add>::Output as Mul>::Output
  where &'a T: Add, &'b <&'a T as Add>::Output: Mul {
  let t = x + x;
  &t * &t
  }
 _^
note: ...so that the type `<&T as std::ops::Add<&'a T>>::Output` is not borrowed for too long

 &t * &t
 ^^
error[E0490]: a value of type `<&T as std::ops::Add<&'a T>>::Output` is borrowed for too long

 &t * &t
 ^^

note: the type is valid for the lifetime 'b as defined on the function body

 / fn double_and_square<'a, 'b, T>(x: &'a T) > <&'b <&'a T as Add>::Output as Mul>::Output
  where &'a T: Add, &'b <&'a T as Add>::Output: Mul {
  let t = x + x;
  &t * &t
  }
 _^
note: but the borrow lasts for the lifetime 'a as defined on the function body

 / fn double_and_square<'a, 'b, T>(x: &'a T) > <&'b <&'a T as Add>::Output as Mul>::Output
  where &'a T: Add, &'b <&'a T as Add>::Output: Mul {
  let t = x + x;
  &t * &t
  }
 _^
The way that I read the lifetime must be valid for the lifetime 'b as defined on the function body
tells me the compiler thinks 'b
is supposed to live as long as or longer than the whole function body, whereas I just want it to mean "any lifetime".
Question:
Is what I'm trying to do even possible in Rust? If not, are there any proposed changes I should watch that will make it possible?