Skip to content

WIP: Add `not_exhaustive_enough´ lint - #6328

Closed
jrqc wants to merge 9 commits into
rust-lang:masterfrom
jrqc:not_exhaustive_enough
Closed

WIP: Add `not_exhaustive_enough´ lint#6328
jrqc wants to merge 9 commits into
rust-lang:masterfrom
jrqc:not_exhaustive_enough

Conversation

@jrqc

@jrqc jrqc commented Nov 12, 2020

Copy link
Copy Markdown
Contributor

r? @ebroto
Fixes #5557
changelog: new lint not_exhaustive_enough

@ebroto ebroto self-assigned this Nov 13, 2020
Comment on lines +34 to +36
/// E::Third => {}
/// }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The point of #[non_exhaustive] is that the wildcard match is always required:

Suggested change
/// E::Third => {}
/// }
/// E::Third => {}
/// _ => {}
/// }

@ebroto ebroto left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the effort you've put into this!

I did a first round of review, don't hesitate to ask for clarification if needed.

Comment thread clippy_lints/src/not_exhaustive_enough.rs Outdated
Comment thread clippy_lints/src/not_exhaustive_enough.rs Outdated
Comment thread clippy_lints/src/not_exhaustive_enough.rs
Comment thread clippy_lints/src/not_exhaustive_enough.rs Outdated
Comment thread src/lintlist/mod.rs Outdated
Comment thread tests/ui/not_exhaustive_enough.stderr Outdated
Comment thread tests/ui/not_exhaustive_enough.rs Outdated
Comment thread tests/ui/not_exhaustive_enough.rs
Comment thread tests/ui/not_exhaustive_enough.rs
Comment thread clippy_lints/src/not_exhaustive_enough.rs Outdated
@ebroto ebroto added the S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) label Nov 24, 2020
@ebroto

ebroto commented Nov 24, 2020

Copy link
Copy Markdown
Contributor

Also, my apologies for the delay in reviewing, I did not have much free time lately.

@Rantanen

Copy link
Copy Markdown
Contributor

I'm slightly concerned that the full use of this lint will be held back by inability to distinguish between:

  • I want to only match these two items and don't care about the rest.
  • I want to match everything, but need to use wildcard for non_exhaustive.
match io_error.kind() {
  ErrorKind::TimedOut => self.retry(),
  _ => return Err(io_error),  // This is intended to match all known and unknown kinds.
}
if let Some(Foo { x, .. /* don't care for the rest */ }) = maybe_foo {
  ..
}

These issues can always be ignored case-by-case with #[allow(..)] attributes on the statements, but if that has to be done frequently the added noise of said attributes might outweigh the benefits.

I don't really have any good solutions to this problem and I do feel having the lint as it is implemented here is better than not having it at all. :)

@jrqc

jrqc commented Nov 24, 2020

Copy link
Copy Markdown
Contributor Author

Thank you for the review! I will make the necessary changes as soon as possible

@ebroto

ebroto commented Nov 24, 2020

Copy link
Copy Markdown
Contributor

@Rantanen that's a very good point.

The idea behind the lint is to warn in case new fields/variants are added, so it should target those cases where the user wanted to be as exhaustive as possible. But we don't know how the data structure looked like when the user wrote the code, so we can only approximate.

Some possible heuristics could be (although I'm not happy with any of them TBH):

  • Warn only if a majority of the fields/variants are already included (i.e. >= n/2+1).
  • Do not warn if only one field/variant is included (without taking wildcard/rest pattern into account).

@ebroto

ebroto commented Nov 24, 2020

Copy link
Copy Markdown
Contributor

If the lint turns out to be more annoying than helpful we can always turn it into a restriction lint.

@bors

bors commented Nov 27, 2020

Copy link
Copy Markdown
Contributor

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

Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels:

@rustbot modify labels: +S-waiting-on-review -S-waiting-on-author

@giraffate

Copy link
Copy Markdown
Contributor

ping from triage @jrqc. There seem to be some small fixes left to be done. Could you have any update on this?

@jrqc

jrqc commented Dec 29, 2020

Copy link
Copy Markdown
Contributor Author

Sorry about the delayed response @ebroto @giraffate
I will update it today

@jrqc

jrqc commented Dec 30, 2020

Copy link
Copy Markdown
Contributor Author

@ebroto Made the necessary changes! Hope I didn't miss anything
Again sorry about the late edit

@jrqc
jrqc force-pushed the not_exhaustive_enough branch from 31a5752 to 891d914 Compare December 30, 2020 17:57
@ebroto ebroto added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties and removed S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels Jan 3, 2021
@ebroto

ebroto commented Jan 3, 2021

Copy link
Copy Markdown
Contributor

Sorry about the delayed response

No problem, thanks for sticking with it! I will try to review in the coming days.

@ebroto

ebroto commented Jan 16, 2021

Copy link
Copy Markdown
Contributor

r? @Manishearth (I'm leaving the team, so I'm reassigning my PRs to other active members)

@rust-highfive rust-highfive assigned Manishearth and unassigned ebroto Jan 16, 2021
@Manishearth

Copy link
Copy Markdown
Member

I'll review this when I get a chance, but I'm wondering: we're replicating a lot of the exhaustiveness checking logic in rustc, yeah? Can we use it, or make this lint a lint in rustc?

@Manishearth

Copy link
Copy Markdown
Member

@flip1995 what are your opinions on the above^ ?

@flip1995

Copy link
Copy Markdown
Member

I don't really have an opinion on this, since I didn't review any of the exhaustiveness PRs AFAICR. I just can give a general answer: If we can share code with rustc, we should do that. But I don't know how code in Clippy or rustc looks like for exhaustiveness checks.

@Manishearth

Copy link
Copy Markdown
Member

@flip1995 so the thing is that rustc already has exhaustiveness checks, and this is a lint that was proposed in a Rust RFC, so it would both be easy to implement in rustc and make sense. It feels weird to reimplement exhaustiveness checking in a partial way outside of rustc when we can have a perfect version of this lint in rustc.

@flip1995

Copy link
Copy Markdown
Member

Yeah, agreed.

@giraffate

Copy link
Copy Markdown
Contributor

ping from triage @Manishearth. Do we still need discussion here?

@Manishearth

Copy link
Copy Markdown
Member

Yeah, sorry, I think we've discussed this and we shouldn't be doing this in clippy. It's worth filing a bug on rust-lang/rust to add such an allow-default lint. Sorry @jrqc!

@jplatte

jplatte commented Apr 18, 2021

Copy link
Copy Markdown
Contributor

I can't find an issue about this lint at rust-lang/rust, did anybody end up creating one? Also, given that this won't be implemented in clippy, somebody should close the associated issue (#5557).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties

Projects

None yet

Development

Successfully merging this pull request may close these issues.

New lint: warn about missing variants/fields for non-exhaustive enums/structs

8 participants