Description
Code
pub trait Dog: Animal {}
pub trait Animal {
fn speak(&self) {
println!("Hey.");
}
}
impl<D> Animal for D where D: Dog {
fn speak(&self) {
self.speak()
}
}
pub struct Labrador;
impl Dog for Labrador {}
fn main() {
Labrador.speak();
}
Current output
Errors
Exited with signal 6 (SIGABRT): abort program
Standard Error
Compiling playground v0.0.1 (/playground)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.57s
Running `target/debug/playground`
thread 'main' has overflowed its stack
fatal runtime error: stack overflow
Standard Output
Desired output
warning: function cannot return without recursing
--> src/main.rs:4:5
|
4 | fn speak(&self) {
| ^^^^^^^^^^^^^^^ cannot return without recursing
5 | self.speak();
| ------------ recursive call site
|
Rationale and extra context
This class of error is properly caught and warned against in the simplest case: calling a trait method from within that same trait method. You can see this in the above code by replacing the blanket implementation with:
impl Animal for Labrador {
fn speak(&self) {
self.speak()
}
}
Which results in the warning listed above in the "desired output".
What appears to be happening is that, because Dog
is required to be Animal
, calling self.speak()
from within the blanket implementation is calling the Animal
method on Dog
- which takes precedence over calling the trait method we are currently in.
This code snippet is already seemingly tautological, and it isn't clear how the compiler is reasoning about this. A type implementing Dog
must be an Animal
, yet Labrador
cannot have the Animal
trait unless it is also a Dog
!
Other cases
No response
Rust Version
I've been using rust playground for this: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=e62693e73ead0c65f1b471f8eca6a43a
Using rust 1.82.0
Anything else?
No response