Replace some more paths with diagnostic items

This commit is contained in:
Alex Macleod 2022-02-25 15:38:06 +00:00
parent 7b2896a8fc
commit 2955db493e
10 changed files with 63 additions and 86 deletions

View File

@ -1,11 +1,11 @@
use clippy_utils::diagnostics::span_lint_and_note;
use clippy_utils::ty::is_copy;
use clippy_utils::{match_def_path, paths};
use if_chain::if_chain;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
declare_clippy_lint! {
/// ### What it does
@ -128,14 +128,16 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let arg_ty = cx.typeck_results().expr_ty(arg);
if let ty::Ref(..) = arg_ty.kind() {
if match_def_path(cx, def_id, &paths::DROP) {
lint = DROP_REF;
msg = DROP_REF_SUMMARY.to_string();
} else if match_def_path(cx, def_id, &paths::MEM_FORGET) {
lint = FORGET_REF;
msg = FORGET_REF_SUMMARY.to_string();
} else {
return;
match cx.tcx.get_diagnostic_name(def_id) {
Some(sym::mem_drop) => {
lint = DROP_REF;
msg = DROP_REF_SUMMARY.to_string();
},
Some(sym::mem_forget) => {
lint = FORGET_REF;
msg = FORGET_REF_SUMMARY.to_string();
},
_ => return,
}
span_lint_and_note(cx,
lint,
@ -144,14 +146,16 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
Some(arg.span),
&format!("argument has type `{}`", arg_ty));
} else if is_copy(cx, arg_ty) {
if match_def_path(cx, def_id, &paths::DROP) {
lint = DROP_COPY;
msg = DROP_COPY_SUMMARY.to_string();
} else if match_def_path(cx, def_id, &paths::MEM_FORGET) {
lint = FORGET_COPY;
msg = FORGET_COPY_SUMMARY.to_string();
} else {
return;
match cx.tcx.get_diagnostic_name(def_id) {
Some(sym::mem_drop) => {
lint = DROP_COPY;
msg = DROP_COPY_SUMMARY.to_string();
},
Some(sym::mem_forget) => {
lint = FORGET_COPY;
msg = FORGET_COPY_SUMMARY.to_string();
},
_ => return,
}
span_lint_and_note(cx,
lint,

View File

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_opt;
use clippy_utils::{match_def_path, meets_msrv, msrvs, paths};
use clippy_utils::{meets_msrv, msrvs};
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind, GenericArg, QPath};
@ -8,6 +8,7 @@
use rustc_middle::ty::{self, Ty};
use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::sym;
declare_clippy_lint! {
/// ### What it does
@ -99,7 +100,7 @@ fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<
if let Some(GenericArg::Type(real_ty)) = args.args.get(0);
if let Some(def_id) = cx.qpath_res(count_func_qpath, count_func.hir_id).opt_def_id();
if match_def_path(cx, def_id, &paths::MEM_SIZE_OF);
if cx.tcx.is_diagnostic_item(sym::mem_size_of, def_id);
then {
cx.typeck_results().node_substs(count_func.hir_id).types().next().map(|resolved_ty| (real_ty, resolved_ty))
} else {

View File

@ -1,8 +1,8 @@
use clippy_utils::diagnostics::span_lint;
use clippy_utils::{match_def_path, paths};
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
declare_clippy_lint! {
/// ### What it does
@ -32,7 +32,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
if let ExprKind::Call(path_expr, [ref first_arg, ..]) = e.kind {
if let ExprKind::Path(ref qpath) = path_expr.kind {
if let Some(def_id) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id() {
if match_def_path(cx, def_id, &paths::MEM_FORGET) {
if cx.tcx.is_diagnostic_item(sym::mem_forget, def_id) {
let forgot_ty = cx.typeck_results().expr_ty(first_arg);
if forgot_ty.ty_adt_def().map_or(false, |def| def.has_dtor(cx.tcx)) {

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
use clippy_utils::source::{snippet, snippet_with_applicability};
use clippy_utils::ty::is_non_aggregate_primitive_type;
use clippy_utils::{is_default_equivalent, is_lang_ctor, match_def_path, meets_msrv, msrvs, paths};
use clippy_utils::{is_default_equivalent, is_lang_ctor, meets_msrv, msrvs};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::LangItem::OptionNone;
@ -249,7 +249,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if let ExprKind::Call(func, func_args) = expr.kind;
if let ExprKind::Path(ref func_qpath) = func.kind;
if let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id();
if match_def_path(cx, def_id, &paths::MEM_REPLACE);
if cx.tcx.is_diagnostic_item(sym::mem_replace, def_id);
if let [dest, src] = func_args;
then {
check_replace_option_with_none(cx, src, dest, expr.span);

View File

@ -1,8 +1,9 @@
use clippy_utils::diagnostics::span_lint;
use clippy_utils::{is_expr_path_def_path, paths, ty::is_uninit_value_valid_for_ty};
use clippy_utils::{is_expr_diagnostic_item, ty::is_uninit_value_valid_for_ty};
use if_chain::if_chain;
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_span::sym;
use super::UNINIT_ASSUMED_INIT;
@ -11,7 +12,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
if_chain! {
if let hir::ExprKind::Call(callee, args) = recv.kind;
if args.is_empty();
if is_expr_path_def_path(cx, callee, &paths::MEM_MAYBEUNINIT_UNINIT);
if is_expr_diagnostic_item(cx, callee, sym::maybe_uninit_uninit);
if !is_uninit_value_valid_for_ty(cx, cx.typeck_results().expr_ty_adjusted(expr));
then {
span_lint(

View File

@ -135,7 +135,7 @@ fn check_fn(
}
if let ty::Adt(def, _) = arg_ty.kind() {
if match_def_path(cx, def.did, &paths::MEM_MANUALLY_DROP) {
if def.is_manually_drop() {
continue;
}
}

View File

@ -9,6 +9,7 @@
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, Ty, TypeAndMut};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
declare_clippy_lint! {
/// ### What it does
@ -44,8 +45,7 @@ fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, inverted:
if !inverted;
if let ExprKind::Path(ref count_func_qpath) = count_func.kind;
if let Some(def_id) = cx.qpath_res(count_func_qpath, count_func.hir_id).opt_def_id();
if match_def_path(cx, def_id, &paths::MEM_SIZE_OF)
|| match_def_path(cx, def_id, &paths::MEM_SIZE_OF_VAL);
if matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::mem_size_of | sym::mem_size_of_val));
then {
cx.typeck_results().node_substs(count_func.hir_id).types().next()
} else {

View File

@ -1,9 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::path_res;
use clippy_utils::ty::is_type_lang_item;
use clippy_utils::{match_function_call, paths};
use rustc_hir::{lang_items, Expr};
use rustc_hir::{lang_items, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
declare_clippy_lint! {
/// ### What it does
@ -38,9 +39,12 @@
impl<'tcx> LateLintPass<'tcx> for UndroppedManuallyDrops {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if let Some([arg_0, ..]) = match_function_call(cx, expr, &paths::DROP) {
if_chain! {
if let ExprKind::Call(fun, [arg_0, ..]) = expr.kind;
if path_res(cx, fun).opt_def_id() == cx.tcx.get_diagnostic_item(sym::mem_drop);
let ty = cx.typeck_results().expr_ty(arg_0);
if is_type_lang_item(cx, ty, lang_items::LangItem::ManuallyDrop) {
if is_type_lang_item(cx, ty, lang_items::LangItem::ManuallyDrop);
then {
span_lint_and_help(
cx,
UNDROPPED_MANUALLY_DROPS,

View File

@ -1,7 +1,6 @@
#![allow(clippy::similar_names)] // `expr` and `expn`
use crate::visitors::expr_visitor_no_bodies;
use crate::{match_def_path, paths};
use arrayvec::ArrayVec;
use if_chain::if_chain;
@ -14,29 +13,31 @@
use rustc_span::{sym, ExpnData, ExpnId, ExpnKind, Span, Symbol};
use std::ops::ControlFlow;
const FORMAT_MACRO_PATHS: &[&[&str]] = &[
&paths::FORMAT_ARGS_MACRO,
&paths::ASSERT_EQ_MACRO,
&paths::ASSERT_MACRO,
&paths::ASSERT_NE_MACRO,
&paths::EPRINT_MACRO,
&paths::EPRINTLN_MACRO,
&paths::PRINT_MACRO,
&paths::PRINTLN_MACRO,
&paths::WRITE_MACRO,
&paths::WRITELN_MACRO,
const FORMAT_MACRO_DIAG_ITEMS: &[Symbol] = &[
sym::assert_eq_macro,
sym::assert_macro,
sym::assert_ne_macro,
sym::debug_assert_eq_macro,
sym::debug_assert_macro,
sym::debug_assert_ne_macro,
sym::eprint_macro,
sym::eprintln_macro,
sym::format_args_macro,
sym::format_macro,
sym::print_macro,
sym::println_macro,
sym::std_panic_macro,
sym::write_macro,
sym::writeln_macro,
];
const FORMAT_MACRO_DIAG_ITEMS: &[Symbol] = &[sym::format_macro, sym::std_panic_macro];
/// Returns true if a given Macro `DefId` is a format macro (e.g. `println!`)
pub fn is_format_macro(cx: &LateContext<'_>, macro_def_id: DefId) -> bool {
FORMAT_MACRO_PATHS
.iter()
.any(|path| match_def_path(cx, macro_def_id, path))
|| FORMAT_MACRO_DIAG_ITEMS
.iter()
.any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, macro_def_id))
if let Some(name) = cx.tcx.get_diagnostic_name(macro_def_id) {
FORMAT_MACRO_DIAG_ITEMS.contains(&name)
} else {
false
}
}
/// A macro call, like `vec![1, 2, 3]`.

View File

@ -16,44 +16,27 @@
#[cfg(feature = "internal")]
pub const DIAGNOSTIC_BUILDER: [&str; 3] = ["rustc_errors", "diagnostic_builder", "DiagnosticBuilder"];
pub const ARC_PTR_EQ: [&str; 4] = ["alloc", "sync", "Arc", "ptr_eq"];
#[allow(clippy::invalid_paths)] // `check_path` does not seem to work for macros
pub const ASSERT_EQ_MACRO: [&str; 3] = ["core", "macros", "assert_eq"];
#[allow(clippy::invalid_paths)] // `check_path` does not seem to work for macros
pub const ASSERT_MACRO: [&str; 4] = ["core", "macros", "builtin", "assert"];
#[allow(clippy::invalid_paths)] // `check_path` does not seem to work for macros
pub const ASSERT_NE_MACRO: [&str; 3] = ["core", "macros", "assert_ne"];
pub const ASMUT_TRAIT: [&str; 3] = ["core", "convert", "AsMut"];
pub const ASREF_TRAIT: [&str; 3] = ["core", "convert", "AsRef"];
/// Preferably use the diagnostic item `sym::Borrow` where possible
pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"];
pub const BORROW_MUT_TRAIT: [&str; 3] = ["core", "borrow", "BorrowMut"];
pub const BTREEMAP_CONTAINS_KEY: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "contains_key"];
pub const BTREEMAP_ENTRY: [&str; 6] = ["alloc", "collections", "btree", "map", "entry", "Entry"];
pub const BTREEMAP_INSERT: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "insert"];
pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"];
pub const COW: [&str; 3] = ["alloc", "borrow", "Cow"];
pub const CSTRING_AS_C_STR: [&str; 5] = ["std", "ffi", "c_str", "CString", "as_c_str"];
pub const DEBUG_TRAIT: [&str; 3] = ["core", "fmt", "Debug"];
pub const DEFAULT_TRAIT_METHOD: [&str; 4] = ["core", "default", "Default", "default"];
pub const DEREF_MUT_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "DerefMut", "deref_mut"];
/// Preferably use the diagnostic item `sym::deref_method` where possible
pub const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref", "deref"];
pub const DIR_BUILDER: [&str; 3] = ["std", "fs", "DirBuilder"];
pub const DISPLAY_TRAIT: [&str; 3] = ["core", "fmt", "Display"];
pub const DROP: [&str; 3] = ["core", "mem", "drop"];
#[cfg(feature = "internal")]
pub const EARLY_CONTEXT: [&str; 2] = ["rustc_lint", "EarlyContext"];
#[allow(clippy::invalid_paths)] // `check_path` does not seem to work for macros
pub const EPRINT_MACRO: [&str; 3] = ["std", "macros", "eprint"];
#[allow(clippy::invalid_paths)] // `check_path` does not seem to work for macros
pub const EPRINTLN_MACRO: [&str; 3] = ["std", "macros", "eprintln"];
pub const EXIT: [&str; 3] = ["std", "process", "exit"];
pub const F32_EPSILON: [&str; 4] = ["core", "f32", "<impl f32>", "EPSILON"];
pub const F64_EPSILON: [&str; 4] = ["core", "f64", "<impl f64>", "EPSILON"];
pub const FILE: [&str; 3] = ["std", "fs", "File"];
pub const FILE_TYPE: [&str; 3] = ["std", "fs", "FileType"];
#[allow(clippy::invalid_paths)] // `check_path` does not seem to work for macros
pub const FORMAT_ARGS_MACRO: [&str; 4] = ["core", "macros", "builtin", "format_args"];
pub const FROM_FROM: [&str; 4] = ["core", "convert", "From", "from"];
pub const FROM_ITERATOR_METHOD: [&str; 6] = ["core", "iter", "traits", "collect", "FromIterator", "from_iter"];
pub const FROM_STR_METHOD: [&str; 5] = ["core", "str", "traits", "FromStr", "from_str"];
@ -85,17 +68,8 @@
pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"];
#[cfg(feature = "internal")]
pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"];
pub const MEM_DISCRIMINANT: [&str; 3] = ["core", "mem", "discriminant"];
pub const MEM_FORGET: [&str; 3] = ["core", "mem", "forget"];
pub const MEM_MANUALLY_DROP: [&str; 4] = ["core", "mem", "manually_drop", "ManuallyDrop"];
pub const MEM_MAYBEUNINIT: [&str; 4] = ["core", "mem", "maybe_uninit", "MaybeUninit"];
pub const MEM_MAYBEUNINIT_UNINIT: [&str; 5] = ["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"];
pub const MEM_REPLACE: [&str; 3] = ["core", "mem", "replace"];
pub const MEM_SIZE_OF: [&str; 3] = ["core", "mem", "size_of"];
pub const MEM_SIZE_OF_VAL: [&str; 3] = ["core", "mem", "size_of_val"];
pub const MUTEX_GUARD: [&str; 4] = ["std", "sync", "mutex", "MutexGuard"];
pub const OPEN_OPTIONS: [&str; 3] = ["std", "fs", "OpenOptions"];
pub const OPS_MODULE: [&str; 2] = ["core", "ops"];
/// Preferably use the diagnostic item `sym::Option` where possible
pub const OPTION: [&str; 3] = ["core", "option", "Option"];
pub const OPTION_NONE: [&str; 4] = ["core", "option", "Option", "None"];
@ -116,10 +90,6 @@
pub const POLL: [&str; 4] = ["core", "task", "poll", "Poll"];
pub const POLL_PENDING: [&str; 5] = ["core", "task", "poll", "Poll", "Pending"];
pub const POLL_READY: [&str; 5] = ["core", "task", "poll", "Poll", "Ready"];
#[allow(clippy::invalid_paths)] // `check_path` does not seem to work for macros
pub const PRINT_MACRO: [&str; 3] = ["std", "macros", "print"];
#[allow(clippy::invalid_paths)] // `check_path` does not seem to work for macros
pub const PRINTLN_MACRO: [&str; 3] = ["std", "macros", "println"];
pub const PTR_COPY: [&str; 3] = ["core", "intrinsics", "copy"];
pub const PTR_COPY_NONOVERLAPPING: [&str; 3] = ["core", "intrinsics", "copy_nonoverlapping"];
pub const PTR_EQ: [&str; 3] = ["core", "ptr", "eq"];
@ -200,8 +170,4 @@
pub const VEC_RESIZE: [&str; 4] = ["alloc", "vec", "Vec", "resize"];
pub const WEAK_ARC: [&str; 3] = ["alloc", "sync", "Weak"];
pub const WEAK_RC: [&str; 3] = ["alloc", "rc", "Weak"];
#[allow(clippy::invalid_paths)] // `check_path` does not seem to work for macros
pub const WRITE_MACRO: [&str; 3] = ["core", "macros", "write"];
#[allow(clippy::invalid_paths)] // `check_path` does not seem to work for macros
pub const WRITELN_MACRO: [&str; 3] = ["core", "macros", "writeln"];
pub const PTR_NON_NULL: [&str; 4] = ["core", "ptr", "non_null", "NonNull"];