use crate::utils::{
- attrs::is_proc_macro, is_must_use_ty, iter_input_pats, match_def_path, must_use_attr, 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,
+ attr_by_name, attrs::is_proc_macro, is_must_use_ty, is_trait_impl_item, iter_input_pats, match_def_path,
+ must_use_attr, qpath_res, return_ty, snippet, snippet_opt, span_lint, span_lint_and_help, span_lint_and_then,
+ trait_ref_of_method, type_is_unsafe_function,
};
-use matches::matches;
-use rustc::hir::{self, def::Res, def_id::DefId, intravisit};
-use rustc::impl_lint_pass;
-use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintContext, LintPass};
+use rustc::hir::map::Map;
+use rustc::lint::in_external_macro;
use rustc::ty::{self, Ty};
+use rustc_ast::ast::Attribute;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
-use rustc_session::declare_tool_lint;
+use rustc_hir as hir;
+use rustc_hir::intravisit;
+use rustc_hir::{def::Res, def_id::DefId};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::source_map::Span;
use rustc_target::spec::abi::Abi;
-use syntax::ast::Attribute;
-use syntax::source_map::Span;
declare_clippy_lint! {
/// **What it does:** Checks for functions with too many parameters.
&mut self,
cx: &LateContext<'a, 'tcx>,
kind: intravisit::FnKind<'tcx>,
- decl: &'tcx hir::FnDecl,
+ decl: &'tcx hir::FnDecl<'_>,
body: &'tcx hir::Body<'_>,
span: Span,
hir_id: hir::HirId,
) {
- let is_impl = if let Some(hir::Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) {
- matches!(item.kind, hir::ItemKind::Impl(_, _, _, _, Some(_), _, _))
- } else {
- false
- };
-
let unsafety = match kind {
- hir::intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _, _) => unsafety,
- hir::intravisit::FnKind::Method(_, sig, _, _) => sig.header.unsafety,
- hir::intravisit::FnKind::Closure(_) => return,
+ intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _, _) => unsafety,
+ intravisit::FnKind::Method(_, sig, _, _) => sig.header.unsafety,
+ intravisit::FnKind::Closure(_) => return,
};
// don't warn for implementations, it's not their fault
- if !is_impl {
+ if !is_trait_impl_item(cx, hir_id) {
// don't lint extern functions decls, it's not their fault either
match kind {
- hir::intravisit::FnKind::Method(
+ intravisit::FnKind::Method(
_,
&hir::FnSig {
header: hir::FnHeader { abi: Abi::Rust, .. },
_,
_,
)
- | hir::intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _, _) => {
+ | intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _, _) => {
self.check_arg_number(cx, decl, span.with_hi(decl.output.span().hi()))
},
_ => {},
check_needless_must_use(cx, &sig.decl, item.hir_id, item.span, fn_header_span, attr);
return;
}
- if cx.access_levels.is_exported(item.hir_id) && !is_proc_macro(&item.attrs) {
+ if cx.access_levels.is_exported(item.hir_id)
+ && !is_proc_macro(&item.attrs)
+ && attr_by_name(&item.attrs, "no_mangle").is_none()
+ {
check_must_use_candidate(
cx,
&sig.decl,
}
fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::TraitItem<'_>) {
- if let hir::TraitItemKind::Method(ref sig, ref eid) = item.kind {
+ if let hir::TraitItemKind::Fn(ref sig, ref eid) = item.kind {
// don't lint extern functions decls, it's not their fault
if sig.header.abi == Abi::Rust {
self.check_arg_number(cx, &sig.decl, item.span.with_hi(sig.decl.output.span().hi()));
}
impl<'a, 'tcx> Functions {
- fn check_arg_number(self, cx: &LateContext<'_, '_>, decl: &hir::FnDecl, fn_span: Span) {
+ fn check_arg_number(self, cx: &LateContext<'_, '_>, decl: &hir::FnDecl<'_>, fn_span: Span) {
let args = decl.inputs.len() as u64;
if args > self.threshold {
span_lint(
fn check_raw_ptr(
cx: &LateContext<'a, 'tcx>,
unsafety: hir::Unsafety,
- decl: &'tcx hir::FnDecl,
+ decl: &'tcx hir::FnDecl<'_>,
body: &'tcx hir::Body<'_>,
hir_id: hir::HirId,
) {
tables,
};
- hir::intravisit::walk_expr(&mut v, expr);
+ intravisit::walk_expr(&mut v, expr);
}
}
}
fn check_needless_must_use(
cx: &LateContext<'_, '_>,
- decl: &hir::FnDecl,
+ decl: &hir::FnDecl<'_>,
item_id: hir::HirId,
item_span: Span,
fn_header_span: Span,
},
);
} else if !attr.is_value_str() && is_must_use_ty(cx, return_ty(cx, item_id)) {
- span_help_and_lint(
+ span_lint_and_help(
cx,
DOUBLE_MUST_USE,
fn_header_span,
fn check_must_use_candidate<'a, 'tcx>(
cx: &LateContext<'a, 'tcx>,
- decl: &'tcx hir::FnDecl,
+ decl: &'tcx hir::FnDecl<'_>,
body: &'tcx hir::Body<'_>,
item_span: Span,
item_id: hir::HirId,
});
}
-fn returns_unit(decl: &hir::FnDecl) -> bool {
+fn returns_unit(decl: &hir::FnDecl<'_>) -> bool {
match decl.output {
- hir::FunctionRetTy::DefaultReturn(_) => true,
- hir::FunctionRetTy::Return(ref ty) => match ty.kind {
+ hir::FnRetTy::DefaultReturn(_) => true,
+ hir::FnRetTy::Return(ref ty) => match ty.kind {
hir::TyKind::Tup(ref tys) => tys.is_empty(),
hir::TyKind::Never => true,
_ => false,
body.params.iter().any(|param| is_mutable_pat(cx, ¶m.pat, &mut tys))
}
-fn is_mutable_pat(cx: &LateContext<'_, '_>, pat: &hir::Pat, tys: &mut FxHashSet<DefId>) -> bool {
+fn is_mutable_pat(cx: &LateContext<'_, '_>, pat: &hir::Pat<'_>, tys: &mut FxHashSet<DefId>) -> bool {
if let hir::PatKind::Wild = pat.kind {
return false; // ignore `_` patterns
}
static KNOWN_WRAPPER_TYS: &[&[&str]] = &[&["alloc", "rc", "Rc"], &["std", "sync", "Arc"]];
fn is_mutable_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>, span: Span, tys: &mut FxHashSet<DefId>) -> bool {
- use ty::TyKind::*;
match ty.kind {
// primitive types are never mutable
- Bool | Char | Int(_) | Uint(_) | Float(_) | Str => false,
- Adt(ref adt, ref substs) => {
+ ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false,
+ ty::Adt(ref adt, ref substs) => {
tys.insert(adt.did) && !ty.is_freeze(cx.tcx, cx.param_env, span)
|| KNOWN_WRAPPER_TYS.iter().any(|path| match_def_path(cx, adt.did, path))
&& substs.types().any(|ty| is_mutable_ty(cx, ty, span, tys))
},
- Tuple(ref substs) => substs.types().any(|ty| is_mutable_ty(cx, ty, span, tys)),
- Array(ty, _) | Slice(ty) => is_mutable_ty(cx, ty, span, tys),
- RawPtr(ty::TypeAndMut { ty, mutbl }) | Ref(_, ty, mutbl) => {
+ ty::Tuple(ref substs) => substs.types().any(|ty| is_mutable_ty(cx, ty, span, tys)),
+ ty::Array(ty, _) | ty::Slice(ty) => is_mutable_ty(cx, ty, span, tys),
+ ty::RawPtr(ty::TypeAndMut { ty, mutbl }) | ty::Ref(_, ty, mutbl) => {
mutbl == hir::Mutability::Mut || is_mutable_ty(cx, ty, span, tys)
},
// calling something constitutes a side effect, so return true on all callables
}
}
-fn raw_ptr_arg(arg: &hir::Param, ty: &hir::Ty) -> Option<hir::HirId> {
+fn raw_ptr_arg(arg: &hir::Param<'_>, ty: &hir::Ty<'_>) -> Option<hir::HirId> {
if let (&hir::PatKind::Binding(_, id, _, _), &hir::TyKind::Ptr(_)) = (&arg.pat.kind, &ty.kind) {
Some(id)
} else {
}
impl<'a, 'tcx> intravisit::Visitor<'tcx> for DerefVisitor<'a, 'tcx> {
- fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
+ type Map = Map<'tcx>;
+
+ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) {
match expr.kind {
- hir::ExprKind::Call(ref f, ref args) => {
+ hir::ExprKind::Call(ref f, args) => {
let ty = self.tables.expr_ty(f);
if type_is_unsafe_function(self.cx, ty) {
}
}
},
- hir::ExprKind::MethodCall(_, _, ref args) => {
+ hir::ExprKind::MethodCall(_, _, args) => {
let def_id = self.tables.type_dependent_def_id(expr.hir_id).unwrap();
let base_type = self.cx.tcx.type_of(def_id);
}
}
},
- hir::ExprKind::Unary(hir::UnDeref, ref ptr) => self.check_arg(ptr),
+ hir::ExprKind::Unary(hir::UnOp::UnDeref, ref ptr) => self.check_arg(ptr),
_ => (),
}
intravisit::walk_expr(self, expr);
}
- fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> {
+ fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
intravisit::NestedVisitorMap::None
}
}
impl<'a, 'tcx> DerefVisitor<'a, 'tcx> {
- fn check_arg(&self, ptr: &hir::Expr) {
+ fn check_arg(&self, ptr: &hir::Expr<'_>) {
if let hir::ExprKind::Path(ref qpath) = ptr.kind {
if let Res::Local(id) = qpath_res(self.cx, qpath, ptr.hir_id) {
if self.ptrs.contains(&id) {
}
impl<'a, 'tcx> intravisit::Visitor<'tcx> for StaticMutVisitor<'a, 'tcx> {
- fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
- use hir::ExprKind::*;
+ type Map = Map<'tcx>;
+
+ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) {
+ use hir::ExprKind::{AddrOf, Assign, AssignOp, Call, MethodCall};
if self.mutates_static {
return;
}
match expr.kind {
- Call(_, ref args) | MethodCall(_, _, ref args) => {
+ Call(_, args) | MethodCall(_, _, args) => {
let mut tys = FxHashSet::default();
for arg in args {
let def_id = arg.hir_id.owner_def_id();
tys.clear();
}
},
- Assign(ref target, _) | AssignOp(_, ref target, _) | AddrOf(_, hir::Mutability::Mut, ref target) => {
+ Assign(ref target, ..) | AssignOp(_, ref target, _) | AddrOf(_, hir::Mutability::Mut, ref target) => {
self.mutates_static |= is_mutated_static(self.cx, target)
},
_ => {},
}
}
- fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> {
+ fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
intravisit::NestedVisitorMap::None
}
}
-fn is_mutated_static(cx: &LateContext<'_, '_>, e: &hir::Expr) -> bool {
- use hir::ExprKind::*;
+fn is_mutated_static(cx: &LateContext<'_, '_>, e: &hir::Expr<'_>) -> bool {
+ use hir::ExprKind::{Field, Index, Path};
match e.kind {
Path(ref qpath) => {