]> git.lizzy.rs Git - rust.git/commitdiff
Merge remote-tracking branch 'upstream/master' into rustup
authorflip1995 <hello@philkrones.com>
Fri, 3 Jul 2020 10:50:41 +0000 (12:50 +0200)
committerflip1995 <hello@philkrones.com>
Fri, 3 Jul 2020 10:50:41 +0000 (12:50 +0200)
1  2 
clippy_lints/src/attrs.rs
clippy_lints/src/await_holding_lock.rs
clippy_lints/src/dereference.rs
clippy_lints/src/map_identity.rs
clippy_lints/src/methods/mod.rs
clippy_lints/src/misc.rs
clippy_lints/src/needless_pass_by_value.rs
clippy_lints/src/regex.rs
clippy_lints/src/utils/sugg.rs

index 2505ff32fe52333d919ceee9b2947c96b11b2e62,bb9d8be5daee0a7b624ccd27c7b0a9fa2cae9002..2d0855f6895540d74ae948ce75e8a90799a0721a
@@@ -249,15 -272,17 +272,17 @@@ declare_lint_pass!(Attributes => 
      DEPRECATED_SEMVER,
      USELESS_ATTRIBUTE,
      UNKNOWN_CLIPPY_LINTS,
+     BLANKET_CLIPPY_RESTRICTION_LINTS,
  ]);
  
 -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Attributes {
 -    fn check_attribute(&mut self, cx: &LateContext<'a, 'tcx>, attr: &'tcx Attribute) {
 +impl<'tcx> LateLintPass<'tcx> for Attributes {
 +    fn check_attribute(&mut self, cx: &LateContext<'tcx>, attr: &'tcx Attribute) {
          if let Some(items) = &attr.meta_item_list() {
              if let Some(ident) = attr.ident() {
-                 match &*ident.as_str() {
+                 let ident = &*ident.as_str();
+                 match ident {
                      "allow" | "warn" | "deny" | "forbid" => {
-                         check_clippy_lint_names(cx, items);
+                         check_clippy_lint_names(cx, ident, items);
                      },
                      _ => {},
                  }
      }
  }
  
- #[allow(clippy::single_match_else)]
- fn check_clippy_lint_names(cx: &LateContext<'_>, items: &[NestedMetaItem]) {
-     let lint_store = cx.lints();
-     for lint in items {
 -fn check_clippy_lint_names(cx: &LateContext<'_, '_>, ident: &str, items: &[NestedMetaItem]) {
++fn check_clippy_lint_names(cx: &LateContext<'_>, ident: &str, items: &[NestedMetaItem]) {
+     fn extract_name(lint: &NestedMetaItem) -> Option<SymbolStr> {
          if_chain! {
              if let Some(meta_item) = lint.meta_item();
              if meta_item.path.segments.len() > 1;
index d740d88a77d6cb8b018764c43b54840901066dc8,0fdd591982588f59835f014ff82bfe75fa05ed66..323cad7fa1a8c7dcfe62eb67e71c4af4dd36bfae
@@@ -70,12 -70,13 +70,13 @@@ impl<'tcx> LateLintPass<'tcx> for Deref
      }
  }
  
 -fn lint_deref(cx: &LateContext<'_, '_>, method_name: &str, call_expr: &Expr<'_>, var_span: Span, expr_span: Span) {
 +fn lint_deref(cx: &LateContext<'_>, method_name: &str, call_expr: &Expr<'_>, var_span: Span, expr_span: Span) {
      match method_name {
          "deref" => {
-             if cx.tcx.lang_items().deref_trait().map_or(false, |id| {
+             let impls_deref_trait = cx.tcx.lang_items().deref_trait().map_or(false, |id| {
                  implements_trait(cx, cx.tables().expr_ty(&call_expr), id, &[])
-             }) {
+             });
+             if impls_deref_trait {
                  span_lint_and_sugg(
                      cx,
                      EXPLICIT_DEREF_METHODS,
index 0000000000000000000000000000000000000000,30c67672e9fa143ceb83d321682626ec7226f297..24ec78c884647951dcb82849f8ffff9f2bc24800
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,126 +1,126 @@@
 -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapIdentity {
 -    fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
+ use crate::utils::{
+     is_adjusted, is_type_diagnostic_item, match_path, match_trait_method, match_var, paths, remove_blocks,
+     span_lint_and_sugg,
+ };
+ use if_chain::if_chain;
+ use rustc_errors::Applicability;
+ use rustc_hir::{Body, Expr, ExprKind, Pat, PatKind, QPath, StmtKind};
+ use rustc_lint::{LateContext, LateLintPass};
+ use rustc_session::{declare_lint_pass, declare_tool_lint};
+ declare_clippy_lint! {
+     /// **What it does:** Checks for instances of `map(f)` where `f` is the identity function.
+     ///
+     /// **Why is this bad?** It can be written more concisely without the call to `map`.
+     ///
+     /// **Known problems:** None.
+     ///
+     /// **Example:**
+     ///
+     /// ```rust
+     /// let x = [1, 2, 3];
+     /// let y: Vec<_> = x.iter().map(|x| x).map(|x| 2*x).collect();
+     /// ```
+     /// Use instead:
+     /// ```rust
+     /// let x = [1, 2, 3];
+     /// let y: Vec<_> = x.iter().map(|x| 2*x).collect();
+     /// ```
+     pub MAP_IDENTITY,
+     complexity,
+     "using iterator.map(|x| x)"
+ }
+ declare_lint_pass!(MapIdentity => [MAP_IDENTITY]);
 -fn get_map_argument<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option<&'a [Expr<'a>]> {
++impl<'tcx> LateLintPass<'tcx> for MapIdentity {
++    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+         if expr.span.from_expansion() {
+             return;
+         }
+         if_chain! {
+             if let Some([caller, func]) = get_map_argument(cx, expr);
+             if is_expr_identity_function(cx, func);
+             then {
+                 span_lint_and_sugg(
+                     cx,
+                     MAP_IDENTITY,
+                     expr.span.trim_start(caller.span).unwrap(),
+                     "unnecessary map of the identity function",
+                     "remove the call to `map`",
+                     String::new(),
+                     Applicability::MachineApplicable
+                 )
+             }
+         }
+     }
+ }
+ /// Returns the arguments passed into map() if the expression is a method call to
+ /// map(). Otherwise, returns None.
 -fn is_expr_identity_function(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
++fn get_map_argument<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<&'a [Expr<'a>]> {
+     if_chain! {
+         if let ExprKind::MethodCall(ref method, _, ref args, _) = expr.kind;
+         if args.len() == 2 && method.ident.as_str() == "map";
+         let caller_ty = cx.tables().expr_ty(&args[0]);
+         if match_trait_method(cx, expr, &paths::ITERATOR)
+             || is_type_diagnostic_item(cx, caller_ty, sym!(result_type))
+             || is_type_diagnostic_item(cx, caller_ty, sym!(option_type));
+         then {
+             Some(args)
+         } else {
+             None
+         }
+     }
+ }
+ /// Checks if an expression represents the identity function
+ /// Only examines closures and `std::convert::identity`
 -fn is_body_identity_function(cx: &LateContext<'_, '_>, func: &Body<'_>) -> bool {
++fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+     match expr.kind {
+         ExprKind::Closure(_, _, body_id, _, _) => is_body_identity_function(cx, cx.tcx.hir().body(body_id)),
+         ExprKind::Path(QPath::Resolved(_, ref path)) => match_path(path, &paths::STD_CONVERT_IDENTITY),
+         _ => false,
+     }
+ }
+ /// Checks if a function's body represents the identity function
+ /// Looks for bodies of the form `|x| x`, `|x| return x`, `|x| { return x }` or `|x| {
+ /// return x; }`
 -fn match_expr_param(cx: &LateContext<'_, '_>, expr: &Expr<'_>, pat: &Pat<'_>) -> bool {
++fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
+     let params = func.params;
+     let body = remove_blocks(&func.value);
+     // if there's less/more than one parameter, then it is not the identity function
+     if params.len() != 1 {
+         return false;
+     }
+     match body.kind {
+         ExprKind::Path(QPath::Resolved(None, _)) => match_expr_param(cx, body, params[0].pat),
+         ExprKind::Ret(Some(ref ret_val)) => match_expr_param(cx, ret_val, params[0].pat),
+         ExprKind::Block(ref block, _) => {
+             if_chain! {
+                 if block.stmts.len() == 1;
+                 if let StmtKind::Semi(ref expr) | StmtKind::Expr(ref expr) = block.stmts[0].kind;
+                 if let ExprKind::Ret(Some(ref ret_val)) = expr.kind;
+                 then {
+                     match_expr_param(cx, ret_val, params[0].pat)
+                 } else {
+                     false
+                 }
+             }
+         },
+         _ => false,
+     }
+ }
+ /// Returns true iff an expression returns the same thing as a parameter's pattern
 -        match_var(expr, ident.name) && !(cx.tables().hir_owner == Some(expr.hir_id.owner) && is_adjusted(cx, expr))
++fn match_expr_param(cx: &LateContext<'_>, expr: &Expr<'_>, pat: &Pat<'_>) -> bool {
+     if let PatKind::Binding(_, _, ident, _) = pat.kind {
++        match_var(expr, ident.name) && !(cx.tables().hir_owner == expr.hir_id.owner && is_adjusted(cx, expr))
+     } else {
+         false
+     }
+ }
Simple merge
index d7e1a62a19d5204bd9d0e81bbe9b6c64bbc44dbe,744b9aa602230bca9a31f98af864b5898ff94753..6a256627bd18e3a085116e4ce653a7f3eaa4a2f2
@@@ -570,7 -570,26 +570,26 @@@ fn is_array(cx: &LateContext<'_>, expr
      matches!(&walk_ptrs_ty(cx.tables().expr_ty(expr)).kind, ty::Array(_, _))
  }
  
- fn check_to_owned(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>) {
 -fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool) {
++fn check_to_owned(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool) {
+     #[derive(Default)]
+     struct EqImpl {
+         ty_eq_other: bool,
+         other_eq_ty: bool,
+     }
+     impl EqImpl {
+         fn is_implemented(&self) -> bool {
+             self.ty_eq_other || self.other_eq_ty
+         }
+     }
 -    fn symmetric_partial_eq<'tcx>(cx: &LateContext<'_, 'tcx>, ty: Ty<'tcx>, other: Ty<'tcx>) -> Option<EqImpl> {
++    fn symmetric_partial_eq<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, other: Ty<'tcx>) -> Option<EqImpl> {
+         cx.tcx.lang_items().eq_trait().map(|def_id| EqImpl {
+             ty_eq_other: implements_trait(cx, ty, def_id, &[other.into()]),
+             other_eq_ty: implements_trait(cx, other, def_id, &[ty.into()]),
+         })
+     }
      let (arg_ty, snip) = match expr.kind {
          ExprKind::MethodCall(.., ref args, _) if args.len() == 1 => {
              if match_trait_method(cx, expr, &paths::TO_STRING) || match_trait_method(cx, expr, &paths::TO_OWNED) {
@@@ -694,7 -720,7 +720,7 @@@ fn non_macro_local(cx: &LateContext<'_>
      }
  }
  
- fn check_cast(cx: &LateContext<'_>, span: Span, e: &Expr<'_>, ty: &Ty<'_>) {
 -fn check_cast(cx: &LateContext<'_, '_>, span: Span, e: &Expr<'_>, ty: &hir::Ty<'_>) {
++fn check_cast(cx: &LateContext<'_>, span: Span, e: &Expr<'_>, ty: &hir::Ty<'_>) {
      if_chain! {
          if let TyKind::Ptr(ref mut_ty) = ty.kind;
          if let ExprKind::Lit(ref lit) = e.kind;
index b67abad6ccb8f502e3e89ae6e4163eb43d8ef8ca,7405edbcd1966ac736be2a0f7ed01ff5e11ea438..d8c8eff2c853f508859b866c22f78d4809a3f390
@@@ -71,42 -52,10 +52,10 @@@ pub struct Regex 
      last: Option<HirId>,
  }
  
- impl_lint_pass!(Regex => [INVALID_REGEX, REGEX_MACRO, TRIVIAL_REGEX]);
+ impl_lint_pass!(Regex => [INVALID_REGEX, TRIVIAL_REGEX]);
  
 -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Regex {
 -    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
 +impl<'tcx> LateLintPass<'tcx> for Regex {
-     fn check_crate(&mut self, _: &LateContext<'tcx>, _: &'tcx Crate<'_>) {
-         self.spans.clear();
-     }
-     fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) {
-         if_chain! {
-             if self.last.is_none();
-             if let Some(ref expr) = block.expr;
-             if match_type(cx, cx.tables().expr_ty(expr), &paths::REGEX);
-             if let Some(span) = is_expn_of(expr.span, "regex");
-             then {
-                 if !self.spans.contains(&span) {
-                     span_lint(
-                         cx,
-                         REGEX_MACRO,
-                         span,
-                         "`regex!(_)` found. \
-                         Please use `Regex::new(_)`, which is faster for now."
-                     );
-                     self.spans.insert(span);
-                 }
-                 self.last = Some(block.hir_id);
-             }
-         }
-     }
-     fn check_block_post(&mut self, _: &LateContext<'tcx>, block: &'tcx Block<'_>) {
-         if self.last.map_or(false, |id| block.hir_id == id) {
-             self.last = None;
-         }
-     }
 +    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
          if_chain! {
              if let ExprKind::Call(ref fun, ref args) = expr.kind;
              if let ExprKind::Path(ref qpath) = fun.kind;
Simple merge