Skip to content
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

Enhance needless_borrow to consider trait implementations #9136

Merged
merged 2 commits into from
Aug 18, 2022

Conversation

smoelius
Copy link
Contributor

@smoelius smoelius commented Jul 8, 2022

The proposed enhancement causes needless_borrow to suggest removing & from &e when &e is an argument position requiring trait implementations, and e implements the required traits. Example:

error: the borrowed expression implements the required traits
  --> $DIR/needless_borrow.rs:131:51
   |
LL |     let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
   |                                                   ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]`

r? @Jarcho

changelog: Enhance needless_borrow to consider trait implementations

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Jul 8, 2022
@Jarcho
Copy link
Contributor

Jarcho commented Jul 9, 2022

Probably won't have time to look at this for a few days. Does this handle something like:

struct S<T>(Vec<T>);
impl<T> S<T> {
    fn push(&mut self, item: T) where T: Eq { .. }
}

@smoelius
Copy link
Contributor Author

smoelius commented Jul 9, 2022

No problem at all.

Something like S.push(&0) would be ignored. There is a condition that the changed argument's type parameter not appear elsewhere in the function signature. In this case, T appears in the type of the &mut self argument.

@smoelius
Copy link
Contributor Author

smoelius commented Jul 9, 2022

However, you caused me to realize I was incorrectly assuming the argument type was a type parameter.

I have corrected the error and added a relevant test.

Copy link
Contributor

@Jarcho Jarcho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably ignore cases where the trait has a &mut self method, but the unreferenced type is not a mutable reference. e.g.

#[derive(Clone, Copy)]
struct Iter(..);
impl Iterator for Iter { .. }

fn takes_iter(_: impl Iterator) {}
fn dont_warn(mut x: Iter) -> {
    takes_iter(&mut x);
}
fn warn(mut x: &mut Iter) -> {
    takes_iter(&mut x)
}

Iterators shouldn't implement Copy for exactly this reason, but that doesn't stop it from happening.

clippy_lints/src/dereference.rs Outdated Show resolved Hide resolved
clippy_lints/src/dereference.rs Outdated Show resolved Hide resolved
clippy_lints/src/dereference.rs Outdated Show resolved Hide resolved
clippy_lints/src/dereference.rs Outdated Show resolved Hide resolved
clippy_lints/src/dereference.rs Outdated Show resolved Hide resolved
clippy_lints/src/dereference.rs Outdated Show resolved Hide resolved
clippy_lints/src/dereference.rs Outdated Show resolved Hide resolved
clippy_lints/src/dereference.rs Outdated Show resolved Hide resolved
clippy_lints/src/dereference.rs Show resolved Hide resolved
clippy_lints/src/dereference.rs Outdated Show resolved Hide resolved
@bors
Copy link
Contributor

bors commented Jul 13, 2022

☔ The latest upstream changes (presumably #9169) made this pull request unmergeable. Please resolve the merge conflicts.

@ghost
Copy link

ghost commented Jul 14, 2022

I got a crash with this branch on the crossbeam-epoch-0.9.9 crate.

thread 'rustc' panicked at 'assertion failed: !value.has_escaping_bound_vars()'
Backtrace
thread 'rustc' panicked at 'assertion failed: !value.has_escaping_bound_vars()', /rustc/ddcbba036aee08f0709f98a92a342a278eae5c05/compiler/rustc_middle/src/ty/sty.rs:996:9
stack backtrace:
   0: rust_begin_unwind
             at /rustc/ddcbba036aee08f0709f98a92a342a278eae5c05/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/ddcbba036aee08f0709f98a92a342a278eae5c05/library/core/src/panicking.rs:142:14
   2: core::panicking::panic
             at /rustc/ddcbba036aee08f0709f98a92a342a278eae5c05/library/core/src/panicking.rs:48:5
   3: <rustc_middle::ty::sty::Binder<rustc_middle::ty::sty::TraitRef>>::dummy
   4: <rustc_infer::infer::InferCtxt as rustc_trait_selection::infer::InferCtxtExt>::type_implements_trait
   5: rustc_infer::infer::InferCtxtBuilder::enter
   6: clippy_utils::ty::implements_trait_with_env
   7: clippy_utils::ty::implements_trait
   8: clippy_lints::dereference::needless_borrow_impl_arg_position
   9: <clippy_lints::dereference::Dereferencing as rustc_lint::passes::LateLintPass>::check_expr
  10: <rustc_lint::late::LateLintPassObjects as rustc_lint::passes::LateLintPass>::check_expr
  11: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_expr
  12: rustc_hir::intravisit::walk_expr::<rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects>>
  13: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_expr
  14: rustc_hir::intravisit::walk_expr::<rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects>>
  15: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_expr
  16: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_block
  17: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_expr
  18: rustc_hir::intravisit::walk_expr::<rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects>>
  19: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_expr
  20: rustc_hir::intravisit::walk_block::<rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects>>
  21: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_block
  22: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_expr
  23: rustc_hir::intravisit::walk_expr::<rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects>>
  24: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_expr
  25: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_expr
  26: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_block
  27: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_expr
  28: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_nested_body
  29: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_fn
  30: rustc_hir::intravisit::walk_impl_item::<rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects>>
  31: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_nested_impl_item
  32: rustc_hir::intravisit::walk_impl_item_ref::<rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects>>
  33: rustc_hir::intravisit::walk_item::<rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects>>
  34: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_nested_item
  35: rustc_hir::intravisit::walk_mod::<rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects>>
  36: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_mod
  37: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_nested_item
  38: rustc_hir::intravisit::walk_mod::<rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects>>
  39: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_mod
  40: rustc_lint::late::late_lint_pass_crate::<rustc_lint::late::LateLintPassObjects>
  41: rustc_lint::late::late_lint_crate::<rustc_lint::BuiltinCombinedLateLintPass>
  42: rustc_data_structures::sync::join::<rustc_lint::late::check_crate<rustc_lint::BuiltinCombinedLateLintPass, rustc_interface::passes::analysis::{closure#5}::{closure#1}::{closure#2}::{closure#0}::{closure#0}>::{closure#0}, rustc_lint::late::check_crate<rustc_lint::BuiltinCombinedLateLintPass, rustc_interface::passes::analysis::{closure#5}::{closure#1}::{closure#2}::{closure#0}::{closure#0}>::{closure#1}, (), ()>
  43: <rustc_session::session::Session>::time::<(), rustc_interface::passes::analysis::{closure#5}::{closure#1}::{closure#2}::{closure#0}>
  44: <core::panic::unwind_safe::AssertUnwindSafe<rustc_interface::passes::analysis::{closure#5}::{closure#1}> as core::ops::function::FnOnce<()>>::call_once
  45: <rustc_session::session::Session>::time::<(), rustc_interface::passes::analysis::{closure#5}>
  46: rustc_interface::passes::analysis
  47: <rustc_query_system::dep_graph::graph::DepGraph<rustc_middle::dep_graph::dep_node::DepKind>>::with_task::<rustc_middle::ty::context::TyCtxt, (), core::result::Result<(), rustc_errors::ErrorGuaranteed>>
  48: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::plumbing::QueryCtxt, rustc_query_system::query::caches::DefaultCache<(), core::result::Result<(), rustc_errors::ErrorGuaranteed>>>
  49: rustc_query_system::query::plumbing::get_query::<rustc_query_impl::queries::analysis, rustc_query_impl::plumbing::QueryCtxt>
  50: <rustc_interface::passes::QueryContext>::enter::<rustc_driver::run_compiler::{closure#1}::{closure#2}::{closure#3}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>
  51: <rustc_interface::interface::Compiler>::enter::<rustc_driver::run_compiler::{closure#1}::{closure#2}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_errors::ErrorGuaranteed>>
  52: rustc_span::with_source_map::<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_interface::interface::create_compiler_and_run<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_driver::run_compiler::{closure#1}>::{closure#1}>
  53: <scoped_tls::ScopedKey<rustc_span::SessionGlobals>>::set::<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_driver::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new

note: Clippy version: clippy 0.1.64 (2507d2ad8 2022-07-09)

@smoelius
Copy link
Contributor Author

Thanks, @mikerite!

@smoelius
Copy link
Contributor Author

I think the most recent push addresses all of the review comments up to this point, and the crash. Please let me know if I misunderstood anything.

Regarding the "is copyable" condition, I imposed a hard limit of 256 bytes. Please let me know if you would prefer a different approach.

@Jarcho
Copy link
Contributor

Jarcho commented Jul 18, 2022

A couple of comments now that I've had time to think through the implementation.

  • You can ignore my earlier comment about the size of parameters. The calling convention for large types is that they're passed by reference anyways. Sorry for wasting time on that one.

  • Currently this only handles T: SomeTrait predicates, but T: SomeTrait<U> and U: SomeTrait<T> predicates also need to be handled. This requires a few steps:

    1. Get the current substitution list for the function call.
    2. Replace the substitution for T with the new type.
    3. Apply the new substitution list to each predicate.
    4. Check each new substituted predicate with predicate_must_hold_modulo_regions. The InferCtxt can be created with cx.tcx.infer_ctxt().enter(|infcx| ...)

    You'll still want to keep the rest of the restrictions in place in order to avoid false positives.

@smoelius
Copy link
Contributor Author

  • Currently this only handles T: SomeTrait predicates, but T: SomeTrait<U> and U: SomeTrait<T> predicates also need to be handled. This requires a few steps:

    1. Get the current substitution list for the function call.
    2. Replace the substitution for T with the new type.
    3. Apply the new substitution list to each predicate.
    4. Check each new substituted predicate with predicate_must_hold_modulo_regions. The InferCtxt can be created with cx.tcx.infer_ctxt().enter(|infcx| ...)

You're saying this should be done for all predicates, not just trait predicates, correct?

If so, are there any tools you know of to make iii easier? I.e., something easier than performing a match and handling each PredicateKind individually?

@Jarcho
Copy link
Contributor

Jarcho commented Jul 19, 2022

The subst method will perform the actual substitution. It exists on both List<Predicate>> and Predicate itself.

@bors
Copy link
Contributor

bors commented Jul 19, 2022

☔ The latest upstream changes (presumably #9210) made this pull request unmergeable. Please resolve the merge conflicts.

@smoelius smoelius force-pushed the enhance-needless-borrow branch 3 times, most recently from 43ea74d to cd70a3d Compare July 20, 2022 10:19
@smoelius
Copy link
Contributor Author

I think the second round of comments are addressed.

@smoelius
Copy link
Contributor Author

Please let me know if I misunderstood any of your suggestions, @Jarcho.

@smoelius
Copy link
Contributor Author

@Jarcho How's this?

clippy_lints/src/dereference.rs Outdated Show resolved Hide resolved
let new_generic_arg = ty::GenericArg::from(new_ty);

// If `replaced.is_empty()`, then `param_ty` and `new_ty` are those initially passed in.
if !(substs[param_ty.index as usize] == new_generic_arg
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check could be done right before pushing the types to the queue thereby removing the need to check for the initial argument.

clippy_lints/src/dereference.rs Outdated Show resolved Hide resolved
@smoelius
Copy link
Contributor Author

smoelius commented Aug 3, 2022

Please consider this paused. I have to fix this.

@smoelius
Copy link
Contributor Author

smoelius commented Aug 3, 2022

OK. I think this is fixed now. The new test ICEs without try_normalize_erasing_regions.

@Jarcho
Copy link
Contributor

Jarcho commented Aug 4, 2022

That should be the last thing. I want to run one more check on more crates, but that will take a couple of days as I have other tests running right now.

@Jarcho
Copy link
Contributor

Jarcho commented Aug 5, 2022

Looks like it mostly catches AsRef and IntoIterator with Serialize being a very distant third. Didn't see any FP's in the top 5000 crates.

You can squash down some of the commits and then it's good to go.

@smoelius
Copy link
Contributor Author

smoelius commented Aug 6, 2022

Done.

I left in the change that moved get_input_traits_and_projections to clippy_utils, even though this change was ultimately not needed. Please let me know if you would like me to undo this change.

@Jarcho
Copy link
Contributor

Jarcho commented Aug 8, 2022

It would be better to remove it. This would get removed as an unused util function if we ever clean up useless/overlapping util functions.

I'm going to put a hold on merging this as it conflicts #9126 and the lint fixed there is about to beta. I can't guarantee I'll have time to deal with the merge conflict in the next week.

@smoelius smoelius force-pushed the enhance-needless-borrow branch 3 times, most recently from 903274b to ad778ad Compare August 8, 2022 13:49
@smoelius
Copy link
Contributor Author

smoelius commented Aug 8, 2022

It would be better to remove it. This would get removed as an unused util function if we ever clean up useless/overlapping util functions.

I moved get_input_traits_and_projections back into unnecessary_to_owned.rs, but kept a few changes that came out of this review.

I'm going to put a hold on merging this as it conflicts #9126 and the lint fixed there is about to beta. I can't guarantee I'll have time to deal with the merge conflict in the next week.

No problem at all.

@bors
Copy link
Contributor

bors commented Aug 8, 2022

☔ The latest upstream changes (presumably #9126) made this pull request unmergeable. Please resolve the merge conflicts.

@Jarcho
Copy link
Contributor

Jarcho commented Aug 16, 2022

Ping @smoelius just in case github didn't. This is good to merge once the conflicts are resolved. Sorry for dumping that on you.

@smoelius
Copy link
Contributor Author

Sorry, I misunderstood your previous message.

If it helps to verify the rebase, here is the diff between the old patch (ad778ad) and the new (032f112):

15c15
< index d513a229b..47bdc41a2 100644
---
> index 3b27f061e..357cf6fc4 100644
25c25
<              return Err(CliError::RaSetupActive);
---
>              return Err(CliError::IntellijSetupActive);
50c50
< index c089f4d8c..c831fb831 100644
---
> index 05e79a241..c503142e5 100644
72c72
< index a90f894a7..7d2b526bc 100644
---
> index e0b94f719..e38704701 100644
79c79
< -use clippy_utils::ty::{expr_sig, peel_mid_ty_refs, variant_of_res};
---
> -use clippy_utils::ty::{expr_sig, peel_mid_ty_refs, ty_sig, variant_of_res};
81c81
< +use clippy_utils::ty::{contains_ty, expr_sig, is_copy, peel_mid_ty_refs, variant_of_res};
---
> +use clippy_utils::ty::{contains_ty, expr_sig, is_copy, peel_mid_ty_refs, ty_sig, variant_of_res};
99c99
< -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable, TypeckResults};
---
> -use rustc_middle::ty::{self, Binder, BoundVariableKind, List, Ty, TyCtxt, TypeVisitable, TypeckResults};
101,102c101,102
< +    self, subst::Subst, EarlyBinder, FnSig, GenericArgKind, ParamTy, PredicateKind, ProjectionPredicate, Ty, TyCtxt,
< +    TypeVisitable, TypeckResults,
---
> +    self, subst::Subst, Binder, BoundVariableKind, EarlyBinder, FnSig, GenericArgKind, List, ParamTy, PredicateKind,
> +    ProjectionPredicate, Ty, TyCtxt, TypeVisitable, TypeckResults,
106c106
<  use rustc_span::{symbol::sym, Span, Symbol};
---
>  use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP};
196c196
< @@ -521,7 +547,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
---
> @@ -510,7 +536,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
205c205
< @@ -553,6 +579,8 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
---
> @@ -542,6 +568,8 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
214c214
< @@ -605,6 +633,7 @@ enum Position {
---
> @@ -594,6 +622,7 @@ enum Position {
222c222
< @@ -638,7 +667,7 @@ impl Position {
---
> @@ -630,7 +659,7 @@ impl Position {
228c228
<              Self::DerefStable(p) | Self::ReborrowStable(p) | Self::Other(p) => p,
---
>              Self::DerefStable(p, _) | Self::ReborrowStable(p) | Self::Other(p) => p,
231c231
< @@ -647,8 +676,12 @@ impl Position {
---
> @@ -639,8 +668,12 @@ impl Position {
246c246
< @@ -751,12 +784,19 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
---
> @@ -732,13 +765,20 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
254,255c254,256
< -                        Some(ty) => binding_ty_auto_deref_stability(ty, precedence),
< -                        None => param_auto_deref_stability(ty.skip_binder(), precedence),
---
> -                        Some(hir_ty) => binding_ty_auto_deref_stability(cx, hir_ty, precedence, ty.bound_vars()),
> -                        None => ty_auto_deref_stability(cx, cx.tcx.erase_late_bound_regions(ty), precedence)
> -                            .position_for_arg(),
260c261
< +                            Some(ty) => binding_ty_auto_deref_stability(ty, precedence),
---
> +                            Some(hir_ty) => binding_ty_auto_deref_stability(cx, hir_ty, precedence, ty.bound_vars()),
265c266,267
< +                                    param_auto_deref_stability(ty.skip_binder(), precedence)
---
> +                                    ty_auto_deref_stability(cx, cx.tcx.erase_late_bound_regions(ty), precedence)
> +                                        .position_for_arg()
272c274
< @@ -797,7 +837,12 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
---
> @@ -779,12 +819,17 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
276c278,283
< -                            param_auto_deref_stability(cx.tcx.fn_sig(id).skip_binder().inputs()[i], precedence)
---
> -                            ty_auto_deref_stability(
> -                                cx,
> -                                cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(id).input(i)),
> -                                precedence,
> -                            )
> -                            .position_for_arg()
281c288,293
< +                                param_auto_deref_stability(ty, precedence)
---
> +                                ty_auto_deref_stability(
> +                                    cx,
> +                                    cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(id).input(i)),
> +                                    precedence,
> +                                )
> +                                .position_for_arg()
286c298
< @@ -920,6 +965,205 @@ fn ty_contains_infer(ty: &hir::Ty<'_>) -> bool {
---
> @@ -946,6 +991,205 @@ fn ty_contains_infer(ty: &hir::Ty<'_>) -> bool {
489,492c501,504
<  // Checks whether a type is stable when switching to auto dereferencing,
<  fn param_auto_deref_stability(ty: Ty<'_>, precedence: i8) -> Position {
<      let ty::Ref(_, mut ty, _) = *ty.kind() else {
< @@ -1026,7 +1270,8 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data
---
>  struct TyPosition<'tcx> {
>      position: Position,
>      ty: Option<Ty<'tcx>>,
> @@ -1084,7 +1328,8 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data
503c515
< index 8444532f6..ef8c33a03 100644
---
> index e6a405f81..521739c28 100644
506c518
< @@ -807,7 +807,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
---
> @@ -821,7 +821,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
516c528
< index b4c6bfb31..ad55ee63c 100644
---
> index 99b56da7a..e4624167a 100644
519,521c531,533
< @@ -5,9 +5,8 @@ use clippy_utils::source::snippet_opt;
<  use clippy_utils::ty::{
<      contains_ty, get_associated_type, get_iterator_item_ty, implements_trait, is_copy, peel_mid_ty_refs,
---
> @@ -6,9 +6,8 @@ use clippy_utils::ty::{
>      contains_ty, get_associated_type, get_iterator_item_ty, implements_trait, is_copy, is_type_diagnostic_item,
>      peel_mid_ty_refs,
530c542
< @@ -360,25 +359,15 @@ fn get_input_traits_and_projections<'tcx>(
---
> @@ -373,25 +372,15 @@ fn get_input_traits_and_projections<'tcx>(

@Jarcho
Copy link
Contributor

Jarcho commented Aug 18, 2022

Thank you for pushing through and implementing all this.

@bors r+

@bors
Copy link
Contributor

bors commented Aug 18, 2022

📌 Commit 032f112 has been approved by Jarcho

It is now in the queue for this repository.

@bors
Copy link
Contributor

bors commented Aug 18, 2022

⌛ Testing commit 032f112 with merge c419d0a...

@smoelius
Copy link
Contributor Author

Thanks for the detailed and thorough review!

@bors
Copy link
Contributor

bors commented Aug 18, 2022

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: Jarcho
Pushing c419d0a to master...

@bors bors merged commit c419d0a into rust-lang:master Aug 18, 2022
@smoelius smoelius deleted the enhance-needless-borrow branch August 18, 2022 16:36
bors added a commit that referenced this pull request Oct 8, 2022
Further enhance `needless_borrow`, mildly refactor `redundant_clone`

This PR does the following:
* Moves some code from `redundant_clone` into a new `clippy_utils` module called `mir`, and wraps that code in a function called `dropped_without_further_use`.
* Relaxes the "is copyable" condition condition from #9136 by also suggesting to remove borrows from values dropped without further use. The changes involve the just mentioned function.
* Separates `redundant_clone` into modules.

Strictly speaking, the last bullet is independent of the others. `redundant_clone` is somewhat hairy, IMO. Separating it into modules makes it slightly less so, by helping to delineate what depends upon what.

I've tried to break everything up into digestible commits.

r? `@Jarcho`

(`@Jarcho` I hope you don't mind.)

changelog: continuation of #9136
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants