Open
Description
Description
This affects any lint where we recommend moving code into a closure. Off the top of my head are manual_map
, option_if_let_else
, and map_entry
, but there are probably more.
Given the following code:
let mut x = 0;
let ref_x = &mut x;
let _ = match Some(0) {
Some(y) => Some({
*ref_x = y;
some_fn_call(&mut x) + y
}),
None => None,
};
Clippy will suggest to use Option::map
let _ = Some(0).map(|y| {
*ref_x = y;
some_fn_call(&mut x) + y
});
This will fail with multiple mutable borrows of x
due to the closure capturing both ref_x
and x
. The original code would have the borrow held by ref_x
end right before x
is borrowed for some_fn_call
.
Solving this would require the lifetimes computed by borrowck which I don't believe we have easy access to. It may also require turning these as MIR lints.
Version
No response
Additional Labels
@rustbot label +I-false-positive
@rustbot label +E-hard
@rustbot label +T-MIR
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
option_if_let_else
on conflicting mut borrow #8344tamaroning commentedon May 24, 2022
@rustbot claim
tamaroning commentedon May 28, 2022
I am thinking of reusing
PosibbleBorrowerVisitor
used in redundant_closure, which means no need to deal with specific cases (like #7531 )Jarcho commentedon May 30, 2022
I assume you mean
redundant_clone
. You'll need to adaptPossibleBorrowerVisitor
to track only mutable borrows (easy) and either convert all the lints to MIR lints, or find some way to link HIR nodes with MIR (the less easy part).This will also introduce false negatives as well.
PossibleBorrowerVisitor
is not particularly precise at tracking lifetimes.tamaroning commentedon May 30, 2022
ohh yes. I mean redundant_clone.
I think just comparing spans of nodes with spans of mir statements might be enough. (further invastigation is needed)
I see. I am going to dig into borrow checker and try to use intermidiate state of it.
Jarcho commentedon Jun 1, 2022
It might be doable. I can't think of a reason why it couldn't work, but it has to be done as least somewhat separately for each lint.
You might need changes on the rustc side to make that work. It might be worth waiting until polonius is ready, but that could be years.
manual_map
does not consider the borrowing relationship #9407TimonPost commentedon May 12, 2023
I also get a false positive suggestion where clippy suggests faulty code with a borrow issue: