rust-clippy icon indicating copy to clipboard operation
rust-clippy copied to clipboard

Fix and improve `match_type_on_diagnostic_item`

Open Jarcho opened this issue 2 years ago • 15 comments

This extracts the fix for the lint out of #7647. There's still a couple of other functions to check, but at least this will get lint working again.

The two added util functions (is_diagnostic_item and is_lang_item) are needed to handle DefId for unit and tuple struct/variant constructors. The rustc_diagnostic_item and lang attributes are attached to the struct/variant DefId, but most of the time they are used through their constructors which have a different DefId. The two utility functions will check if the DefId is for a constructor and switch to the associated struct/variant DefId.

There does seem to be a bug on rustc's side where constructor DefIds from external crates seem to be returning DefKind::Variant instead of DefKind::Ctor(). There's a workaround put in right.

changelog: None

Jarcho avatar Nov 12 '21 01:11 Jarcho

r? @giraffate

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

rust-highfive avatar Nov 12 '21 01:11 rust-highfive

Hmm now there are two functions named is_diagnostic_item with slightly different semantics. Would it work to have is_diagnostic_item_ctor? I would think we should always know whether or not to expect a ctor, basically only with ExprKind::Call.

camsteffen avatar Nov 12 '21 16:11 camsteffen

I added them so the automated switch from match_def_path would work. Otherwise the lint needs to know which one to use for each case. The ctor DefId will always be used in an expression or pattern, but for a random DefId it could also be from the item directly.

The distinction between the two is also useless in clippy.

They could be named is_*_item_or_ctor which is what's actually happening, but that's also a cumbersome name.

Jarcho avatar Nov 12 '21 17:11 Jarcho

:umbrella: The latest upstream changes (presumably #7639) made this pull request unmergeable. Please resolve the merge conflicts.

bors avatar Nov 16 '21 03:11 bors

for a random DefId it could also be from the item directly

I don't think we have any cases where generality over the two (ctor or not) is actually needed. We are always expecting one or the other depending on context. And the ctor cases are much less common. So we can put in tcx.parent(ctor_id) for those cases and it shouldn't add up to much.

The distinction between the two is also useless in clippy

That is maybe true, but we still have to deal with the distinction. If we "cover up" the ctor DefIds, making it look like it is the diagnostic item id when it is not, that will lead to surprises when you go to use the DefId with other queries.

camsteffen avatar Nov 18 '21 05:11 camsteffen

I don't think we have any cases where generality over the two (ctor or not) is actually needed.

I was referring to the lint suggestion in this case. At the point match_def_path is called it is just a DefId from an unknown source. I guess just suggesting both options wouldn't be a big deal either for an internal lint.

Jarcho avatar Nov 18 '21 05:11 Jarcho

Ah right. Maybe you could query whether the item has a public constructor to at least narrow down some cases.

camsteffen avatar Nov 18 '21 06:11 camsteffen

The lint has to look up the DefId of the item being checked for, so it's easy enough to see if it's a tuple/unit variant. Should I just suggest reworking the code to use is_lang_ctor or is_diagnostic_ctor (and add that one) for those? Otherwise the current functions would need to stay and get renamed.

Jarcho avatar Nov 18 '21 06:11 Jarcho

First attempt at handling ctor suggestions differently.

is_diagnostic_item_or_ctor and is_lang_item_or_ctor are used for structs with publicly accessible constructors as there's no (not incredibly difficult) way to distinguish where a DefId came from.

is_diagnostic_ctor is the counterpart to is_lang_item. There aren't any uses of it, but it's needed to provide a suggestion.

Jarcho avatar Jan 01 '22 23:01 Jarcho

:umbrella: The latest upstream changes (presumably #8219) made this pull request unmergeable. Please resolve the merge conflicts.

bors avatar Jan 04 '22 22:01 bors

:umbrella: The latest upstream changes (presumably #8468) made this pull request unmergeable. Please resolve the merge conflicts.

bors avatar Feb 24 '22 18:02 bors

:umbrella: The latest upstream changes (presumably #8939) made this pull request unmergeable. Please resolve the merge conflicts.

bors avatar Jun 27 '22 00:06 bors

The only extra function introduced now is is_res_diagnostic_ctor which is unused because there aren't any diagnostic item variants currently.

Jarcho avatar Jun 29 '22 13:06 Jarcho

:umbrella: The latest upstream changes (presumably #8666) made this pull request unmergeable. Please resolve the merge conflicts.

bors avatar Jun 30 '22 04:06 bors

:umbrella: The latest upstream changes (presumably #9279) made this pull request unmergeable. Please resolve the merge conflicts.

bors avatar Aug 02 '22 10:08 bors

:umbrella: The latest upstream changes (presumably #8696) made this pull request unmergeable. Please resolve the merge conflicts.

bors avatar Aug 21 '22 08:08 bors

:umbrella: The latest upstream changes (presumably #9573) made this pull request unmergeable. Please resolve the merge conflicts.

bors avatar Oct 02 '22 10:10 bors

r? @llogiq

It looks like @giraffate is either busy or forgot about this.

Jarcho avatar Oct 02 '22 13:10 Jarcho

Dogfood says no:

2022-10-02T13:08:48.0943209Z     Checking clippy_lints v0.1.66 (/home/runner/work/rust-clippy/rust-clippy/clippy_lints)
2022-10-02T13:08:48.0943818Z error: dereferencing a slice pattern where every element takes a reference
2022-10-02T13:08:48.0944250Z   --> src/methods/manual_ok_or.rs:25:41
2022-10-02T13:08:48.0944504Z    |
2022-10-02T13:08:48.0957818Z 25 |         if let ExprKind::Call(err_path, &[ref err_arg]) = or_expr.kind;
2022-10-02T13:08:48.0958204Z    |                                         ^^^^^^^^^^^^^^
2022-10-02T13:08:48.0958444Z    |
2022-10-02T13:08:48.0959050Z    = note: `-D clippy::needless-borrowed-reference` implied by `-D clippy::all`
2022-10-02T13:08:48.0959790Z    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference
2022-10-02T13:08:48.0960246Z help: try removing the `&` and `ref` parts
2022-10-02T13:08:48.0960518Z    |
2022-10-02T13:08:48.0960949Z 25 -         if let ExprKind::Call(err_path, &[ref err_arg]) = or_expr.kind;
2022-10-02T13:08:48.0961336Z 25 +         if let ExprKind::Call(err_path, [err_arg]) = or_expr.kind;

llogiq avatar Oct 02 '22 15:10 llogiq

Oops. Looks like I didn't push when I fixed that.

Jarcho avatar Oct 02 '22 18:10 Jarcho

LGTM.

Thank you, this approach seems a clear improvement.

@bors r+

llogiq avatar Oct 02 '22 19:10 llogiq

:pushpin: Commit 162aa19793f21c99cf7ec2a8c080ee2f8843f7db has been approved by llogiq

It is now in the queue for this repository.

bors avatar Oct 02 '22 19:10 bors

:hourglass: Testing commit 162aa19793f21c99cf7ec2a8c080ee2f8843f7db with merge bef93d3b1464b6d467482d47a53c62aadaa9f41c...

bors avatar Oct 02 '22 19:10 bors

:sunny: Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test Approved by: llogiq Pushing bef93d3b1464b6d467482d47a53c62aadaa9f41c to master...

bors avatar Oct 02 '22 19:10 bors