Why doesn't Rust give a "unconditional recursion" warning for using x.into()
method when it gives warning for Self::from(x)
?
Consider below example, in rust playground:
struct Foo;
struct Bar;
impl From<Foo> for Bar {
fn from(x: Foo) -> Self {
x.into() // No recursion warning
}
}
fn main() {}
Consider another example that shows recursive warning in rust playground
struct Foo;
struct Bar;
impl From<Foo> for Bar {
fn from(x: Foo) -> Self {
Self::from(x) // Shows recursion warning
}
}
fn main() {}
warning: function cannot return without recursing
--> src/main.rs:5:5
|
5 | fn from(x: Foo) -> Self {
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
6 | Self::from(x)
| ------------- recursive call site
|
= note: `#[warn(unconditional_recursion)]` on by default
= help: a `loop` may express intention better if this is on purpose
The method is not directly calling itself, it is calling another trait implementation. It happens that the trait implementation will call back to the first, but the compiler does not do cross-function analysis. This does not trigger a warning either:
fn a() { b(); }
fn b() { a(); }
fn main() {
a();
}
Cross-function checks are more complicated and harder to apply efficiently than local-function checks. There is an open issue to catch this case.