X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=clippy_lints%2Fsrc%2Flifetimes.rs;h=32170c9a7c6a7ce036a794631cc7a406ae77c419;hb=4d60841205d10293d6759df1948acda4c607c7eb;hp=cf7a016231e347f41dfb829918e2d93b405bec9d;hpb=b2caf669a8d2fd0bd121c1e898fb2e185a7fa30c;p=rust.git diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index cf7a016231e..32170c9a7c6 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -1,13 +1,22 @@ +// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use crate::reexport::*; +use crate::utils::{last_path_segment, span_lint}; use matches::matches; -use rustc::lint::*; -use rustc::{declare_lint, lint_array}; use rustc::hir::def::Def; -use rustc::hir::*; use rustc::hir::intravisit::*; -use std::collections::{HashMap, HashSet}; -use syntax::codemap::Span; -use crate::utils::{last_path_segment, span_lint}; +use rustc::hir::*; +use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintContext, LintPass}; +use rustc::{declare_tool_lint, lint_array}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use syntax::source_map::Span; use syntax::symbol::keywords; /// **What it does:** Checks for lifetime annotations which can be removed by @@ -22,13 +31,15 @@ /// /// **Example:** /// ```rust -/// fn in_and_out<'a>(x: &'a u8, y: u8) -> &'a u8 { x } +/// fn in_and_out<'a>(x: &'a u8, y: u8) -> &'a u8 { +/// x +/// } /// ``` declare_clippy_lint! { - pub NEEDLESS_LIFETIMES, - complexity, - "using explicit lifetimes for references in function arguments when elision rules \ - would allow omitting them" +pub NEEDLESS_LIFETIMES, +complexity, +"using explicit lifetimes for references in function arguments when elision rules \ + would allow omitting them" } /// **What it does:** Checks for lifetimes in generics that are never used @@ -42,7 +53,9 @@ /// /// **Example:** /// ```rust -/// fn unused_lifetime<'a>(x: u8) { .. } +/// fn unused_lifetime<'a>(x: u8) { +/// .. +/// } /// ``` declare_clippy_lint! { pub EXTRA_UNUSED_LIFETIMES, @@ -103,9 +116,9 @@ fn check_fn_inner<'a, 'tcx>( } let mut bounds_lts = Vec::new(); - let types = generics.params.iter().filter_map(|param| match param.kind { - GenericParamKind::Type { .. } => Some(param), - GenericParamKind::Lifetime { .. } => None, + let types = generics.params.iter().filter(|param| match param.kind { + GenericParamKind::Type { .. } => true, + GenericParamKind::Lifetime { .. } => false, }); for typ in types { for bound in &typ.bounds { @@ -142,7 +155,8 @@ fn check_fn_inner<'a, 'tcx>( cx, NEEDLESS_LIFETIMES, span, - "explicit lifetimes given in parameter types where they could be elided", + "explicit lifetimes given in parameter types where they could be elided \ + (or replaced with `'_` if needed by type declaration)", ); } report_extra_lifetimes(cx, decl, generics); @@ -190,7 +204,7 @@ fn could_use_elision<'a, 'tcx: 'a>( let mut checker = BodyLifetimeChecker { lifetimes_used_in_body: false, }; - checker.visit_expr(&cx.tcx.hir.body(body_id).value); + checker.visit_expr(&cx.tcx.hir().body(body_id).value); if checker.lifetimes_used_in_body { return false; } @@ -210,9 +224,7 @@ fn could_use_elision<'a, 'tcx: 'a>( // no output lifetimes, check distinctness of input lifetimes // only unnamed and static, ok - let unnamed_and_static = input_lts - .iter() - .all(|lt| *lt == RefLt::Unnamed || *lt == RefLt::Static); + let unnamed_and_static = input_lts.iter().all(|lt| *lt == RefLt::Unnamed || *lt == RefLt::Static); if unnamed_and_static { return false; } @@ -237,8 +249,8 @@ fn could_use_elision<'a, 'tcx: 'a>( } } -fn allowed_lts_from(named_generics: &[GenericParam]) -> HashSet { - let mut allowed_lts = HashSet::new(); +fn allowed_lts_from(named_generics: &[GenericParam]) -> FxHashSet { + let mut allowed_lts = FxHashSet::default(); for par in named_generics.iter() { if let GenericParamKind::Lifetime { .. } = par.kind { if par.bounds.is_empty() { @@ -263,7 +275,7 @@ fn lts_from_bounds<'a, T: Iterator>(mut vec: Vec, bo /// Number of unique lifetimes in the given vector. fn unique_lifetimes(lts: &[RefLt]) -> usize { - lts.iter().collect::>().len() + lts.iter().collect::>().len() } /// A visitor usable for `rustc_front::visit::walk_ty()`. @@ -310,8 +322,9 @@ fn collect_anonymous_lifetimes(&mut self, qpath: &QPath, ty: &Ty) { && !last_path_segment.args.iter().any(|arg| match arg { GenericArg::Lifetime(_) => true, GenericArg::Type(_) => false, - }) { - let hir_id = self.cx.tcx.hir.node_to_hir_id(ty.id); + }) + { + let hir_id = self.cx.tcx.hir().node_to_hir_id(ty.id); match self.cx.tables.qpath_def(qpath, hir_id) { Def::TyAlias(def_id) | Def::Struct(def_id) => { let generics = self.cx.tcx.generics_of(def_id); @@ -344,24 +357,20 @@ fn visit_ty(&mut self, ty: &'tcx Ty) { self.record(&None); }, TyKind::Path(ref path) => { - if let QPath::Resolved(_, ref path) = *path { - if let Def::Existential(def_id) = path.def { - let node_id = self.cx.tcx.hir.as_local_node_id(def_id).unwrap(); - if let ItemKind::Existential(ref exist_ty) = self.cx.tcx.hir.expect_item(node_id).node { - for bound in &exist_ty.bounds { - if let GenericBound::Outlives(_) = *bound { - self.record(&None); - } - } - } else { - unreachable!() + self.collect_anonymous_lifetimes(path, ty); + }, + TyKind::Def(item, _) => { + if let ItemKind::Existential(ref exist_ty) = self.cx.tcx.hir().expect_item(item.id).node { + for bound in &exist_ty.bounds { + if let GenericBound::Outlives(_) = *bound { + self.record(&None); } - walk_ty(self, ty); - return; } + } else { + unreachable!() } - self.collect_anonymous_lifetimes(path, ty); - } + walk_ty(self, ty); + }, TyKind::TraitObject(ref bounds, ref lt) => { if !lt.is_elided() { self.abort = true; @@ -403,9 +412,11 @@ fn has_where_lifetimes<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, where_clause: & // and check that all lifetimes are allowed match visitor.into_vec() { None => return false, - Some(lts) => for lt in lts { - if !allowed_lts.contains(<) { - return true; + Some(lts) => { + for lt in lts { + if !allowed_lts.contains(<) { + return true; + } } }, } @@ -424,7 +435,7 @@ fn has_where_lifetimes<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, where_clause: & } struct LifetimeChecker { - map: HashMap, + map: FxHashMap, } impl<'tcx> Visitor<'tcx> for LifetimeChecker { @@ -449,7 +460,9 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { } fn report_extra_lifetimes<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, func: &'tcx FnDecl, generics: &'tcx Generics) { - let hs = generics.params.iter() + let hs = generics + .params + .iter() .filter_map(|par| match par.kind { GenericParamKind::Lifetime { .. } => Some((par.name.ident().name, par.span)), _ => None, @@ -461,7 +474,12 @@ fn report_extra_lifetimes<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, func: &'tcx walk_fn_decl(&mut checker, func); for &v in checker.map.values() { - span_lint(cx, EXTRA_UNUSED_LIFETIMES, v, "this lifetime isn't used in the function definition"); + span_lint( + cx, + EXTRA_UNUSED_LIFETIMES, + v, + "this lifetime isn't used in the function definition", + ); } }