Convert redundant_clone
to an analysis pass take 2
#14599
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
supersedes #11364
fixes #10940
fixes #10893
fixes #10870
fixes #10577
fixes #10545
fixes #10517
Don't worry about reviewing this as a whole, I'll be splitting it up into smaller chunks to be reviewed separately.
This comes with a separate dataflow framework than rustc's since many changes would be needed to track values correctly. As an example a mutable borrow of a pair of strings
&mut (String, String)
would need to cause both strings to hold different values and the only way to do that in rustc's framework is to track sub-statement positions. The new framework lets us easily do a preprocessing pass at the expense of not trivially supporting cursors.Arena allocation is used heavily throughout. This simplifies some lifetimes both by using only a single lifetime parameter and not having to store as many owning values. It also avoids having a large number of small allocations that need to also be dropped.
No suggestions are give with the lint. This is unfortunate but they are non-trivial to add since removing the clone call is only correct in a subset of cases. Future uses of a projection may need to be changed; the clone call might be changed to a move of a different name (
x.clone()
->y
) or changed to a borrow.mem::take
is needed in some cases as well.The diagnostic output is currently a stand-in. I will be adding notes about where the values diverge and where the lifetimes of the pair of values end. Basically a message saying one value is modified, but the other isn't used after that point before it's dropped.
changelog:
redundant_clone
: Fix false positives where the clone result is stored in a local.changelog:
redundant_clone
: Track the use of the clone throughout the function body rather than only checking for immediate consumption.changelog:
redundant_clone
: Extended to analyze code in loopschangelog:
redundant_clone
: Track values inside fields rather than just tracking top level locals.