]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/len_zero.rs
Merge commit 'e636b88aa180e8cab9e28802aac90adbc984234d' into clippyup
[rust.git] / clippy_lints / src / len_zero.rs
index 48881e1c2f0316309aca2b878f7b0b927543f532..c9c4891bb08acf67f4161184424f50b4ac486ea8 100644 (file)
@@ -1,13 +1,13 @@
-use crate::utils::{get_item_name, snippet_with_applicability, span_lint, span_lint_and_sugg, walk_ptrs_ty};
-use rustc::ty;
-use rustc_ast::ast::{LitKind, Name};
+use crate::utils::{get_item_name, snippet_with_applicability, span_lint, span_lint_and_sugg};
+use rustc_ast::ast::LitKind;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{AssocItemKind, BinOpKind, Expr, ExprKind, ImplItemRef, Item, ItemKind, TraitItemRef};
 use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::source_map::{Span, Spanned};
+use rustc_span::source_map::{Span, Spanned, Symbol};
 
 declare_clippy_lint! {
     /// **What it does:** Checks for getting the length of something via `.len()`
@@ -70,8 +70,8 @@
 
 declare_lint_pass!(LenZero => [LEN_ZERO, LEN_WITHOUT_IS_EMPTY]);
 
-impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LenZero {
-    fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) {
+impl<'tcx> LateLintPass<'tcx> for LenZero {
+    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
         if item.span.from_expansion() {
             return;
         }
@@ -87,7 +87,7 @@ fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) {
         }
     }
 
-    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         if expr.span.from_expansion() {
             return;
         }
@@ -118,10 +118,10 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
     }
 }
 
-fn check_trait_items(cx: &LateContext<'_, '_>, visited_trait: &Item<'_>, trait_items: &[TraitItemRef]) {
-    fn is_named_self(cx: &LateContext<'_, '_>, item: &TraitItemRef, name: &str) -> bool {
+fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items: &[TraitItemRef]) {
+    fn is_named_self(cx: &LateContext<'_>, item: &TraitItemRef, name: &str) -> bool {
         item.ident.name.as_str() == name
-            && if let AssocItemKind::Method { has_self } = item.kind {
+            && if let AssocItemKind::Fn { has_self } = item.kind {
                 has_self && {
                     let did = cx.tcx.hir().local_def_id(item.id.hir_id);
                     cx.tcx.fn_sig(did).inputs().skip_binder().len() == 1
@@ -132,9 +132,9 @@ fn is_named_self(cx: &LateContext<'_, '_>, item: &TraitItemRef, name: &str) -> b
     }
 
     // fill the set with current and super traits
-    fn fill_trait_set(traitt: DefId, set: &mut FxHashSet<DefId>, cx: &LateContext<'_, '_>) {
+    fn fill_trait_set(traitt: DefId, set: &mut FxHashSet<DefId>, cx: &LateContext<'_>) {
         if set.insert(traitt) {
-            for supertrait in rustc_infer::traits::supertrait_def_ids(cx.tcx, traitt) {
+            for supertrait in rustc_trait_selection::traits::supertrait_def_ids(cx.tcx, traitt) {
                 fill_trait_set(supertrait, set, cx);
             }
         }
@@ -143,14 +143,14 @@ fn fill_trait_set(traitt: DefId, set: &mut FxHashSet<DefId>, cx: &LateContext<'_
     if cx.access_levels.is_exported(visited_trait.hir_id) && trait_items.iter().any(|i| is_named_self(cx, i, "len")) {
         let mut current_and_super_traits = FxHashSet::default();
         let visited_trait_def_id = cx.tcx.hir().local_def_id(visited_trait.hir_id);
-        fill_trait_set(visited_trait_def_id, &mut current_and_super_traits, cx);
+        fill_trait_set(visited_trait_def_id.to_def_id(), &mut current_and_super_traits, cx);
 
         let is_empty_method_found = current_and_super_traits
             .iter()
             .flat_map(|&i| cx.tcx.associated_items(i).in_definition_order())
             .any(|i| {
-                i.kind == ty::AssocKind::Method
-                    && i.method_has_self_argument
+                i.kind == ty::AssocKind::Fn
+                    && i.fn_has_self_parameter
                     && i.ident.name == sym!(is_empty)
                     && cx.tcx.fn_sig(i.def_id).inputs().skip_binder().len() == 1
             });
@@ -169,10 +169,10 @@ fn fill_trait_set(traitt: DefId, set: &mut FxHashSet<DefId>, cx: &LateContext<'_
     }
 }
 
-fn check_impl_items(cx: &LateContext<'_, '_>, item: &Item<'_>, impl_items: &[ImplItemRef<'_>]) {
-    fn is_named_self(cx: &LateContext<'_, '_>, item: &ImplItemRef<'_>, name: &str) -> bool {
+fn check_impl_items(cx: &LateContext<'_>, item: &Item<'_>, impl_items: &[ImplItemRef<'_>]) {
+    fn is_named_self(cx: &LateContext<'_>, item: &ImplItemRef<'_>, name: &str) -> bool {
         item.ident.name.as_str() == name
-            && if let AssocItemKind::Method { has_self } = item.kind {
+            && if let AssocItemKind::Fn { has_self } = item.kind {
                 has_self && {
                     let did = cx.tcx.hir().local_def_id(item.id.hir_id);
                     cx.tcx.fn_sig(did).inputs().skip_binder().len() == 1
@@ -210,8 +210,9 @@ fn is_named_self(cx: &LateContext<'_, '_>, item: &ImplItemRef<'_>, name: &str) -
     }
 }
 
-fn check_cmp(cx: &LateContext<'_, '_>, span: Span, method: &Expr<'_>, lit: &Expr<'_>, op: &str, compare_to: u32) {
-    if let (&ExprKind::MethodCall(ref method_path, _, ref args), &ExprKind::Lit(ref lit)) = (&method.kind, &lit.kind) {
+fn check_cmp(cx: &LateContext<'_>, span: Span, method: &Expr<'_>, lit: &Expr<'_>, op: &str, compare_to: u32) {
+    if let (&ExprKind::MethodCall(ref method_path, _, ref args, _), &ExprKind::Lit(ref lit)) = (&method.kind, &lit.kind)
+    {
         // check if we are in an is_empty() method
         if let Some(name) = get_item_name(cx, method) {
             if name.as_str() == "is_empty" {
@@ -224,9 +225,9 @@ fn check_cmp(cx: &LateContext<'_, '_>, span: Span, method: &Expr<'_>, lit: &Expr
 }
 
 fn check_len(
-    cx: &LateContext<'_, '_>,
+    cx: &LateContext<'_>,
     span: Span,
-    method_name: Name,
+    method_name: Symbol,
     args: &[Expr<'_>],
     lit: &LitKind,
     op: &str,
@@ -258,10 +259,10 @@ fn check_len(
 }
 
 /// Checks if this type has an `is_empty` method.
-fn has_is_empty(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
+fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     /// Gets an `AssocItem` and return true if it matches `is_empty(self)`.
-    fn is_is_empty(cx: &LateContext<'_, '_>, item: &ty::AssocItem) -> bool {
-        if let ty::AssocKind::Method = item.kind {
+    fn is_is_empty(cx: &LateContext<'_>, item: &ty::AssocItem) -> bool {
+        if let ty::AssocKind::Fn = item.kind {
             if item.ident.name.as_str() == "is_empty" {
                 let sig = cx.tcx.fn_sig(item.def_id);
                 let ty = sig.skip_binder();
@@ -275,7 +276,7 @@ fn is_is_empty(cx: &LateContext<'_, '_>, item: &ty::AssocItem) -> bool {
     }
 
     /// Checks the inherent impl's items for an `is_empty(self)` method.
-    fn has_is_empty_impl(cx: &LateContext<'_, '_>, id: DefId) -> bool {
+    fn has_is_empty_impl(cx: &LateContext<'_>, id: DefId) -> bool {
         cx.tcx.inherent_impls(id).iter().any(|imp| {
             cx.tcx
                 .associated_items(*imp)
@@ -284,18 +285,14 @@ fn has_is_empty_impl(cx: &LateContext<'_, '_>, id: DefId) -> bool {
         })
     }
 
-    let ty = &walk_ptrs_ty(cx.tables.expr_ty(expr));
-    match ty.kind {
-        ty::Dynamic(ref tt, ..) => {
-            if let Some(principal) = tt.principal() {
-                cx.tcx
-                    .associated_items(principal.def_id())
-                    .in_definition_order()
-                    .any(|item| is_is_empty(cx, &item))
-            } else {
-                false
-            }
-        },
+    let ty = &cx.typeck_results().expr_ty(expr).peel_refs();
+    match ty.kind() {
+        ty::Dynamic(ref tt, ..) => tt.principal().map_or(false, |principal| {
+            cx.tcx
+                .associated_items(principal.def_id())
+                .in_definition_order()
+                .any(|item| is_is_empty(cx, &item))
+        }),
         ty::Projection(ref proj) => has_is_empty_impl(cx, proj.item_def_id),
         ty::Adt(id, _) => has_is_empty_impl(cx, id.did),
         ty::Array(..) | ty::Slice(..) | ty::Str => true,