]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/lifetimes.rs
Update lint documentation to use markdown headlines
[rust.git] / clippy_lints / src / lifetimes.rs
index 5fed58b821097611575400becbbf741b100c5ae1..e5e6f8d25cc11143878512361a1a9d9f5672cb99 100644 (file)
@@ -1,4 +1,5 @@
-use crate::utils::{in_macro, span_lint, trait_ref_of_method};
+use clippy_utils::diagnostics::span_lint;
+use clippy_utils::{in_macro, trait_ref_of_method};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::intravisit::{
     walk_fn_decl, walk_generic_param, walk_generics, walk_item, walk_param_bound, walk_poly_trait_ref, walk_ty,
 use rustc_span::symbol::{kw, Symbol};
 
 declare_clippy_lint! {
-    /// **What it does:** Checks for lifetime annotations which can be removed by
+    /// ### What it does
+    /// Checks for lifetime annotations which can be removed by
     /// relying on lifetime elision.
     ///
-    /// **Why is this bad?** The additional lifetimes make the code look more
+    /// ### Why is this bad?
+    /// The additional lifetimes make the code look more
     /// complicated, while there is nothing out of the ordinary going on. Removing
     /// them leads to more readable code.
     ///
-    /// **Known problems:**
+    /// ### Known problems
     /// - We bail out if the function has a `where` clause where lifetimes
     /// are mentioned due to potenial false positives.
     /// - Lifetime bounds such as `impl Foo + 'a` and `T: 'a` must be elided with the
     /// placeholder notation `'_` because the fully elided notation leaves the type bound to `'static`.
     ///
-    /// **Example:**
+    /// ### Example
     /// ```rust
     /// // Bad: unnecessary lifetime annotations
     /// fn in_and_out<'a>(x: &'a u8, y: u8) -> &'a u8 {
 }
 
 declare_clippy_lint! {
-    /// **What it does:** Checks for lifetimes in generics that are never used
+    /// ### What it does
+    /// Checks for lifetimes in generics that are never used
     /// anywhere else.
     ///
-    /// **Why is this bad?** The additional lifetimes make the code look more
+    /// ### Why is this bad?
+    /// The additional lifetimes make the code look more
     /// complicated, while there is nothing out of the ordinary going on. Removing
     /// them leads to more readable code.
     ///
-    /// **Known problems:** None.
-    ///
-    /// **Example:**
+    /// ### Example
     /// ```rust
     /// // Bad: unnecessary lifetimes
     /// fn unused_lifetime<'a>(x: u8) {
@@ -80,7 +83,7 @@
 impl<'tcx> LateLintPass<'tcx> for Lifetimes {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
         if let ItemKind::Fn(ref sig, ref generics, id) = item.kind {
-            check_fn_inner(cx, &sig.decl, Some(id), generics, item.span, true);
+            check_fn_inner(cx, sig.decl, Some(id), generics, item.span, true);
         }
     }
 
@@ -89,7 +92,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>)
             let report_extra_lifetimes = trait_ref_of_method(cx, item.hir_id()).is_none();
             check_fn_inner(
                 cx,
-                &sig.decl,
+                sig.decl,
                 Some(id),
                 &item.generics,
                 item.span,
@@ -104,7 +107,7 @@ fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>
                 TraitFn::Required(_) => None,
                 TraitFn::Provided(id) => Some(id),
             };
-            check_fn_inner(cx, &sig.decl, body, &item.generics, item.span, true);
+            check_fn_inner(cx, sig.decl, body, &item.generics, item.span, true);
         }
     }
 }
@@ -148,7 +151,7 @@ fn check_fn_inner<'tcx>(
                     .last()
                     .expect("a path must have at least one segment")
                     .args;
-                if let Some(ref params) = *params {
+                if let Some(params) = *params {
                     let lifetimes = params.args.iter().filter_map(|arg| match arg {
                         GenericArg::Lifetime(lt) => Some(lt),
                         _ => None,
@@ -162,7 +165,7 @@ fn check_fn_inner<'tcx>(
             }
         }
     }
-    if could_use_elision(cx, decl, body, &generics.params) {
+    if could_use_elision(cx, decl, body, generics.params) {
         span_lint(
             cx,
             NEEDLESS_LIFETIMES,
@@ -200,11 +203,11 @@ fn could_use_elision<'tcx>(
         input_visitor.visit_ty(arg);
     }
     // extract lifetimes in output type
-    if let Return(ref ty) = func.output {
+    if let Return(ty) = func.output {
         output_visitor.visit_ty(ty);
     }
     for lt in named_generics {
-        input_visitor.visit_generic_param(lt)
+        input_visitor.visit_generic_param(lt);
     }
 
     if input_visitor.abort() || output_visitor.abort() {
@@ -358,10 +361,13 @@ fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {
 
     fn visit_poly_trait_ref(&mut self, poly_tref: &'tcx PolyTraitRef<'tcx>, tbm: TraitBoundModifier) {
         let trait_ref = &poly_tref.trait_ref;
-        if CLOSURE_TRAIT_BOUNDS
-            .iter()
-            .any(|&item| trait_ref.trait_def_id() == self.cx.tcx.lang_items().items()[item as usize])
-        {
+        if CLOSURE_TRAIT_BOUNDS.iter().any(|&item| {
+            self.cx
+                .tcx
+                .lang_items()
+                .require(item)
+                .map_or(false, |id| Some(id) == trait_ref.trait_def_id())
+        }) {
             let mut sub_visitor = RefVisitor::new(self.cx);
             sub_visitor.visit_trait_ref(trait_ref);
             self.nested_elision_site_lts.append(&mut sub_visitor.all_lts());
@@ -384,7 +390,7 @@ fn visit_ty(&mut self, ty: &'tcx Ty<'_>) {
                 self.nested_elision_site_lts.append(&mut sub_visitor.all_lts());
                 return;
             },
-            TyKind::TraitObject(bounds, ref lt) => {
+            TyKind::TraitObject(bounds, ref lt, _) => {
                 if !lt.is_elided() {
                     self.unelided_trait_object_lifetime = true;
                 }
@@ -412,12 +418,12 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, where_clause: &'tcx WhereCl
                 // a predicate like F: Trait or F: for<'a> Trait<'a>
                 let mut visitor = RefVisitor::new(cx);
                 // walk the type F, it may not contain LT refs
-                walk_ty(&mut visitor, &pred.bounded_ty);
+                walk_ty(&mut visitor, pred.bounded_ty);
                 if !visitor.all_lts().is_empty() {
                     return true;
                 }
                 // if the bounds define new lifetimes, they are fine to occur
-                let allowed_lts = allowed_lts_from(&pred.bound_generic_params);
+                let allowed_lts = allowed_lts_from(pred.bound_generic_params);
                 // now walk the bounds
                 for bound in pred.bounds.iter() {
                     walk_param_bound(&mut visitor, bound);
@@ -429,8 +435,8 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, where_clause: &'tcx WhereCl
             },
             WherePredicate::EqPredicate(ref pred) => {
                 let mut visitor = RefVisitor::new(cx);
-                walk_ty(&mut visitor, &pred.lhs_ty);
-                walk_ty(&mut visitor, &pred.rhs_ty);
+                walk_ty(&mut visitor, pred.lhs_ty);
+                walk_ty(&mut visitor, pred.rhs_ty);
                 if !visitor.lts.is_empty() {
                     return true;
                 }
@@ -459,7 +465,7 @@ fn visit_generic_param(&mut self, param: &'tcx GenericParam<'_>) {
         // `'b` in `'a: 'b` is useless unless used elsewhere in
         // a non-lifetime bound
         if let GenericParamKind::Type { .. } = param.kind {
-            walk_generic_param(self, param)
+            walk_generic_param(self, param);
         }
     }
     fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {