Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undetected unconditional recursion in Clone impl using to_owned() #40437

Open
crumblingstatue opened this issue Mar 11, 2017 · 1 comment
Open
Labels
A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@crumblingstatue
Copy link
Contributor

crumblingstatue commented Mar 11, 2017

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?

@Mark-Simulacrum Mark-Simulacrum added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 12, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 26, 2017
@Mark-Simulacrum Mark-Simulacrum added A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. and removed A-diagnostics Area: Messages for errors, warnings, and lints labels May 29, 2018
@Mark-Simulacrum
Copy link
Member

Also see #50049.

@jonas-schievink jonas-schievink added C-enhancement Category: An issue proposing an enhancement or a PR with one. and removed C-bug Category: This is a bug. labels Aug 10, 2020
@fmease fmease added A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. and removed A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. labels Dec 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants