From 68ab3055efc17d6c57e7c9515acf76462d23062d Mon Sep 17 00:00:00 2001 From: Mikhail Babenko Date: Thu, 14 Nov 2019 02:42:00 +0300 Subject: [PATCH] move is_must_use_ty to utils --- clippy_lints/src/functions.rs | 45 +------------------------------- clippy_lints/src/utils/mod.rs | 48 ++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 45 deletions(-) diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs index f2ac83139d11..07a4333df0dd 100644 --- a/clippy_lints/src/functions.rs +++ b/clippy_lints/src/functions.rs @@ -1,6 +1,7 @@ use crate::utils::{ attrs::is_proc_macro, iter_input_pats, match_def_path, qpath_res, return_ty, snippet, snippet_opt, span_help_and_lint, span_lint, span_lint_and_then, trait_ref_of_method, type_is_unsafe_function, + must_use_attr, is_must_use_ty, }; use matches::matches; use rustc::hir::{self, def::Res, def_id::DefId, intravisit}; @@ -465,15 +466,6 @@ fn check_must_use_candidate<'a, 'tcx>( }); } -fn must_use_attr(attrs: &[Attribute]) -> Option<&Attribute> { - attrs.iter().find(|attr| { - attr.ident().map_or(false, |ident| { - let ident: &str = &ident.as_str(); - "must_use" == ident - }) - }) -} - fn returns_unit(decl: &hir::FnDecl) -> bool { match decl.output { hir::FunctionRetTy::DefaultReturn(_) => true, @@ -485,41 +477,6 @@ fn returns_unit(decl: &hir::FnDecl) -> bool { } } -fn is_must_use_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool { - use ty::TyKind::*; - match ty.kind { - Adt(ref adt, _) => must_use_attr(&cx.tcx.get_attrs(adt.did)).is_some(), - Foreign(ref did) => must_use_attr(&cx.tcx.get_attrs(*did)).is_some(), - Slice(ref ty) | Array(ref ty, _) | RawPtr(ty::TypeAndMut { ref ty, .. }) | Ref(_, ref ty, _) => { - // for the Array case we don't need to care for the len == 0 case - // because we don't want to lint functions returning empty arrays - is_must_use_ty(cx, *ty) - }, - Tuple(ref substs) => substs.types().any(|ty| is_must_use_ty(cx, ty)), - Opaque(ref def_id, _) => { - for (predicate, _) in cx.tcx.predicates_of(*def_id).predicates { - if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate { - if must_use_attr(&cx.tcx.get_attrs(poly_trait_predicate.skip_binder().trait_ref.def_id)).is_some() { - return true; - } - } - } - false - }, - Dynamic(binder, _) => { - for predicate in binder.skip_binder().iter() { - if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate { - if must_use_attr(&cx.tcx.get_attrs(trait_ref.def_id)).is_some() { - return true; - } - } - } - false - }, - _ => false, - } -} - fn has_mutable_arg(cx: &LateContext<'_, '_>, body: &hir::Body) -> bool { let mut tys = FxHashSet::default(); body.params.iter().any(|param| is_mutable_pat(cx, ¶m.pat, &mut tys)) diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index c75b61c6718c..eeb9696a34ab 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -41,7 +41,7 @@ use rustc::ty::{ }; use rustc_errors::Applicability; use smallvec::SmallVec; -use syntax::ast::{self, LitKind}; +use syntax::ast::{self, LitKind, Attribute}; use syntax::attr; use syntax::source_map::{Span, DUMMY_SP}; use syntax::symbol::{kw, Symbol}; @@ -1237,3 +1237,49 @@ pub fn parent_node_is_if_expr<'a, 'b>(expr: &Expr, cx: &LateContext<'a, 'b>) -> _ => false, } } + +pub fn must_use_attr(attrs: &[Attribute]) -> Option<&Attribute> { + attrs.iter().find(|attr| { + attr.ident().map_or(false, |ident| { + let ident: &str = &ident.as_str(); + "must_use" == ident + }) + }) +} + +// Returns whether the type has #[must_use] attribute +pub fn is_must_use_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool { + use ty::TyKind::*; + match ty.kind { + Adt(ref adt, _) => must_use_attr(&cx.tcx.get_attrs(adt.did)).is_some(), + Foreign(ref did) => must_use_attr(&cx.tcx.get_attrs(*did)).is_some(), + Slice(ref ty) | Array(ref ty, _) | RawPtr(ty::TypeAndMut { ref ty, .. }) | Ref(_, ref ty, _) => { + // for the Array case we don't need to care for the len == 0 case + // because we don't want to lint functions returning empty arrays + is_must_use_ty(cx, *ty) + }, + Tuple(ref substs) => substs.types().any(|ty| is_must_use_ty(cx, ty)), + Opaque(ref def_id, _) => { + for (predicate, _) in cx.tcx.predicates_of(*def_id).predicates { + if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate { + if must_use_attr(&cx.tcx.get_attrs(poly_trait_predicate.skip_binder().trait_ref.def_id)).is_some() { + return true; + } + } + } + false + }, + Dynamic(binder, _) => { + for predicate in binder.skip_binder().iter() { + if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate { + if must_use_attr(&cx.tcx.get_attrs(trait_ref.def_id)).is_some() { + return true; + } + } + } + false + }, + _ => false, + } +} +