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

Add the derivable_impls lint #7570

Merged
merged 1 commit into from
Sep 4, 2021
Merged

Conversation

HKalbasi
Copy link
Member

@HKalbasi HKalbasi commented Aug 16, 2021

Fix #7550

changelog: Add new derivable_impls lint. mem_replace_with_default now covers non constructor cases.

@rust-highfive
Copy link

r? @flip1995

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Aug 16, 2021
@camsteffen
Copy link
Contributor

You can use is_default_equivalent_ctor. Otherwise I think you got it covered. Careful not to lint macros where a dynamically generated impl just happens to be Default-equivalent.

@HKalbasi
Copy link
Member Author

I added is_default_equivalent_ctor and some more cases to is_default.

Careful not to lint macros where a dynamically generated impl just happens to be Default-equivalent.

I think it should be ok, do you have special test in mind that I can add it?

r? @camsteffen

@rust-highfive rust-highfive assigned camsteffen and unassigned flip1995 Aug 19, 2021
@HKalbasi HKalbasi force-pushed the derivable-impls branch 2 times, most recently from c4ac1c0 to 6498b8f Compare August 19, 2021 21:13
@camsteffen
Copy link
Contributor

The lint is technically correct because the result of mem::replace is the return value of the function. Although I don't really like the suggestion in that case. I think we should allow mem::replace for primitive types.

@HKalbasi
Copy link
Member Author

Or maybe just for boolean? For integers take isn't better?

@camsteffen
Copy link
Contributor

mem::take makes the most sense when you have something with heap allocation like a Vec where you are literally taking the heap-allocated data from the Vec. mem::take with integers is okay but (at least personally) I don't think it is better than mem::replace(n, 0). Allowing primitives is the simplest way to draw the line here.

@camsteffen camsteffen added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Aug 20, 2021
@camsteffen
Copy link
Contributor

Careful not to lint macros where a dynamically generated impl just happens to be Default-equivalent.

I think it should be ok, do you have special test in mind that I can add it?

Here's a couple tests - playground

@HKalbasi
Copy link
Member Author

I disabled that lint for primitives. But it is still enable for stack allocated things like (0, false).

@rustbot label +S-waiting-on-review

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Aug 20, 2021
@camsteffen camsteffen removed the S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) label Aug 20, 2021
clippy_lints/src/derivable_impls.rs Outdated Show resolved Hide resolved
clippy_lints/src/derivable_impls.rs Show resolved Hide resolved
clippy_utils/src/lib.rs Outdated Show resolved Hide resolved
clippy_utils/src/paths.rs Outdated Show resolved Hide resolved
clippy_lints/src/derivable_impls.rs Outdated Show resolved Hide resolved
tests/ui/derivable_impls.rs Show resolved Hide resolved
clippy_utils/src/lib.rs Outdated Show resolved Hide resolved
clippy_lints/src/mem_replace.rs Outdated Show resolved Hide resolved
clippy_lints/src/derivable_impls.rs Outdated Show resolved Hide resolved
@bors
Copy link
Collaborator

bors commented Aug 23, 2021

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

@HKalbasi HKalbasi force-pushed the derivable-impls branch 5 times, most recently from 3817081 to 5167f10 Compare August 24, 2021 15:48
@flip1995
Copy link
Member

r? @camsteffen reassigning, since you already did most of the reviewing work.

@camsteffen
Copy link
Contributor

Whoops I somehow assumed this was already assigned to me.

@camsteffen
Copy link
Contributor

We should watch out for cases where a manual impl is needed because a derive adds different type bounds (rust-lang/rust#26925). For example, a struct with Option<T> does not require T: Default, but a derive adds that type bound anyways. A simple approach would be to just ignore impls with any type variables. Or, unless I'm missing something, I think it would be correct to lint if all type variables have the Default constraint. In any case, we should probably mention this issue in the lint docs.

@camsteffen camsteffen added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Aug 30, 2021
@HKalbasi
Copy link
Member Author

I now disabled lint for non-lifetime generics, because in addition to that issue, specialized impls can create false positives, and detection of them is not always easy:

struct SpecializedImpl<A, B> {
    a: A,
    b: B,
}

impl<T: Default> Default for SpecializedImpl<T, T> {
    fn default() -> Self {
        Self {
            a: T::default(),
            b: T::default(),
        }
    }
}

Not sure if there is real use case for specialized impls of default trait, but #[derive(Default)] behave differently in this case.

@camsteffen
Copy link
Contributor

Wouldn't that example be the same as derive?

@HKalbasi
Copy link
Member Author

No? I think derive will generate this:

impl<A: Default, B: Default> Default for SpecializedImpl<A, B> {
    fn default() -> Self {
        Self {
            a: A::default(),
            b: B::default(),
        }
    }
}

Copy link
Contributor

@camsteffen camsteffen left a comment

Choose a reason for hiding this comment

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

A couple more things and this is almost ready! Can you be a little more specific for the mem_replace_with_default changelog?

clippy_lints/src/derivable_impls.rs Show resolved Hide resolved
clippy_lints/src/derivable_impls.rs Show resolved Hide resolved
@HKalbasi HKalbasi force-pushed the derivable-impls branch 2 times, most recently from 502181f to e69061d Compare September 2, 2021 11:14
Copy link
Contributor

@camsteffen camsteffen left a comment

Choose a reason for hiding this comment

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

Sorry, found a couple more things.

clippy_lints/src/derivable_impls.rs Show resolved Hide resolved
clippy_lints/src/derivable_impls.rs Outdated Show resolved Hide resolved
clippy_lints/src/derivable_impls.rs Outdated Show resolved Hide resolved
@bors
Copy link
Collaborator

bors commented Sep 2, 2021

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

@HKalbasi HKalbasi force-pushed the derivable-impls branch 2 times, most recently from 479acf7 to 93390d4 Compare September 3, 2021 22:16
@camsteffen
Copy link
Contributor

Thanks!

@bors r+

@bors
Copy link
Collaborator

bors commented Sep 4, 2021

📌 Commit 8221f9e has been approved by camsteffen

@bors
Copy link
Collaborator

bors commented Sep 4, 2021

⌛ Testing commit 8221f9e with merge 6541662...

bors added a commit that referenced this pull request Sep 4, 2021
Add the `derivable_impls` lint

Fix #7550

changelog:
Add new derivable_impls lint.
mem_replace_with_default now covers non constructor cases.
@bors
Copy link
Collaborator

bors commented Sep 4, 2021

💔 Test failed - checks-action_test

@HKalbasi
Copy link
Member Author

HKalbasi commented Sep 4, 2021

changelog: is there, what is wrong?

@camsteffen
Copy link
Contributor

Oh it has to be on the same line like changelog: <stuff>

@camsteffen
Copy link
Contributor

@bors retry

@HKalbasi
Copy link
Member Author

HKalbasi commented Sep 4, 2021

Like this? Please edit it in the desired way if it is wrong.

@bors
Copy link
Collaborator

bors commented Sep 4, 2021

⌛ Testing commit 8221f9e with merge a8c269a...

@bors
Copy link
Collaborator

bors commented Sep 4, 2021

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: camsteffen
Pushing a8c269a to master...

@bors bors merged commit a8c269a into rust-lang:master Sep 4, 2021
@HKalbasi HKalbasi deleted the derivable-impls branch September 4, 2021 21:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Detect redundant Default implementations
7 participants