]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #9386 - smoelius:further-enhance-needless-borrow, r=Jarcho
authorbors <bors@rust-lang.org>
Sat, 8 Oct 2022 21:24:54 +0000 (21:24 +0000)
committerbors <bors@rust-lang.org>
Sat, 8 Oct 2022 21:24:54 +0000 (21:24 +0000)
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

1  2 
clippy_utils/src/lib.rs

diff --combined clippy_utils/src/lib.rs
index e6492d76260e2d69fd726321aa10c70edc01a335,5c8ffffc8c8a6b9524f2d105349688b1f73c6046..dbe75b43cb2405cc259ac6f03d1d6ff3a7a90f2c
@@@ -25,10 -25,12 +25,12 @@@ extern crate rustc_data_structures
  extern crate rustc_errors;
  extern crate rustc_hir;
  extern crate rustc_hir_analysis;
+ extern crate rustc_index;
  extern crate rustc_infer;
  extern crate rustc_lexer;
  extern crate rustc_lint;
  extern crate rustc_middle;
+ extern crate rustc_mir_dataflow;
  extern crate rustc_parse_format;
  extern crate rustc_session;
  extern crate rustc_span;
@@@ -48,6 -50,7 +50,7 @@@ pub mod eager_or_lazy
  pub mod higher;
  mod hir_utils;
  pub mod macros;
+ pub mod mir;
  pub mod msrvs;
  pub mod numeric_literal;
  pub mod paths;
@@@ -122,7 -125,7 +125,7 @@@ pub fn parse_msrv(msrv: &str, sess: Opt
          return Some(version);
      } else if let Some(sess) = sess {
          if let Some(span) = span {
-             sess.span_err(span, &format!("`{msrv}` is not a valid Rust version"));
+             sess.span_err(span, format!("`{msrv}` is not a valid Rust version"));
          }
      }
      None
@@@ -815,37 -818,13 +818,37 @@@ pub fn is_default_equivalent(cx: &LateC
                  false
              }
          },
 -        ExprKind::Call(repl_func, _) => is_default_equivalent_call(cx, repl_func),
 +        ExprKind::Call(repl_func, []) => is_default_equivalent_call(cx, repl_func),
 +        ExprKind::Call(from_func, [ref arg]) => is_default_equivalent_from(cx, from_func, arg),
          ExprKind::Path(qpath) => is_res_lang_ctor(cx, cx.qpath_res(qpath, e.hir_id), OptionNone),
          ExprKind::AddrOf(rustc_hir::BorrowKind::Ref, _, expr) => matches!(expr.kind, ExprKind::Array([])),
          _ => false,
      }
  }
  
 +fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: &Expr<'_>) -> bool {
 +    if let ExprKind::Path(QPath::TypeRelative(ty, seg)) = from_func.kind &&
 +        seg.ident.name == sym::from
 +    {
 +        match arg.kind {
 +            ExprKind::Lit(hir::Lit {
 +                node: LitKind::Str(ref sym, _),
 +                ..
 +            }) => return sym.is_empty() && is_path_diagnostic_item(cx, ty, sym::String),
 +            ExprKind::Array([]) => return is_path_diagnostic_item(cx, ty, sym::Vec),
 +            ExprKind::Repeat(_, ArrayLen::Body(len)) => {
 +                if let ExprKind::Lit(ref const_lit) = cx.tcx.hir().body(len.body).value.kind &&
 +                    let LitKind::Int(v, _) = const_lit.node
 +                {
 +                        return v == 0 && is_path_diagnostic_item(cx, ty, sym::Vec);
 +                }
 +            }
 +            _ => (),
 +        }
 +    }
 +    false
 +}
 +
  /// Checks if the top level expression can be moved into a closure as is.
  /// Currently checks for:
  /// * Break/Continue outside the given loop HIR ids.