Description
Hi, consider this code:
#![deny(unconditional_recursion)]
struct Object {
}
impl Object {
// RENAME HERE:
fn foo(&self) -> f32 {
7.0
}
}
impl ToObject for Object {
fn to_object(&self) -> &Object {
self
}
}
trait ToObject {
fn to_object(&self) -> &Object;
}
trait ObjectOps : ToObject {
fn foo(&self) -> f32 {
self.to_object().foo()
}
}
impl<T:ToObject> ObjectOps for T {}
fn main() {
let x = Object{};
println!("{}",x.foo());
}
It works fine. Let's rename foo
to foo2
next to the comment "RENAME HERE". What happens is that this code has infinite recursion now and rustc
doesn't report any error nor warning despite the usage of #![deny(unconditional_recursion)]
.
This is a serious problem, as a simple refactoring can cause something like that and it is very, very hard to debug, especially on WASM platform, where infinite recursion can just return a random number (it is UB). This problem could be solvable if I was able to write somehow MAGIC::Object::foo(self.to_object())
instead of self.to_object().foo()
but in such a way, that the methods from ObjectOps
would not be visible in MAGIC::Object
. Currently, when refactoring such code we can get infinite recursion and spend hours debugging it :(