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::takeis 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.