perf: skip redundant clone analysis for clone-free functions - #17486
Open
charliermarsh wants to merge 2 commits into
Open
perf: skip redundant clone analysis for clone-free functions#17486charliermarsh wants to merge 2 commits into
charliermarsh wants to merge 2 commits into
Conversation
Scan function bodies for clone-like method calls before requesting optimized MIR. Skip nested closures because they receive their own lint callbacks, and preserve qualified-call, alias, macro, and closure coverage. On Rust 1.95, the synthetic 4,096-function workload improved from 220 ms to 178 ms. Codex incremental core checks improved from 4.19 s to 3.98 s at the median.
Collaborator
|
Thanks for the pull request, and welcome! You should hear from one of our reviewers after this PR gets at least 2 reviews from the community. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
CommanderStorm
approved these changes
Aug 2, 2026
Comment on lines
+255
to
+268
| fn contains_clone_like_call(body: &Body<'_>) -> bool { | ||
| for_each_expr_without_closures(body, |expr| { | ||
| if let ExprKind::MethodCall(method, ..) = expr.kind | ||
| && matches!( | ||
| method.ident.name, | ||
| sym::clone | sym::to_owned | sym::to_string | sym::to_path_buf | sym::to_os_string | ||
| ) | ||
| { | ||
| ControlFlow::Break(()) | ||
| } else { | ||
| ControlFlow::Continue(()) | ||
| } | ||
| }) | ||
| .is_some() |
Contributor
There was a problem hiding this comment.
see above
Suggested change
| fn contains_clone_like_call(body: &Body<'_>) -> bool { | |
| for_each_expr_without_closures(body, |expr| { | |
| if let ExprKind::MethodCall(method, ..) = expr.kind | |
| && matches!( | |
| method.ident.name, | |
| sym::clone | sym::to_owned | sym::to_string | sym::to_path_buf | sym::to_os_string | |
| ) | |
| { | |
| ControlFlow::Break(()) | |
| } else { | |
| ControlFlow::Continue(()) | |
| } | |
| }) | |
| .is_some() | |
| fn contains_no_clone_like_call(body: &Body<'_>) -> bool { | |
| for_each_expr_without_closures(body, |expr| { | |
| if let ExprKind::MethodCall(method, ..) = expr.kind | |
| && matches!( | |
| method.ident.name, | |
| sym::clone | sym::to_owned | sym::to_string | sym::to_path_buf | sym::to_os_string | |
| ) | |
| { | |
| ControlFlow::Break(()) | |
| } else { | |
| ControlFlow::Continue(()) | |
| } | |
| }) | |
| .is_none() |
Comment on lines
+78
to
+80
| // Closures receive their own `check_fn` callback and are checked separately. | ||
| // Building MIR for `fn`s with unsatisfiable clauses results in ICE. | ||
| if fn_has_unsatisfiable_clauses(cx, def_id.to_def_id()) { | ||
| if !contains_clone_like_call(body) || fn_has_unsatisfiable_clauses(cx, def_id.to_def_id()) { |
Contributor
There was a problem hiding this comment.
🤔 would this be cleaner?
(lol on the diff github produces)
Suggested change
| // Closures receive their own `check_fn` callback and are checked separately. | |
| // Building MIR for `fn`s with unsatisfiable clauses results in ICE. | |
| if fn_has_unsatisfiable_clauses(cx, def_id.to_def_id()) { | |
| if !contains_clone_like_call(body) || fn_has_unsatisfiable_clauses(cx, def_id.to_def_id()) { | |
| // Closures receive their own `check_fn` callback and are checked separately. | |
| // Building MIR for `fn`s with unsatisfiable clauses results in ICE and is expensive. | |
| if contains_no_clone_like_call(body) || fn_has_unsatisfiable_clauses(cx, def_id.to_def_id()) { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
On master,
redundant_clonerequests optimized MIR for every function. It turns out this is fairly expensive. This PR adds a pre-filter that scans each function’s HIR first and skips MIR analysis unless the body contains a.clone(),.to_owned(),.to_string(),.to_path_buf(), or.to_os_string()call. (It's just a pre-filter so false positives are acceptable.)Benchmarking on my M4, incremental Clippy checks in
codex-rswent from 4.19 s to 3.98 s (~5% improvement). A more contrived workload (4,096 functions) went from 220 ms to 178 ms (~19% improvement).changelog: none