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

add extra byref checking for the guard's local #11468

Merged
merged 3 commits into from Sep 16, 2023

Conversation

kiscad
Copy link
Contributor

@kiscad kiscad commented Sep 7, 2023

changelog: [redundant_guards]: Now checks if the variable is bound using ref before linting.

The lint should not be emitted, when the local variable is bind by-ref in the pattern.

fixes #11465

@rustbot
Copy link
Collaborator

rustbot commented Sep 7, 2023

r? @blyxyas

(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 Sep 7, 2023

for pat in *pats {
if let PatKind::Binding(annot, pat_id, ..) = &pat.kind
&& matches!(annot.0, rustc_ast::ByRef::No)
Copy link
Member

Choose a reason for hiding this comment

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

Would it make sense to have this ByRef check in the get_pat_binding function, instead of duplicating the code for finding the right binding in a new function? I.e. having it here:

if let PatKind::Binding(_, hir_id, _, _) = pat.kind
&& hir_id == local

Copy link
Contributor Author

@kiscad kiscad Sep 8, 2023

Choose a reason for hiding this comment

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

Thanks. This is better.

@Alexendoo Alexendoo linked an issue Sep 7, 2023 that may be closed by this pull request
@@ -80,6 +81,37 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
}
}

fn is_the_local_binded_by_value_in_pat(local: &Expr<'_>, arm: &Arm<'_>) -> bool {
Copy link
Member

Choose a reason for hiding this comment

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

This name probably should be more illustrative.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, this function is removed now.

Copy link
Member

Choose a reason for hiding this comment

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

Could you add some more tests? Like 2 simpler tests that are not specifically from #11465, checking that everything still works.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, a few tests are added.

@kiscad kiscad changed the title add extract checking for the guard's local add extra checking for the guard's local Sep 8, 2023
@kiscad kiscad changed the title add extra checking for the guard's local add extra byref checking for the guard's local Sep 8, 2023
@blyxyas
Copy link
Member

blyxyas commented Sep 11, 2023

Instead of just not linting any pattern with a ref, I think we can check if one of the arguments is a reference. e.g.:

Some(ref x) if let &1 = x => {},

Clippy could remove the reference from this &1 and suggest:

Some(1)=> {},

I'm pretty sure this is the case for all arguments where ref followed by a reference argument.

multiple_bindings = true;
return false;
is_byref = matches!(bind_annot.0, rustc_ast::ByRef::Yes);
if span.replace(pat.span).is_some() {
Copy link
Member

Choose a reason for hiding this comment

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

It seems like span is set to None and not modified anytime before this if statement. Could this return true? Seeing the replace documentation, that .is_some would evaluate if before replacing, it had any value. But I don't see it having any other value than None. 🤔 It has been here since the very start.

@Centri3, is there a reason for this if statement?

Copy link
Member

@y21 y21 Sep 13, 2023

Choose a reason for hiding this comment

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

It gets set to Some(_) by the replace call and since it returns the old option, the condition will be true when it reaches the replace call for the 2nd time or any other time after the first replace call (ie when the pattern is found twice, for stuff like let Ok(v) | Err(v) I imagine?).

I got confused by this before when I looked at the code, maybe it could be written clearer

Copy link
Contributor Author

@kiscad kiscad Sep 13, 2023

Choose a reason for hiding this comment

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

How about the code below?

if span.is_some() {
    multiple_bindings = true;
    return false;
} else {
    span.insert(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.

No, but a comment linking to @y21's comment would be really helpful for future reference would help future reviewers / contributors?

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.

This is pretty close to being finished, just a couple questions ❤️

cx: &LateContext<'tcx>,
guard_expr: &Expr<'_>,
outer_arm: &Arm<'tcx>,
) -> Option<(Span, bool, bool)> {
Copy link
Member

Choose a reason for hiding this comment

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

Probably a good idea to write a comment describing what are these 2 bools / what are their function

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just made a custom type PatBindingInfo for the return type.

Comment on lines 180 to 182
B { ref c, .. } if c == &1 => {},
B { ref c, .. } if let &1 = c => {},
B { ref c, .. } if matches!(c, &1) => {},
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't these have the same treatment as the first match c? Is this intended because it's from a struct?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. These cases are handled now.

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 this mini-typo and this should be ready to go, thanks! ❤️

clippy_lints/src/matches/redundant_guards.rs Outdated Show resolved Hide resolved
cx: &LateContext<'tcx>,
guard_expr: &Expr<'_>,
outer_arm: &Arm<'tcx>,
) -> Option<PatBindingInfo> {
Copy link
Member

Choose a reason for hiding this comment

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

Good idea to abstract this return type! 🤠

fix typo

Co-authored-by: Alejandra González <blyxyas@gmail.com>
@blyxyas
Copy link
Member

blyxyas commented Sep 16, 2023

@bors r+

@bors
Copy link
Collaborator

bors commented Sep 16, 2023

📌 Commit 67f0ba4 has been approved by blyxyas

It is now in the queue for this repository.

@bors
Copy link
Collaborator

bors commented Sep 16, 2023

⌛ Testing commit 67f0ba4 with merge ef73648...

@bors
Copy link
Collaborator

bors commented Sep 16, 2023

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

@bors bors merged commit ef73648 into rust-lang:master Sep 16, 2023
5 checks passed
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.

redundant_guards doesn't take ref into account
5 participants