Skip to content

[filter_next]: suggest making binding mutable if it needs to be #11016

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 1 commit into from
Jul 10, 2023

Conversation

y21
Copy link
Member

@y21 y21 commented Jun 23, 2023

Fixes #10029

changelog: [filter_next]: suggest making binding mutable if it needs to be and adjust applicability

@rustbot
Copy link
Collaborator

rustbot commented Jun 23, 2023

r? @dswij

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Jun 23, 2023
&& let Some(hir::Node::Pat(pat)) = cx.tcx.hir().find(id)
&& let hir::PatKind::Binding(BindingAnnotation(_, Mutability::Not), _, ident, _) = pat.kind
{
(Applicability::Unspecified, Some((pat.span, ident)))
Copy link
Member Author

Choose a reason for hiding this comment

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

It can no longer be a machine applicable suggestion if it needs to be made mutable because of cases like these:

let (Ok(f) | Err(f)) = ...;
f.filter(...).next();

There are multiple bindings that would need to be made mutable, but cx.tcx.hir().find(id) only returns one pattern.

iter_skip_next is doing this as well, so I think having it be unspecified is fine.

if_chain! {
if let Some(id) = path_to_local(recv);
if let Node::Pat(pat) = cx.tcx.hir().get(id);
if let PatKind::Binding(ann, _, _, _) = pat.kind;
if ann != BindingAnnotation::MUT;
then {
application = Applicability::Unspecified;
diag.span_help(
pat.span,
format!("for this change `{}` has to be mutable", snippet(cx, pat.span, "..")),
);
}
}

Copy link
Member

Choose a reason for hiding this comment

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

I gues we can walk the parent to find all the bindings, but that's also not simple. This is good enough for now

@dswij
Copy link
Member

dswij commented Jun 25, 2023

Can you help to review this? @blyxyas

@blyxyas
Copy link
Member

blyxyas commented Jun 25, 2023

Yep, will review it! 🤠

Copy link
Member

@blyxyas blyxyas left a comment

Choose a reason for hiding this comment

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

Just a mini-nit, but it's very good.. Thanks ❤️!

use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_span::sym;

use super::FILTER_NEXT;

fn path_to_local(expr: &hir::Expr<'_>) -> Option<hir::HirId> {
Copy link
Member

Choose a reason for hiding this comment

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

We have a path_to_local helper in clippy_utils. Can we use that here?

Copy link
Member Author

@y21 y21 Jun 29, 2023

Choose a reason for hiding this comment

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

If I remember correctly, the existing path_to_local in utils doesn't "work" if the local is reached through field accesses, so for example it would return false for a.b[0] if given the id of the local a, but we need it to return true, because we use this logic to figure out if a binding needs to be made mutable, and a.b[0].find(..) requires a be mutable. Maybe this could be better named or have a comment explaining it.

Copy link
Member

Choose a reason for hiding this comment

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

clippy_utils::path_to_local is too primitive in my opinion. It only handles the case where the expression is a Path, and its Res is a Res::Local. Maybe we should modify it and make it handle this new cases.

(path_to_local's source)

&& let Some(hir::Node::Pat(pat)) = cx.tcx.hir().find(id)
&& let hir::PatKind::Binding(BindingAnnotation(_, Mutability::Not), _, ident, _) = pat.kind
{
(Applicability::Unspecified, Some((pat.span, ident)))
Copy link
Member

Choose a reason for hiding this comment

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

I gues we can walk the parent to find all the bindings, but that's also not simple. This is good enough for now

@bors
Copy link
Contributor

bors commented Jul 9, 2023

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

Copy link
Member

@blyxyas blyxyas left a comment

Choose a reason for hiding this comment

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

LGTM, Thanks! ❤️

@dswij
Copy link
Member

dswij commented Jul 10, 2023

Thank you!

@bors r=blyxyas,dswij

@bors
Copy link
Contributor

bors commented Jul 10, 2023

📌 Commit 23ac723 has been approved by blyxyas,dswij

It is now in the queue for this repository.

@bors
Copy link
Contributor

bors commented Jul 10, 2023

⌛ Testing commit 23ac723 with merge 3be3fb7...

@bors
Copy link
Contributor

bors commented Jul 10, 2023

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: blyxyas,dswij
Pushing 3be3fb7 to master...

@bors bors merged commit 3be3fb7 into rust-lang:master Jul 10, 2023
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.

filter_next: after fixes were automatically applied the compiler reported errors
5 participants