]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/types.rs
Auto merge of #6834 - hyd-dev:clippy-args, r=phansch,flip1995,oli-obk
[rust.git] / clippy_lints / src / types.rs
index e647812a0fe8fc3094eb1ac7697fff805dd3d811..ce201b956d83d83cceeaf97fb9e26983a11346fe 100644 (file)
@@ -11,8 +11,8 @@
 use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, FnKind, NestedVisitorMap, Visitor};
 use rustc_hir::{
     BinOpKind, Block, Body, Expr, ExprKind, FnDecl, FnRetTy, FnSig, GenericArg, GenericBounds, GenericParamKind, HirId,
-    ImplItem, ImplItemKind, Item, ItemKind, Lifetime, Lit, Local, MatchSource, MutTy, Mutability, Node, QPath, Stmt,
-    StmtKind, SyntheticTyParamKind, TraitFn, TraitItem, TraitItemKind, TyKind, UnOp,
+    ImplItem, ImplItemKind, Item, ItemKind, LangItem, Lifetime, Lit, Local, MatchSource, MutTy, Mutability, Node,
+    QPath, Stmt, StmtKind, SyntheticTyParamKind, TraitFn, TraitItem, TraitItemKind, TyKind, UnOp,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::map::Map;
 use crate::utils::paths;
 use crate::utils::sugg::Sugg;
 use crate::utils::{
-    clip, comparisons, differing_macro_contexts, higher, in_constant, indent_of, int_bits, is_hir_ty_cfg_dependant,
-    is_type_diagnostic_item, last_path_segment, match_def_path, match_path, meets_msrv, method_chain_args,
-    multispan_sugg, numeric_literal::NumericLiteral, reindent_multiline, sext, snippet, snippet_opt,
-    snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg,
-    span_lint_and_then, unsext,
+    clip, comparisons, differing_macro_contexts, get_qpath_generic_tys, higher, in_constant, indent_of, int_bits,
+    is_hir_ty_cfg_dependant, is_ty_param_diagnostic_item, is_ty_param_lang_item, is_type_diagnostic_item,
+    last_path_segment, match_def_path, match_path, meets_msrv, method_chain_args, multispan_sugg,
+    numeric_literal::NumericLiteral, reindent_multiline, sext, snippet, snippet_opt, snippet_with_applicability,
+    snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, unsext,
 };
 
 declare_clippy_lint! {
@@ -287,37 +287,16 @@ fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) {
     }
 }
 
-/// Checks if `qpath` has last segment with type parameter matching `path`
-fn match_type_parameter(cx: &LateContext<'_>, qpath: &QPath<'_>, path: &[&str]) -> Option<Span> {
-    let last = last_path_segment(qpath);
-    if_chain! {
-        if let Some(ref params) = last.args;
-        if !params.parenthesized;
-        if let Some(ty) = params.args.iter().find_map(|arg| match arg {
-            GenericArg::Type(ty) => Some(ty),
-            _ => None,
-        });
-        if let TyKind::Path(ref qpath) = ty.kind;
-        if let Some(did) = cx.qpath_res(qpath, ty.hir_id).opt_def_id();
-        if match_def_path(cx, did, path);
-        then {
-            return Some(ty.span);
-        }
-    }
-    None
-}
-
 fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> {
-    if match_type_parameter(cx, qpath, &paths::STRING).is_some() {
-        return Some("str");
-    }
-    if match_type_parameter(cx, qpath, &paths::OS_STRING).is_some() {
-        return Some("std::ffi::OsStr");
-    }
-    if match_type_parameter(cx, qpath, &paths::PATH_BUF).is_some() {
-        return Some("std::path::Path");
+    if is_ty_param_diagnostic_item(cx, qpath, sym::string_type).is_some() {
+        Some("str")
+    } else if is_ty_param_diagnostic_item(cx, qpath, sym::OsString).is_some() {
+        Some("std::ffi::OsStr")
+    } else if is_ty_param_diagnostic_item(cx, qpath, sym::PathBuf).is_some() {
+        Some("std::path::Path")
+    } else {
+        None
     }
-    None
 }
 
 fn match_borrows_parameter(_cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<Span> {
@@ -381,19 +360,19 @@ fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, is_local: boo
                             );
                             return; // don't recurse into the type
                         }
-                        if match_type_parameter(cx, qpath, &paths::VEC).is_some() {
+                        if is_ty_param_diagnostic_item(cx, qpath, sym::vec_type).is_some() {
                             span_lint_and_help(
                                 cx,
                                 BOX_VEC,
                                 hir_ty.span,
                                 "you seem to be trying to use `Box<Vec<T>>`. Consider using just `Vec<T>`",
                                 None,
-                                "`Vec<T>` is already on the heap, `Box<Vec<T>>` makes an extra allocation.",
+                                "`Vec<T>` is already on the heap, `Box<Vec<T>>` makes an extra allocation",
                             );
                             return; // don't recurse into the type
                         }
                     } else if cx.tcx.is_diagnostic_item(sym::Rc, def_id) {
-                        if let Some(span) = match_type_parameter(cx, qpath, &paths::RC) {
+                        if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Rc) {
                             let mut applicability = Applicability::MachineApplicable;
                             span_lint_and_sugg(
                                 cx,
@@ -401,22 +380,19 @@ fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, is_local: boo
                                 hir_ty.span,
                                 "usage of `Rc<Rc<T>>`",
                                 "try",
-                                snippet_with_applicability(cx, span, "..", &mut applicability).to_string(),
+                                snippet_with_applicability(cx, ty.span, "..", &mut applicability).to_string(),
                                 applicability,
                             );
                             return; // don't recurse into the type
                         }
-                        if match_type_parameter(cx, qpath, &paths::BOX).is_some() {
-                            let box_ty = match &last_path_segment(qpath).args.unwrap().args[0] {
-                                GenericArg::Type(ty) => match &ty.kind {
-                                    TyKind::Path(qpath) => qpath,
-                                    _ => return,
-                                },
+                        if let Some(ty) = is_ty_param_lang_item(cx, qpath, LangItem::OwnedBox) {
+                            let qpath = match &ty.kind {
+                                TyKind::Path(qpath) => qpath,
                                 _ => return,
                             };
-                            let inner_span = match &last_path_segment(&box_ty).args.unwrap().args[0] {
-                                GenericArg::Type(ty) => ty.span,
-                                _ => return,
+                            let inner_span = match get_qpath_generic_tys(qpath).next() {
+                                Some(ty) => ty.span,
+                                None => return,
                             };
                             let mut applicability = Applicability::MachineApplicable;
                             span_lint_and_sugg(
@@ -445,17 +421,14 @@ fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, is_local: boo
                             );
                             return; // don't recurse into the type
                         }
-                        if match_type_parameter(cx, qpath, &paths::VEC).is_some() {
-                            let vec_ty = match &last_path_segment(qpath).args.unwrap().args[0] {
-                                GenericArg::Type(ty) => match &ty.kind {
-                                    TyKind::Path(qpath) => qpath,
-                                    _ => return,
-                                },
+                        if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::vec_type) {
+                            let qpath = match &ty.kind {
+                                TyKind::Path(qpath) => qpath,
                                 _ => return,
                             };
-                            let inner_span = match &last_path_segment(&vec_ty).args.unwrap().args[0] {
-                                GenericArg::Type(ty) => ty.span,
-                                _ => return,
+                            let inner_span = match get_qpath_generic_tys(qpath).next() {
+                                Some(ty) => ty.span,
+                                None => return,
                             };
                             let mut applicability = Applicability::MachineApplicable;
                             span_lint_and_sugg(
@@ -498,17 +471,14 @@ fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, is_local: boo
                             );
                             return; // don't recurse into the type
                         }
-                        if match_type_parameter(cx, qpath, &paths::VEC).is_some() {
-                            let vec_ty = match &last_path_segment(qpath).args.unwrap().args[0] {
-                                GenericArg::Type(ty) => match &ty.kind {
-                                    TyKind::Path(qpath) => qpath,
-                                    _ => return,
-                                },
+                        if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::vec_type) {
+                            let qpath = match &ty.kind {
+                                TyKind::Path(qpath) => qpath,
                                 _ => return,
                             };
-                            let inner_span = match &last_path_segment(&vec_ty).args.unwrap().args[0] {
-                                GenericArg::Type(ty) => ty.span,
-                                _ => return,
+                            let inner_span = match get_qpath_generic_tys(qpath).next() {
+                                Some(ty) => ty.span,
+                                None => return,
                             };
                             let mut applicability = Applicability::MachineApplicable;
                             span_lint_and_sugg(
@@ -554,7 +524,7 @@ fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, is_local: boo
                                     cx,
                                     VEC_BOX,
                                     hir_ty.span,
-                                    "`Vec<T>` is already on the heap, the boxing is unnecessary.",
+                                    "`Vec<T>` is already on the heap, the boxing is unnecessary",
                                     "try",
                                     format!("Vec<{}>", snippet(cx, boxed_ty.span, "..")),
                                     Applicability::MachineApplicable,
@@ -563,7 +533,7 @@ fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, is_local: boo
                             }
                         }
                     } else if cx.tcx.is_diagnostic_item(sym::option_type, def_id) {
-                        if match_type_parameter(cx, qpath, &paths::OPTION).is_some() {
+                        if is_ty_param_diagnostic_item(cx, qpath, sym::option_type).is_some() {
                             span_lint(
                                 cx,
                                 OPTION_OPTION,
@@ -578,7 +548,7 @@ enum if you need to distinguish all 3 cases",
                             cx,
                             LINKEDLIST,
                             hir_ty.span,
-                            "I see you're using a LinkedList! Perhaps you meant some other data structure?",
+                            "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?",
                             None,
                             "a `VecDeque` might work",
                         );
@@ -955,7 +925,10 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
                     .iter()
                     .filter(|arg| {
                         if is_unit(cx.typeck_results().expr_ty(arg)) && !is_unit_literal(arg) {
-                            !matches!(&arg.kind, ExprKind::Match(.., MatchSource::TryDesugar))
+                            !matches!(
+                                &arg.kind,
+                                ExprKind::Match(.., MatchSource::TryDesugar) | ExprKind::Path(..)
+                            )
                         } else {
                             false
                         }
@@ -2567,7 +2540,7 @@ fn suggestion<'tcx>(
             }
         }
 
-        if !cx.access_levels.is_exported(item.hir_id) {
+        if !cx.access_levels.is_exported(item.hir_id()) {
             return;
         }