Add fn_param_ref_cloned lint - #17281
Conversation
|
Thanks for the pull request, and welcome! The Rust Project is excited to review your changes, and you should hear from @llogiq (or someone else) some time within the next two weeks. 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 (
Why was this reviewer chosen?The reviewer was selected based on:
|
3e17354 to
fb1530b
Compare
|
Lintcheck changes for 32e80ba
This comment will be updated if you push new changes |
fb1530b to
cf78d0d
Compare
This comment has been minimized.
This comment has been minimized.
cf78d0d to
aa82ebb
Compare
I think that for now I do ignore all expansions from macros (though that probably only involves locally expanded span from macros). However, I would be happy to add some testcases for external macros - tho maybe I would need some direction (example) somewhere to see how it's supposed to be done |
This comment has been minimized.
This comment has been minimized.
d9b58f5 to
6ceb8de
Compare
This comment has been minimized.
This comment has been minimized.
|
After a longer time off, I will try to fixup this PR and see if tests pass properly, then hopefully can finish off remaining suggestions |
6ceb8de to
01e0753
Compare
This comment has been minimized.
This comment has been minimized.
3838565 to
ca049d0
Compare
|
I want to rebase all the commits again later just so there are not 13 of them, but I wanted to ask for a re-review now that some time has passed. Would it be OK if we kept the lint smaller-scoped for now, and I could focus on extending it later? Do you think the scope is sufficient for it to be useful? Thanks a bunch! cc @blyxyas just for the info, I would love as many opinions as I can get :> |
This comment has been minimized.
This comment has been minimized.
Signed-off-by: David Manca <1900179+medzernik@users.noreply.github.com>
Co-Authored by: Matej Almasi <matej.almasi@protonmail.com> Signed-off-by: David Manca <1900179+medzernik@users.noreply.github.com> # Conflicts: # clippy_lints/src/lib.rs
Signed-off-by: David Manca <1900179+medzernik@users.noreply.github.com>
Signed-off-by: David Manca <1900179+medzernik@users.noreply.github.com>
Signed-off-by: David Manca <1900179+medzernik@users.noreply.github.com> # Conflicts: # clippy_lints/src/lib.rs
Signed-off-by: medzernik <medzernik@medzernik.dev>
Signed-off-by: medzernik <medzernik@medzernik.dev>
Signed-off-by: medzernik <medzernik@medzernik.dev>
Signed-off-by: David Manca <1900179+medzernik@users.noreply.github.com>
e7b8e4a to
8be86f9
Compare
|
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
Signed-off-by: David Manca <1900179+medzernik@users.noreply.github.com>
Signed-off-by: David Manca <1900179+medzernik@users.noreply.github.com>
Signed-off-by: David Manca <1900179+medzernik@users.noreply.github.com>
8be86f9 to
32e80ba
Compare
| type CandidateId = rustc_hir::HirId; | ||
| type CandidateSpan = Span; | ||
| type Candidate = (CandidateId, CandidateSpan); | ||
| type CandidateRebinds = Vec<Candidate>; | ||
|
|
||
| #[derive(Default)] | ||
| pub struct FnParamRefCloned { | ||
| candidates: Vec<(Candidate, CandidateRebinds)>, | ||
| } |
There was a problem hiding this comment.
I think that this is adding a lot of cognitive load without much benefit (I get that it's more "readable", but it takes much more time to parse for the first time, and we only use this types here)
|
|
||
| #[derive(Default)] | ||
| pub struct FnParamRefCloned { | ||
| candidates: Vec<(Candidate, CandidateRebinds)>, |
There was a problem hiding this comment.
What is the median length of this array(s)? Could we use smallvec instead?
| let must_impl_trait = [ | ||
| cx.tcx.lang_items().clone_trait().unwrap(), | ||
| cx.tcx.lang_items().drop_trait().unwrap(), | ||
| ]; |
| ControlFlow::<(), Descend>::Continue(Descend::No) | ||
| }, | ||
| rustc_hir::ExprKind::MethodCall(method_name, receiver, args, span) | ||
| if method_name.ident.as_str() == "clone" |
| .collect(); | ||
|
|
||
| // Find all rebinds of param values in the function and add them to the original candidates (tuple) | ||
| if let rustc_hir::ExprKind::Block(block, _) = fn_body.value.kind { |
There was a problem hiding this comment.
Refactor this from an if let into a Block(block, _) = fn_body.value.kind else { return; }
| clippy_utils::diagnostics::span_lint_and_note( | ||
| cx, | ||
| FN_PARAM_REF_CLONED, | ||
| span, | ||
| "function gets a parameter by reference, but you later unconditionally clone it", | ||
| Some(original_candidate.1), | ||
| "consider passing the reference by value instead", | ||
| ); | ||
| } |
There was a problem hiding this comment.
Please refactor these two calls into another function, called something like emit_lint
|
Reminder, once the PR becomes ready for a review, use |
|
☔ The latest upstream changes (possibly #17538) made this pull request unmergeable. Please resolve the merge conflicts. |
Co-authored-by: Alejandra González <blyxyas@goose.love>
Co-authored-by: Alejandra González <blyxyas@goose.love>
Co-authored-by: Alejandra González <blyxyas@goose.love>
Co-authored-by: Alejandra González <blyxyas@goose.love>
View all comments
Co-Authored by: @matej-almasi almasi.mato@gmail.com
changelog: [
fn_param_ref_cloned]: added a lint. Fixes #2074This is a partial WIP PR - We need some feedback (this is also our first contribution).
Added a lint to check whether you are not cloning a reference when passed into a function. Per best practices the caller should decide whether to clone data, and not hide the operation within a function.