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

Fix output lifetime collection in needless_lifetimes #12456

Closed
wants to merge 2 commits into from

Conversation

m-rph
Copy link
Contributor

@m-rph m-rph commented Mar 10, 2024

This is currently draft as I am unsure about how to go with fixing this. I don't completely understand the code D:, but I've identified the issue more or less.

The problem

In the following snippet

mod issue11291 {
    use std::collections::HashMap;
    pub struct MyContainer(HashMap<u8, u32>);
    impl MyContainer {
        pub fn iter<'a>(&'a self) -> impl Iterator<Item = (&'a u8, &'a u32)> + 'a {
            //~^ ERROR: the following explicit lifetimes could be elided: 'a
            self.0.iter()
        }
    }
}

Clippy will suggest:

 pub fn iter<'a>(&'a self) -> impl Iterator<Item = (&'_ u8, &'a u32)> + 'a

Which misses the 2 latter lifetimes.

I probed a bit into the implementation. The lifetimes of the output are collected via a walker. The implementation of the walker is identical for both input and output declaration.

The problem seems related to the truncation in TyKind::OpaqueDef

TyKind::OpaqueDef(item, bounds, _) => {
let map = self.cx.tcx.hir();
let item = map.item(item);
let len = self.lts.len();
walk_item(self, item);
self.lts.truncate(len);
self.lts.extend(bounds.iter().filter_map(|bound| match bound {
GenericArg::Lifetime(&l) => Some(l),
_ => None,
}));
},

Without the truncation, all lifetimes are collected, but going by hir::DefId, we have 4 different lifetimes (LTs) instead of 3. Going by span, we have 3 LTs.

Removing the truncation and keeping only unique LT by their span causes something to break in the linting logic.

Update 1:

It seems that the issue is related to the defids of the LTs, as they can't be found in the allowed LTs.

Update 2:

Yup, using localdefid causes issues with opaque types. Using identifiers for any checks works better and the types are correlated selected. need to fix how the suggestions work to account for that, but otherwise it seems correct-ish.

changelog: [`needless_lifetimes`]: Suggested fix will now elide all output lifetimes.

fixes: #12085
fixes: #11291

r? @blyxyas

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Mar 10, 2024
@m-rph m-rph changed the title Fix output lifetime collection Fix output lifetime collection in needless_lifetimes Mar 10, 2024
Copy link
Contributor Author

@m-rph m-rph left a comment

Choose a reason for hiding this comment

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

Current commit results in a regression where more LTs are collected than they should be.

Comment on lines 271 to +272
LL | fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 {
| ^^ ^^
|
help: elide the lifetimes
|
LL - fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 {
LL + fn multiple_inputs_output_not_elided<'b>(x: &u8, y: &'b u8, z: &'b u8) -> &'b u8 {
|
| ^^ ^^ ^^ ^^ ^^
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is wrong, it wrongly collects both 'a and 'b, should only elide 'a

Comment on lines 127 to +128
LL | fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
| ^^ ^^
|
help: elide the lifetimes
|
LL - fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
LL + fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str {
|
| ^^ ^^ ^^ ^^
Copy link
Contributor Author

Choose a reason for hiding this comment

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

'a shouldn't be collected.

LL - fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {}
LL + fn bar(x: &u8, y: &'_ u8, z: &'_ u8) {}
|
| ^^ ^^ ^^ ^^
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same issue as above.

@xFrednet
Copy link
Member

Hey @m-rph, this is a ping from triage, since there hasn't been any activity in some time. Are you still planning to continue this implementation?

@rustbot author

@rustbot rustbot 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 Jun 20, 2024
@m-rph
Copy link
Contributor Author

m-rph commented Jun 20, 2024

@xFrednet yup. Need to find time. There's 5 issues that need to be addressed and will do all of them in 1 rust go.

@xFrednet
Copy link
Member

xFrednet commented Jun 20, 2024

Okay, just here to poke you a bit ^^ Let me know if you need any help.

error: found time
  --> https://github.com/rust-lang/rust-clippy/pull/12456/comment-5/1:29
   |
   | @xFrednet yup. Need to find time. 
   |                             ^^^^
   = note: This `time` might be a different type then the
           one you where refering to

Sorry, couldn't resist after your comment :P

@xFrednet
Copy link
Member

The assignment was a test. I'm unassigning myself again. Thank you for the help!

@xFrednet xFrednet removed their assignment Jun 25, 2024
@m-rph
Copy link
Contributor Author

m-rph commented Jun 27, 2024

With Alejandra we discussed whether I could rewrite the lint given how old it was, both options are on the table. Seeing that I have accumulated a large collection of issues around needless_lifetimes, I think it's best to just go ahead with the rewrite.

@xFrednet
Copy link
Member

Hey, @m-rph this is a ping from triage, since there hasn't been any activity in some time. Are you still planning to continue this implementation?

Also, is this PR maybe outdated, since you crated #13141?

@rustbot author

@m-rph
Copy link
Contributor Author

m-rph commented Jul 23, 2024

Forgot about this. I will close.

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.

needless_lifetimes wrongly detect elidable lifetime with Iterator FP: needless_lifetimes
4 participants