Undetected unconditional recursion in Clone impl using to_owned()
2412516
Opened by crumblingstatue at
fn main() {
struct Foo;
impl Clone for Foo {
fn clone(&self) -> Self {
self.to_owned()
}
}
Foo.clone();
}
Rustc gives no warning, but this overflows the stack.
Slightly more realistic example:
fn main() {
use std::borrow::{Borrow, ToOwned};
use std::ops::Deref;
struct Foo;
struct Borrowed;
impl Deref for Foo {
type Target = Borrowed;
fn deref(&self) -> &Borrowed {
unimplemented!()
}
}
impl Borrow<Borrowed> for Foo {
fn borrow(&self) -> &Borrowed {
&*self
}
}
impl ToOwned for Borrowed {
type Owned = Foo;
fn to_owned(&self) -> Foo {
unimplemented!()
}
}
impl Clone for Foo {
fn clone(&self) -> Self {
(*self).to_owned() // Oops, should have dereferenced twice
}
}
Foo.clone();
}
(Real life use case for implementing Clone through deref -> to_owned)
Is it feasible for rustc to detect this kind of cross-trait unconditional recursion?
Also see https://github.com/rust-lang/rust/issues/50049.
Mark Rousskov at 2018-05-29 14:30:17