Skip to content

Dereference one less on search_is_some and make it auto-fixable #4454

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

Merged
merged 5 commits into from Sep 4, 2019
Merged

Dereference one less on search_is_some and make it auto-fixable #4454

merged 5 commits into from Sep 4, 2019

Conversation

ghost
Copy link

@ghost ghost commented Aug 26, 2019

Fixes #4453

changelog: none

@ghost
Copy link
Author

ghost commented Aug 26, 2019

@flip1995 do you think this is enough, or is some logic required?
If so, could you mentor me?

I can make it auto fixable once everything else works 😉

How can I run doc tests? cargo test --doc SEARCH_IS_SOME doesn't work for me :/

@phansch
Copy link
Member

phansch commented Aug 26, 2019

How can I run doc tests? cargo test --doc SEARCH_IS_SOME doesn't work for me :/

I think you'll first have to change to the clippy_lints directory for them to work.

@flip1995 flip1995 added the S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) label Aug 26, 2019
@ghost
Copy link
Author

ghost commented Aug 26, 2019

I though this would be easier and the code better to understand. But it seems that I am not capable of fixing the issue 😢

@flip1995
Copy link
Member

flip1995 commented Aug 26, 2019

Your not really far from the goal, and I'm happy to support you to achieve it!

  • You already have the closure argument: closure_arg
  • You only need to care about closure arguments, that are PatKind::Lit(expr)
  • Get the closure_arg_snip = snippet(cx, expr, "..") (This is the name of the closure argument)
  • Run search_snippet.replace(&format!("*{}", closure_arg_snip), &closure_arg_snip)

For test cases, see Playground

@ghost
Copy link
Author

ghost commented Aug 26, 2019

I think you'll first have to change to the clippy_lints directory for them to work.

Thanks. That worked 😃

@ghost
Copy link
Author

ghost commented Aug 26, 2019

@flip1995 thank you for the help 👍

Are you sure I need closure_arg and not the closure_body.value?
PatKind::Lit never finds a match

@flip1995
Copy link
Member

Huh, I'm pretty sure that you need closure_arg. body.value is the actual body of the closure.

It should find a match for _.find(|x| ..), except something else is meant by PatKind::Lit. What you can do to find out the correct PatKind for closures like this, is to add a dbg!(closure_arg.node) to the code and then look at the stderr output, when running the testcase: TESTNAME=ui/<name_of_search_is_some_test_without_.rs> cargo +master uitest

@ghost ghost changed the title WIP: Dereference one less on search_is_some Dereference one less on search_is_some and make it auto-fixable Aug 26, 2019
@ghost
Copy link
Author

ghost commented Aug 26, 2019

LL |     let _ = (0..1).find(|x| *x == 0).is_some();
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `any(|x| x == 0)`

it seems like the lint isn't very exact. This causes rust-fix to replace everything with just any(...)

let _ = any(|x| x == 0);

Or did I do something wrong?

@flip1995
Copy link
Member

flip1995 commented Aug 26, 2019

Rustfix always replaces the span you specify with the suggested code. You have to build the span by hand, since it does not exist in the way you need it. This shouldn't be a problem though. Just search in the methods/mod.rs file for span.with_hi to see how to do this.

@ghost
Copy link
Author

ghost commented Aug 27, 2019

Rustfix always replaces the span you specify with the suggested code

so I should be able to replace expr.span, with a formatted {0}({1}).is_some(), right?

@flip1995
Copy link
Member

No, because the expr.span is everything from the iterator expression ((0..1). in the example above, or e.g. vec.iter().) up to the call of is_some(). Or in other words, everything that is indicated by the ^ in the error message.

You only want to replace the find(..).is_some() with any(..) though. That means you have to construct a span, that starts at find... and ends at ...some(). You already have a span that ends at ...some(): expr.span. Now you need a span that starts with find....


I just looked up how to get this span, and saw, that it is not that easy (and not really easy to explain the changes that need to be made). So I decided to write a patch for you, that simplifies this. (I'll notify you once it's ready)

While looking into this, I found, that there already exists a function to get the name of the closure arg:

pub fn get_arg_name(pat: &Pat) -> Option<ast::Name> {
match pat.node {
PatKind::Binding(.., ident, None) => Some(ident.name),
PatKind::Ref(ref subpat, _) => get_arg_name(subpat),
_ => None,
}
}

You can just use this.

@flip1995
Copy link
Member

flip1995 commented Aug 28, 2019

Here's the patch: https://github.com/flip1995/rust-clippy/commits/method_calls_spans

You can look at the second to last commit on the branch on how to use the method spans. Just git cherry-pick the commits on this PR.

@bors
Copy link
Contributor

bors commented Aug 28, 2019

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

@ghost
Copy link
Author

ghost commented Aug 29, 2019

almost worked

@bors
Copy link
Contributor

bors commented Aug 29, 2019

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

@phansch
Copy link
Member

phansch commented Aug 29, 2019

Sorry about the merge conflict, let me know if I can help resolving it =)

@flip1995
Copy link
Member

That was my fault in 6035b65, so I'd also resolve it for you, if need be.

@ghost
Copy link
Author

ghost commented Aug 29, 2019

I don't get what is going on.
Rebasing just broke my lint again
2019-08-29-173031_556x75_scrot

Please fix it for me :)

@flip1995
Copy link
Member

Done 👍

@flip1995
Copy link
Member

flip1995 commented Sep 2, 2019

Could you add a test case where x is derefed multiple times:

let _ = vec.iter().find(|x| **x == 0).is_some();

@flip1995
Copy link
Member

flip1995 commented Sep 3, 2019

Ok one last change and a run of ./util/dev fmt and this is ready to merge. Sorry that this was harder, than expected. I'm really bad when it comes to judging if an issue is a good first issue 😄

@flip1995
Copy link
Member

flip1995 commented Sep 4, 2019

Thanks!

@bors r+

@bors
Copy link
Contributor

bors commented Sep 4, 2019

📌 Commit 64cd9e4 has been approved by flip1995

@bors
Copy link
Contributor

bors commented Sep 4, 2019

⌛ Testing commit 64cd9e4 with merge 8239b76...

bors added a commit that referenced this pull request Sep 4, 2019
Dereference one less on search_is_some and make it auto-fixable

Fixes #4453

changelog: none
@bors
Copy link
Contributor

bors commented Sep 4, 2019

☀️ Test successful - checks-travis, status-appveyor
Approved by: flip1995
Pushing 8239b76 to master...

@bors bors merged commit 64cd9e4 into rust-lang:master Sep 4, 2019
@ghost ghost deleted the search_is_some branch September 4, 2019 16:57
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.

Wrong suggestion in search_is_some lint
3 participants