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

needless-lifetime - nested elision sites #5978

Merged
merged 7 commits into from
Oct 1, 2020

Conversation

tnielens
Copy link
Contributor

Closes #2944

changelog: fix needless-lifetime nested elision site FPs

@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 28, 2020
@tnielens tnielens changed the title Needless lifetime needless-lifetime - nested elision sites Aug 28, 2020
@ebroto
Copy link
Member

ebroto commented Aug 31, 2020

r? @ebroto

(I started the review, will try to finish it later in the day)

@ebroto ebroto assigned ebroto and unassigned flip1995 Aug 31, 2020
Copy link
Member

@ebroto ebroto left a comment

Choose a reason for hiding this comment

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

Sorry for the delay in getting the PR reviewed, this is a complex topic with many edge cases :)

I have two main concerns about the current approach:

  • We bail out if we find function pointers or closure trait bounds, but the only case that creates false positives is when those have named lifetimes. This leads to unnecessary false negatives.
  • We are duplicating efforts (see below).

Looking at the (long) history of the lint, it seems that it was trying to prevent the same cases you identified in your analysis here (modulo function pointers, which is a very good catch of yours 👍)

(I can't put comments on code that has not been edited, so this will be a bit tough to explain correctly)

  • For the outlives bound on impl Trait in return position, a check was added in support impl trait for needless lifetimes #1400. There is even a test which is lost in the crashes directory (needless_lifetimes_impl_trait, I think that it's there by mistake). The problem in the issue we are resolving here is that the outlives bound is nested as a type parameter of another impl Trait, so the RefVisitor needs to recurse into nested items, which we can accomplish by using NestedVisitorMap::All in RefVisitor::nested_visit_map.

  • For trait bounds (in general), the lint is already bailing out if they are found in the generic parameters. This works also for impl Trait in parameter position, but not in return position. The fix was introduced in Fix false positive unused_lifetime when referenced in generic bounds. #2855. We can use the same approach for impl Trait in return position and for function pointers by "manually" recursing into those looking for named lifetimes, and bail out if we find them.

In RefVisitor::visit_ty, we can add this branch to the match for the function pointers:

            TyKind::BareFn(bare_fn_ty) => {
                let mut visitor = RefVisitor::new(self.cx);
                walk_ty(&mut visitor, ty);
                if visitor.abort || visitor.lts.iter().any(|lt| matches!(lt, RefLt::Named(_))) {
                    self.abort = true;
                }
                return; // don't recurse into the fn declaration
            },

For the trait bounds, we can add this snippet inside the for that iterates on exist_ty.bounds:

                        let mut visitor = RefVisitor::new(self.cx);
                        walk_param_bound(&mut visitor, bound);
                        if visitor.abort || visitor.lts.iter().any(|lt| matches!(lt, RefLt::Named(_))) {
                            self.abort = true;
                            return;
                        }

(We can maybe factor something out by adding a method to the visitor)

I think this way we can avoid duplicating efforts and the false negatives. Please tell me if something is not clear :)

tests/ui/needless_lifetimes.rs Outdated Show resolved Hide resolved
tests/ui/needless_lifetimes.stderr Outdated Show resolved Hide resolved
tests/ui/needless_lifetimes.rs Show resolved Hide resolved
@ebroto ebroto 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 Sep 1, 2020
@tnielens
Copy link
Contributor Author

tnielens commented Sep 2, 2020

thanks for the review @ebroto, I'll dive into asap.

@tnielens
Copy link
Contributor Author

tnielens commented Sep 8, 2020

I reworked the impl and tried to integrate it better in the existing code base. I still have to go over the list of test cases suggested by @ebroto.

@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 Sep 8, 2020
Copy link
Member

@ebroto ebroto left a comment

Choose a reason for hiding this comment

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

I did not have time to dig into the rewrite (sorry about that, I had smaller changes in mind), and sadly won't have until around the end of the week. Hopefully I will recover my normal schedule after that :)

I see some review comments were not applied (here, both cases), and some ui tests are crashing. Please ping me back with those addressed.

clippy_lints/src/utils/paths.rs Show resolved Hide resolved
@ebroto ebroto 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 Sep 15, 2020
tests/ui/needless_lifetimes.rs Outdated Show resolved Hide resolved
tests/ui/needless_lifetimes.rs Show resolved Hide resolved
Copy link
Member

@ebroto ebroto left a comment

Choose a reason for hiding this comment

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

I can't reproduce the test crashes locally now 👍

Besides my two last comments, I think we still miss some cases with fn pointers inside fn pointers/trait bounds:

    fn fun1<'a>(_: &'a i32) -> fn(fn(&'a i32) -> &'a i32) -> i32 {
        |f| 42
    }
    fn fun2<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 {
        |f| 42
    }

    fn fun3<'a>(_: &'a i32) -> impl Fn(fn(&'a i32)) {
        |f| ()
    }
    fn fun4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) {
        |f| ()
    }

(I've tested them and they work as expected)

@tnielens
Copy link
Contributor Author

Thanks @ebroto .
Didn't have much contribution time last week. Will try to finish this asap.

@tnielens
Copy link
Contributor Author

@ebroto I should have addressed all your remarks.

@flip1995 flip1995 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 Oct 1, 2020
Copy link
Member

@ebroto ebroto left a comment

Choose a reason for hiding this comment

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

LGTM!

Sorry for the long review process. I'd like to thank you for this fix and in general for your continued efforts in fixing long standing bugs. Your work is very much appreciated.

@ebroto
Copy link
Member

ebroto commented Oct 1, 2020

@bors r+

@bors
Copy link
Contributor

bors commented Oct 1, 2020

📌 Commit cb2be6f has been approved by ebroto

@bors
Copy link
Contributor

bors commented Oct 1, 2020

⌛ Testing commit cb2be6f with merge d431373...

@tnielens
Copy link
Contributor Author

tnielens commented Oct 1, 2020

Happy to see this merged! Thanks @ebroto for the multiple reviews ;)

@bors
Copy link
Contributor

bors commented Oct 1, 2020

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

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.

Incorrect needless_lifetimes warning for impl Trait based code
5 participants