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

Consider nested lifetimes in mut_from_ref #14471

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

arnaudgolfouse
Copy link

fixes #7749.
This issue proposes searching for DerefMut impls, which is not done here: every lifetime parameter (aka <'a>) is the input types is considered to be potentially mutable, and thus deactivates the lint.

changelog: [mut_from_ref]: Fixes false positive, where lifetimes nested in the type (e.g. Box<&'a mut T>) were not considered.

@rustbot
Copy link
Collaborator

rustbot commented Mar 25, 2025

r? @blyxyas

rustbot has assigned @blyxyas.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Mar 25, 2025
@blyxyas
Copy link
Member

blyxyas commented Mar 26, 2025

I find it very fitting that both the issue reported and the issue bugfixer have cat profile pictures.

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 a very good first contribution!! I left some suggestions but it's a great starting point. Thanks for the contribution! ❤️

hir::intravisit::walk_generic_arg(self, generic_arg);
}
}

Copy link
Member

Choose a reason for hiding this comment

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

This function name is not clear enough and it doesn't Have documentation, what about get_ref_lifetime_mutability?

Copy link
Author

Choose a reason for hiding this comment

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

While writing some docs for it I convinced myself that get_lifetimes was a better name, what do you think?

Comment on lines 573 to 515
for (out, mutability, out_span) in get_ref_lm(ty) {
if mutability != Some(Mutability::Mut) {
continue;
}
let out_region = cx.tcx.named_bound_var(out.hir_id);
let args: Option<Vec<_>> = sig
.decl
.inputs
.iter()
.filter_map(get_ref_lm)
.flat_map(get_ref_lm)
.filter(|&(lt, _, _)| cx.tcx.named_bound_var(lt.hir_id) == out_region)
.map(|(_, mutability, span)| (mutability == Mutability::Not).then_some(span))
.map(|(_, mutability, span)| (mutability == Some(Mutability::Not)).then_some(span))
Copy link
Member

Choose a reason for hiding this comment

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

If we only care about Some(Mutability::<Mut, Not>), we can just not add to results when the case is None? Is there anything impeding that?

Copy link
Author

Choose a reason for hiding this comment

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

The difference is between Some(Not) and Some(Mut)/None actually! The first is collected inside the vector, while the other two short-circuit and make collect return None.
I added a comment to clarify this.

.filter(|&(lt, _, _)| cx.tcx.named_bound_var(lt.hir_id) == out_region)
.map(|(_, mutability, span)| (mutability == Mutability::Not).then_some(span))
.map(|(_, mutability, span)| (mutability == Some(Mutability::Not)).then_some(span))
Copy link
Member

Choose a reason for hiding this comment

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

What about this change? filter_map is more concise and gives us a possibility for further optimization (AFAIK)

Suggested change
.map(|(_, mutability, span)| (mutability == Some(Mutability::Not)).then_some(span))
.filter_map(|(lt, mutability, span)| (mutability == Some(Mutability::Not)).then_some(span))

Copy link
Author

Choose a reason for hiding this comment

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

I tried that initially! But it does not have the same semantics: we really want to return a None to short-circuit the iterator.

@arnaudgolfouse arnaudgolfouse force-pushed the mut_from_ref-false-positive branch from 15560d1 to fb8e574 Compare April 4, 2025 15:55
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.

mut_from_ref and Pin<&mut>
3 participants