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

Return early if the method is a default trait impl for boxed_local #4833

Closed
wants to merge 3 commits into from

Conversation

MentalAllergen
Copy link

fixes #4804
changelog: check for a default trait impl and a corresponding test case

If the parent node is a trait definitions, this lint shouldn't trigger
Comment on lines +160 to +164
trait DefaultTraitImplTest {
fn default_impl(self: Box<Self>) -> u32 {
5
}
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this enough to cover this fix? There might be some more niche cases which I hadn't encountered but which should be tested as well.

Copy link
Member

@flip1995 flip1995 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On a more general note: Why do you take a box instead of just a reference?

trait Trait {
    fn foo(&self) {}
}

should also work.

clippy_lints/src/escape.rs Show resolved Hide resolved
@flip1995
Copy link
Member

I don't know, why I always forget about this: #4351 (comment)

The fix is not to allow this in traits or allow the lint for unsized types, but to add a suggestion that this should be written as &T instead of Box<T>.

Are you willing to add such a suggestion in this PR or should this just be tracked in an issue (#4740) until someone else decides to add a suggestion?

It would definitely be great if you could add to the lint documentation, that this should be rewritten to &T

@MentalAllergen
Copy link
Author

On a more general note: Why do you take a box instead of just a reference?

trait Trait {
    fn foo(&self) {}
}

should also work.

The case which led me to open an issue was something akin to the following:

trait Trait {
    fn foo(self: Box<Self>) -> Result<Box<dyn Trait>, ()> {
        Err(())
    }
}

struct Foo {
    // some data
}

impl Trait for Foo {
    fn foo(self: Box<Self>) -> Result<Box<dyn Trait>, ()> {
        // actually do something with "self"
    }
}

where my intention was to consume the value and receive a new boxed trait object.

Due to having a non negligible count of structs which needed to impl Trait and Trait itself having about 7 or 8 methods of the same return type, having the default trait impl return an Err variant reduced code duplication. Upon encountering an error, the consumed boxed trait object was not necessary for error handling so letting it drop was fine.

In that situation, having this lint suggest using a reference instead of a boxed trait object would still not align with my intentions.

I've later managed to refactor all of that code so it doesn't use dynamic dispatch at all.

@MentalAllergen
Copy link
Author

I am willing to give this a try and change the lint documentation to suggest changing to a &T.
I'm fairly new to the clippy code base so any help is appreciated.

This can be implemented to suggest changing self: Box<Self> only for unsized types while keeping the old message if the type is sized. Should we prefer that to always suggesting a reference?

@flip1995
Copy link
Member

Ah I see now. I think the best way to do this would be to disable this lint for trait definitions, but only for unsized arguments. Diabling it for trait definitions completely will lead to too many FNs.

@flip1995
Copy link
Member

flip1995 commented Nov 20, 2019

I am willing to give this a try and change the lint documentation to suggest changing to a &T.

Adding this to the documentation is as easy as adding a bad+good example here

/// **Example:**
/// ```rust
/// # fn foo(bar: usize) {}
/// let x = Box::new(1);
/// foo(*x);
/// println!("{}", *x);
/// ```
pub BOXED_LOCAL,

Should we prefer that to always suggesting a reference?

Yes the suggestion should be to just remove the box, if the type is sized and change it to &T for unsized types.

add check for a by value self argument in default trait method implementation

add an example for when replacing Box<T> with &T would suffice
Copy link
Member

@flip1995 flip1995 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry, I started the review, but never pressed "Submit review" 😄

We have to look at every argument of default trait impls, not only self. But only for arguments that are sized. See is_sized for the documentation.

/// println!("{}", *x);
///
/// fn foo(arg: Box<[u32]>) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That will test-fail. Please leave the foo(*x); and rename this to bar

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

@MentalAllergen
Copy link
Author

Oh sorry, I started the review, but never pressed "Submit review" 😄

We have to look at every argument of default trait impls, not only self. But only for arguments that are sized. See is_sized for the documentation.

Thanks for the linked docs, I'll get to changing the code in a few days as Uni is heating up at the moment. Should've realized sooner that skipping linting the whole method will not suffice.

@flip1995 flip1995 added the S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) label Nov 25, 2019
@bors
Copy link
Collaborator

bors commented Dec 22, 2019

☔ The latest upstream changes (presumably #4938) made this pull request unmergeable. Please resolve the merge conflicts.

@flip1995
Copy link
Member

Thanks for contributing to Clippy! Sadly this PR was not updated in quite some time. If you waited on input from a reviewer, we're sorry that this fell under the radar. If you want to continue to work on this, just reopen the PR and/or ping a reviewer.

@flip1995 flip1995 closed this May 25, 2020
@flip1995 flip1995 added S-inactive-closed Status: Closed due to inactivity and removed S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels May 25, 2020
@HKalbasi
Copy link
Member

finished in #6571
@rustbot label -S-inactive-closed

@rustbot rustbot removed the S-inactive-closed Status: Closed due to inactivity label Jul 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

False positive for boxed local in default Trait method implementation
5 participants