-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Lint to remove redundant clone()
s
#3355
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
Conversation
cc #17 |
a7433b0
to
d3df19f
Compare
How can I know if |
Ah, working on optimized MIR was much faster -- using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow! This is absolutely great.
One general nit: all these large if_let
s and the bodies of filter_map
would probably be more readable if they were separate functions with a descriptive name.
About these perf percentages that you posted, can you run clippy with and without your lint on some large code bases like cargo
and diesel
and compared those numbers? If it really causes a large slowdown, we can see how to optimize the lint to do less work
if let Some(snip) = snippet_opt(cx, span); | ||
if let Some(dot) = snip.rfind('.'); | ||
then { | ||
let sugg_span = span.with_lo( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm always wary of building our own spans, but I don't see how to do it better right now. Maybe we can change something in rustc that will provide us with better spans?
clippy_lints/src/redundant_clone.rs
Outdated
|
||
impl<'tcx> mir::visit::Visitor<'tcx> for LocalUseVisitor { | ||
fn visit_statement(&mut self, block: mir::BasicBlock, statement: &mir::Statement<'tcx>, location: mir::Location) { | ||
// Once flagged, skip remaining statements |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it might be more performant to iterate manually and run the visitor directly on statements until we don't need it anymore
clippy_lints/src/redundant_clone.rs
Outdated
if ps.len() != 1 { | ||
continue; | ||
} | ||
let pred_terminator = unwrap_or_continue!(&mir[ps[0]].terminator); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, this should never be None
in MIR you get from the compiler. use the terminator
method to get the value directly.
Ooh, I've wanted this lint forever! Thanks for writing this!
You may be interested in the set of escape analysis based lints that help
avoid clones, boxes, and vecs -- we have boxed_local that kind of does this
but ideally we'd have a set of lints that handle similar things. There's a
lot of code that trips up on things like this.
…On Thu, Oct 25, 2018, 4:35 PM Oliver S̶c̶h̶n̶e̶i̶d̶e̶r Scherer < ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In clippy_lints/src/redundant_clone.rs
<#3355 (comment)>
:
>
// _1 in MIR `{ _2 = &_1; _3 = deref(move _2); } -> { _4 = _3; to_path_buf(move _4); }`
let referent = if from_deref {
let ps = mir.predecessors_for(bb);
+ if ps.len() != 1 {
+ continue;
+ }
+ let pred_terminator = unwrap_or_continue!(&mir[ps[0]].terminator);
ah, this should never be None in MIR you get from the compiler. use the
terminator method to get the value directly.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#3355 (review)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABivSMgTHp96niQnba9rOcikjOeBoNyYks5uodpCgaJpZM4X3_fD>
.
|
bed5947
to
6d6ff88
Compare
Result of
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really see where the slowdown is coming from. I presume it's a one-time cost we pay for computing the MIR of all function bodies (which we didn't so far I guess).
Can you confirm this by inserting a return
right after you obtain the MIR and rerun the perf runs?
If that is the reason, then I'm absolutely fine with this slowdown.
clippy_lints/src/redundant_clone.rs
Outdated
}; | ||
|
||
if_chain! { | ||
if !in_macro(span); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this check all the way to the start of the loop and continue if we are in a macro.
Quite noisy, but the slowdown caused by this lint may not be significant.
|
bors r+ Awesome! Thanks so much for creating this lint. Both because it's awesome and because we now have a MIR lint |
bors ping |
Maybe bors is mad at you? bors ping EDIT: it did! |
pong |
it was down, now it is back up again 🎉 bors r=oli-obk |
3355: Lint to remove redundant `clone()`s r=oli-obk a=sinkuu This PR adds lint `redundant_clone`. It suggests to remove redundant `clone()` that clones a owned value that will be dropped without any usage after that. Real-world example: rust-lang/rust@8ec22e7...sinkuu:redundant_clone2 Co-authored-by: Shotaro Yamada <[email protected]>
Timed out |
My bad. An upgrade went wrong, and caused some trouble over the last couple days. ... wait, I thought all the official Rust stuff used bors-voyager. What happened? |
That's just crates.io, the official rust stuff uses homu. I think we set up bors-ng because setting up homu requires some infra edits. |
bors retry |
3355: Lint to remove redundant `clone()`s r=oli-obk a=sinkuu This PR adds lint `redundant_clone`. It suggests to remove redundant `clone()` that clones a owned value that will be dropped without any usage after that. Real-world example: https://github.com/rust-lang/rust/compare/7b0735a..sinkuu:redundant_clone2 Co-authored-by: Shotaro Yamada <[email protected]>
Nothing will pass until #3359 (comment) is resolved:( |
Build failed |
bors retry |
🔒 Permission denied Existing reviewers: click here to make matthiaskrgr a reviewer |
bors retry |
bors ping |
pong |
1 similar comment
pong |
It seems that if bors r=oli-obk |
3355: Lint to remove redundant `clone()`s r=oli-obk a=sinkuu This PR adds lint `redundant_clone`. It suggests to remove redundant `clone()` that clones a owned value that will be dropped without any usage after that. Real-world example: https://github.com/rust-lang/rust/compare/7b0735a..sinkuu:redundant_clone2 Co-authored-by: Shotaro Yamada <[email protected]>
This PR adds lint
redundant_clone
. It suggests to remove redundantclone()
that clones a owned value that will be dropped without any usage after that.Real-world example: https://github.com/rust-lang/rust/compare/7b0735a..sinkuu:redundant_clone2