Skip to content
New issue

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

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

Already on GitHub? # 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
@bors
Copy link
Contributor

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?

@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.

@bors
Copy link
Contributor

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
Contributor

bors commented Sep 4, 2021

📌 Commit 8221f9e has been approved by camsteffen

@bors
Copy link
Contributor

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
Contributor

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
Contributor

bors commented Sep 4, 2021

⌛ Testing commit 8221f9e with merge a8c269a...

@bors
Copy link
Contributor

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
# for free to join this conversation on GitHub. Already have an account? # 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