I managed to do a check like Rust in an infinite loop. A very similar program compiles without problems. Why is the program that I do not want to compile?
To save you time and effort, I made minimal versions of two programs that isolate the problem. Of course, the minimal version is a pointless program. You will need to use your imagination to see my motivation.
Success
Let me start with a version that works. Pattern F<T> wraps T Target type can be converted from F<T> provided that T can.
struct F<T>(T); impl<T> From<F<T>> for Target where Target: From<T> { fn from(a: F<T>) -> Target { let b = Target::from(a.0); f(&b) } }
Here's an example of the caller:
fn main() { let x = Target; let y = F(F(F(x))); let z = Target::from(y); println!("{:?}", z); }
This one works and prints "Target" .
Renouncement
The f function does not use its argument. I would prefer that the From transformation also not use its argument, because the type F<T> may be expensive or impossible to clone. I can write a custom FromRef attribute that differs from std::convert::From by accepting an immutable loan instead of its value:
trait FromRef<T> { fn from_ref(a: &T) -> Self; }
Of course, I ultimately want to use From<&'a T> , but by defining my own trait, I can more clearly ask my question without interfering with the parameters of life. (The behavior of the check type is the same using From<&'a T> ).
Here is my implementation:
impl<T> FromRef<F<T>> for Target where Target: FromRef<T> { fn from_ref(a: &F<T>) -> Target { let b = Target::from_ref(&a.0); f(&b) } }
It compiles. However, the main() function does not matter:
fn main() { let x = Target; let y = F(F(F(x))); let z = Target::from_ref(y); println!("{:?}", z); }
This gives a huge start error message :
error[E0275]: overflow evaluating the requirement `_: std::marker::Sized` --> <anon>:26:13 | 26 | let z = Target::from_ref(y); | ^^^^^^^^^^^^^^^^ | = note: consider adding a `#![recursion_limit="128"]` attribute to your crate = note: required because of the requirements on the impl of `FromRef<F<_>>` for `Target` = note: required because of the requirements on the impl of `FromRef<F<F<_>>>` for `Target` = note: required because of the requirements on the impl of `FromRef<F<F<F<_>>>>` for `Target` etc...
What am I doing wrong?
Update
I accidentally fixed it !
The problem was that I forgot to implement FromRef<Target> for Target .
So now I would like to know: what was the compiler thinking? I still cannot associate the problem with the error message.