-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Open
Labels
A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.C-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
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?
Metadata
Metadata
Assignees
Labels
A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.C-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.