I ran into this issue when I'm trying to create a wrapper type on several numeric types, here is a minimized example to reproduce this problem
use std::ops::Add;
struct Wrapper<T>(pub T);
impl<T: Add<Output = T>> Add for Wrapper<T> {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self(self.0.add(rhs.0))
}
}
impl<T: for<'r> Add<&'r T, Output = T>> Add<&Wrapper<T>> for Wrapper<T> {
type Output = Self;
fn add(self, rhs: &Self) -> Self::Output {
Self(self.0.add(&rhs.0))
}
}
impl<T> Add<Wrapper<T>> for &Wrapper<T>
where for<'r> &'r T: Add<T, Output = T> {
type Output = Wrapper<T>;
fn add(self, rhs: Wrapper<T>) -> Self::Output {
Wrapper((&self.0).add(rhs.0))
}
}
// this function works
fn sum1<T: Add<Output = T> + for<'r> Add<&'r T, Output = T>>(a: T, b: T) -> T {
(a + &b) + b
}
// this doesn't
fn sum2<T: Add<Output = T>>(a: T, b: T) -> T
where for<'r> &'r T: Add<T, Output = T> {
(&a + b) + a
}
fn main() {
assert_eq!(sum1(Wrapper(0), Wrapper(0)).0, 0);
assert_eq!(sum2(Wrapper(0), Wrapper(0)).0, 0);
}
I don't understand why the sum1
works but sum2
will lead to type expansion recursion:
Compiling test_ref v0.1.0 (/home/jacobz/test_ref)
error[E0275]: overflow evaluating the requirement `for<'r> &'r Wrapper<_>: Add<Wrapper<_>>`
--> src/main.rs:43:16
|
43 | assert_eq!(sum2(Wrapper(0), Wrapper(0)).0, 0);
| ^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`test_ref`)
= note: required because of the requirements on the impl of `for<'r> Add<Wrapper<Wrapper<_>>>` for `&'r Wrapper<Wrapper<_>>`
= note: 127 redundant requirements hidden
= note: required because of the requirements on the impl of `for<'r> Add<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<_>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` for `&'r Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<Wrapper<_>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
note: required by a bound in `sum2`
--> src/main.rs:32:22
|
31 | fn sum2<T: Add<Output = T>>(a: T, b: T) -> T
| ---- required by a bound in this
32 | where for<'r> &'r T: Add<T, Output = T> {
| ^^^^^^^^^^^^^^^^^^ required by this bound in `sum2`
For more information about this error, try `rustc --explain E0275`.
Is there any solution to workaround this? Thanks in advance!