mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-23 21:23:56 +00:00
Use diagnostic items for Vec
, VecDeque
and connected refactorings
This commit is contained in:
parent
6ce6b29527
commit
ecf85f4bdc
6 changed files with 30 additions and 42 deletions
|
@ -1,9 +1,10 @@
|
||||||
use clippy_utils::diagnostics::span_lint;
|
use clippy_utils::diagnostics::span_lint;
|
||||||
use clippy_utils::ty::{implements_trait, match_type};
|
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
||||||
use clippy_utils::{get_trait_def_id, higher, is_qpath_def_path, paths};
|
use clippy_utils::{get_trait_def_id, higher, is_qpath_def_path, paths};
|
||||||
use rustc_hir::{BorrowKind, Expr, ExprKind};
|
use rustc_hir::{BorrowKind, Expr, ExprKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
/// **What it does:** Checks for iteration that is guaranteed to be infinite.
|
/// **What it does:** Checks for iteration that is guaranteed to be infinite.
|
||||||
|
@ -202,15 +203,15 @@ const COMPLETING_METHODS: [(&str, usize); 12] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
/// the paths of types that are known to be infinitely allocating
|
/// the paths of types that are known to be infinitely allocating
|
||||||
const INFINITE_COLLECTORS: [&[&str]; 8] = [
|
const INFINITE_COLLECTORS: &[Symbol] = &[
|
||||||
&paths::BINARY_HEAP,
|
sym::BinaryHeap,
|
||||||
&paths::BTREEMAP,
|
sym::BTreeMap,
|
||||||
&paths::BTREESET,
|
sym::BTreeSet,
|
||||||
&paths::HASHMAP,
|
sym::hashmap_type,
|
||||||
&paths::HASHSET,
|
sym::hashset_type,
|
||||||
&paths::LINKED_LIST,
|
sym::LinkedList,
|
||||||
&paths::VEC,
|
sym::vec_type,
|
||||||
&paths::VEC_DEQUE,
|
sym::vecdeque_type,
|
||||||
];
|
];
|
||||||
|
|
||||||
fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
|
fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
|
||||||
|
@ -235,7 +236,10 @@ fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
|
||||||
}
|
}
|
||||||
} else if method.ident.name == sym!(collect) {
|
} else if method.ident.name == sym!(collect) {
|
||||||
let ty = cx.typeck_results().expr_ty(expr);
|
let ty = cx.typeck_results().expr_ty(expr);
|
||||||
if INFINITE_COLLECTORS.iter().any(|path| match_type(cx, ty, path)) {
|
if INFINITE_COLLECTORS
|
||||||
|
.iter()
|
||||||
|
.any(|diag_item| is_type_diagnostic_item(cx, ty, *diag_item))
|
||||||
|
{
|
||||||
return is_infinite(cx, &args[0]);
|
return is_infinite(cx, &args[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ fn get_pointee_ty_and_count_expr(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -
|
||||||
const FUNCTIONS: [&[&str]; 8] = [
|
const FUNCTIONS: [&[&str]; 8] = [
|
||||||
&paths::PTR_COPY_NONOVERLAPPING,
|
&paths::PTR_COPY_NONOVERLAPPING,
|
||||||
&paths::PTR_COPY,
|
&paths::PTR_COPY,
|
||||||
&paths::WRITE_BYTES,
|
&paths::PTR_WRITE_BYTES,
|
||||||
&paths::PTR_SWAP_NONOVERLAPPING,
|
&paths::PTR_SWAP_NONOVERLAPPING,
|
||||||
&paths::PTR_SLICE_FROM_RAW_PARTS,
|
&paths::PTR_SLICE_FROM_RAW_PARTS,
|
||||||
&paths::PTR_SLICE_FROM_RAW_PARTS_MUT,
|
&paths::PTR_SLICE_FROM_RAW_PARTS_MUT,
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
use super::utils::is_layout_incompatible;
|
use super::utils::is_layout_incompatible;
|
||||||
use super::UNSOUND_COLLECTION_TRANSMUTE;
|
use super::UNSOUND_COLLECTION_TRANSMUTE;
|
||||||
use clippy_utils::diagnostics::span_lint;
|
use clippy_utils::diagnostics::span_lint;
|
||||||
use clippy_utils::{match_def_path, paths};
|
use clippy_utils::match_any_diagnostic_items;
|
||||||
use rustc_hir::Expr;
|
use rustc_hir::Expr;
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
|
|
||||||
// used to check for UNSOUND_COLLECTION_TRANSMUTE
|
// used to check for UNSOUND_COLLECTION_TRANSMUTE
|
||||||
static COLLECTIONS: &[&[&str]] = &[
|
static COLLECTIONS: &[Symbol] = &[
|
||||||
&paths::VEC,
|
sym::vec_type,
|
||||||
&paths::VEC_DEQUE,
|
sym::vecdeque_type,
|
||||||
&paths::BINARY_HEAP,
|
sym::BinaryHeap,
|
||||||
&paths::BTREESET,
|
sym::BTreeSet,
|
||||||
&paths::BTREEMAP,
|
sym::BTreeMap,
|
||||||
&paths::HASHSET,
|
sym::hashset_type,
|
||||||
&paths::HASHMAP,
|
sym::hashmap_type,
|
||||||
];
|
];
|
||||||
|
|
||||||
/// Checks for `unsound_collection_transmute` lint.
|
/// Checks for `unsound_collection_transmute` lint.
|
||||||
|
@ -22,7 +23,7 @@ static COLLECTIONS: &[&[&str]] = &[
|
||||||
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool {
|
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool {
|
||||||
match (&from_ty.kind(), &to_ty.kind()) {
|
match (&from_ty.kind(), &to_ty.kind()) {
|
||||||
(ty::Adt(from_adt, from_substs), ty::Adt(to_adt, to_substs)) => {
|
(ty::Adt(from_adt, from_substs), ty::Adt(to_adt, to_substs)) => {
|
||||||
if from_adt.did != to_adt.did || !COLLECTIONS.iter().any(|path| match_def_path(cx, to_adt.did, path)) {
|
if from_adt.did != to_adt.did || match_any_diagnostic_items(cx, to_adt.did, COLLECTIONS).is_none() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if from_substs
|
if from_substs
|
||||||
|
|
|
@ -21,17 +21,11 @@ pub const ASMUT_TRAIT: [&str; 3] = ["core", "convert", "AsMut"];
|
||||||
pub const ASREF_TRAIT: [&str; 3] = ["core", "convert", "AsRef"];
|
pub const ASREF_TRAIT: [&str; 3] = ["core", "convert", "AsRef"];
|
||||||
pub(super) const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"];
|
pub(super) const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"];
|
||||||
pub(super) const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"];
|
pub(super) const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"];
|
||||||
/// Preferably use the diagnostic item `sym::BinaryHeap` where possible
|
|
||||||
pub const BINARY_HEAP: [&str; 4] = ["alloc", "collections", "binary_heap", "BinaryHeap"];
|
|
||||||
/// Preferably use the diagnostic item `sym::Borrow` where possible
|
/// Preferably use the diagnostic item `sym::Borrow` where possible
|
||||||
pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"];
|
pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"];
|
||||||
/// Preferably use the diagnostic item `sym::BTreeMap` where possible
|
|
||||||
pub const BTREEMAP: [&str; 5] = ["alloc", "collections", "btree", "map", "BTreeMap"];
|
|
||||||
pub const BTREEMAP_CONTAINS_KEY: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "contains_key"];
|
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_ENTRY: [&str; 6] = ["alloc", "collections", "btree", "map", "entry", "Entry"];
|
||||||
pub const BTREEMAP_INSERT: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "insert"];
|
pub const BTREEMAP_INSERT: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "insert"];
|
||||||
/// Preferably use the diagnostic item `sym::BTreeSet` where possible
|
|
||||||
pub const BTREESET: [&str; 5] = ["alloc", "collections", "btree", "set", "BTreeSet"];
|
|
||||||
pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"];
|
pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"];
|
||||||
pub const CMP_MAX: [&str; 3] = ["core", "cmp", "max"];
|
pub const CMP_MAX: [&str; 3] = ["core", "cmp", "max"];
|
||||||
pub const CMP_MIN: [&str; 3] = ["core", "cmp", "min"];
|
pub const CMP_MIN: [&str; 3] = ["core", "cmp", "min"];
|
||||||
|
@ -59,13 +53,9 @@ pub const FROM_ITERATOR_METHOD: [&str; 6] = ["core", "iter", "traits", "collect"
|
||||||
pub const FROM_STR_METHOD: [&str; 5] = ["core", "str", "traits", "FromStr", "from_str"];
|
pub const FROM_STR_METHOD: [&str; 5] = ["core", "str", "traits", "FromStr", "from_str"];
|
||||||
pub const FUTURE_FROM_GENERATOR: [&str; 3] = ["core", "future", "from_generator"];
|
pub const FUTURE_FROM_GENERATOR: [&str; 3] = ["core", "future", "from_generator"];
|
||||||
pub const HASH: [&str; 3] = ["core", "hash", "Hash"];
|
pub const HASH: [&str; 3] = ["core", "hash", "Hash"];
|
||||||
/// Preferably use the diagnostic item `sym::hashmap_type` where possible
|
|
||||||
pub const HASHMAP: [&str; 5] = ["std", "collections", "hash", "map", "HashMap"];
|
|
||||||
pub const HASHMAP_CONTAINS_KEY: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "contains_key"];
|
pub const HASHMAP_CONTAINS_KEY: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "contains_key"];
|
||||||
pub const HASHMAP_ENTRY: [&str; 5] = ["std", "collections", "hash", "map", "Entry"];
|
pub const HASHMAP_ENTRY: [&str; 5] = ["std", "collections", "hash", "map", "Entry"];
|
||||||
pub const HASHMAP_INSERT: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "insert"];
|
pub const HASHMAP_INSERT: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "insert"];
|
||||||
/// Preferably use the diagnostic item `sym::hashset_type` where possible
|
|
||||||
pub const HASHSET: [&str; 5] = ["std", "collections", "hash", "set", "HashSet"];
|
|
||||||
#[cfg(feature = "internal-lints")]
|
#[cfg(feature = "internal-lints")]
|
||||||
pub const IDENT: [&str; 3] = ["rustc_span", "symbol", "Ident"];
|
pub const IDENT: [&str; 3] = ["rustc_span", "symbol", "Ident"];
|
||||||
#[cfg(feature = "internal-lints")]
|
#[cfg(feature = "internal-lints")]
|
||||||
|
@ -83,8 +73,6 @@ pub const KW_MODULE: [&str; 3] = ["rustc_span", "symbol", "kw"];
|
||||||
#[cfg(feature = "internal-lints")]
|
#[cfg(feature = "internal-lints")]
|
||||||
pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"];
|
pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"];
|
||||||
pub const LIBC_STRLEN: [&str; 2] = ["libc", "strlen"];
|
pub const LIBC_STRLEN: [&str; 2] = ["libc", "strlen"];
|
||||||
/// Preferably use the diagnostic item `sym::LinkedList` where possible
|
|
||||||
pub const LINKED_LIST: [&str; 4] = ["alloc", "collections", "linked_list", "LinkedList"];
|
|
||||||
#[cfg(any(feature = "internal-lints", feature = "metadata-collector-lint"))]
|
#[cfg(any(feature = "internal-lints", feature = "metadata-collector-lint"))]
|
||||||
pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"];
|
pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"];
|
||||||
pub const MEM_DISCRIMINANT: [&str; 3] = ["core", "mem", "discriminant"];
|
pub const MEM_DISCRIMINANT: [&str; 3] = ["core", "mem", "discriminant"];
|
||||||
|
@ -182,14 +170,10 @@ pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"]
|
||||||
pub const TO_OWNED_METHOD: [&str; 4] = ["alloc", "borrow", "ToOwned", "to_owned"];
|
pub const TO_OWNED_METHOD: [&str; 4] = ["alloc", "borrow", "ToOwned", "to_owned"];
|
||||||
pub const TO_STRING_METHOD: [&str; 4] = ["alloc", "string", "ToString", "to_string"];
|
pub const TO_STRING_METHOD: [&str; 4] = ["alloc", "string", "ToString", "to_string"];
|
||||||
pub const TRY_FROM: [&str; 4] = ["core", "convert", "TryFrom", "try_from"];
|
pub const TRY_FROM: [&str; 4] = ["core", "convert", "TryFrom", "try_from"];
|
||||||
|
|
||||||
pub const VEC: [&str; 3] = ["alloc", "vec", "Vec"];
|
|
||||||
pub const VEC_AS_MUT_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_mut_slice"];
|
pub const VEC_AS_MUT_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_mut_slice"];
|
||||||
pub const VEC_AS_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_slice"];
|
pub const VEC_AS_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_slice"];
|
||||||
pub const VEC_DEQUE: [&str; 4] = ["alloc", "collections", "vec_deque", "VecDeque"];
|
|
||||||
pub const VEC_FROM_ELEM: [&str; 3] = ["alloc", "vec", "from_elem"];
|
pub const VEC_FROM_ELEM: [&str; 3] = ["alloc", "vec", "from_elem"];
|
||||||
pub const VEC_NEW: [&str; 4] = ["alloc", "vec", "Vec", "new"];
|
pub const VEC_NEW: [&str; 4] = ["alloc", "vec", "Vec", "new"];
|
||||||
pub const VEC_RESIZE: [&str; 4] = ["alloc", "vec", "Vec", "resize"];
|
pub const VEC_RESIZE: [&str; 4] = ["alloc", "vec", "Vec", "resize"];
|
||||||
pub const WEAK_ARC: [&str; 3] = ["alloc", "sync", "Weak"];
|
pub const WEAK_ARC: [&str; 3] = ["alloc", "sync", "Weak"];
|
||||||
pub const WEAK_RC: [&str; 3] = ["alloc", "rc", "Weak"];
|
pub const WEAK_RC: [&str; 3] = ["alloc", "rc", "Weak"];
|
||||||
pub const WRITE_BYTES: [&str; 3] = ["core", "intrinsics", "write_bytes"];
|
|
||||||
|
|
|
@ -27,7 +27,6 @@ impl<'tcx> LateLintPass<'tcx> for Pass {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr) {
|
||||||
let ty = cx.typeck_results().expr_ty(expr);
|
let ty = cx.typeck_results().expr_ty(expr);
|
||||||
|
|
||||||
let _ = match_type(cx, ty, &paths::VEC); // FIXME: Doesn't lint external paths
|
|
||||||
let _ = match_type(cx, ty, &OPTION);
|
let _ = match_type(cx, ty, &OPTION);
|
||||||
let _ = match_type(cx, ty, &["core", "result", "Result"]);
|
let _ = match_type(cx, ty, &["core", "result", "Result"]);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
|
error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
|
||||||
--> $DIR/match_type_on_diag_item.rs:31:17
|
--> $DIR/match_type_on_diag_item.rs:30:17
|
||||||
|
|
|
|
||||||
LL | let _ = match_type(cx, ty, &OPTION);
|
LL | let _ = match_type(cx, ty, &OPTION);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::option_type)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::option_type)`
|
||||||
|
@ -12,13 +12,13 @@ LL | #![deny(clippy::internal)]
|
||||||
= note: `#[deny(clippy::match_type_on_diagnostic_item)]` implied by `#[deny(clippy::internal)]`
|
= note: `#[deny(clippy::match_type_on_diagnostic_item)]` implied by `#[deny(clippy::internal)]`
|
||||||
|
|
||||||
error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
|
error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
|
||||||
--> $DIR/match_type_on_diag_item.rs:32:17
|
--> $DIR/match_type_on_diag_item.rs:31:17
|
||||||
|
|
|
|
||||||
LL | let _ = match_type(cx, ty, &["core", "result", "Result"]);
|
LL | let _ = match_type(cx, ty, &["core", "result", "Result"]);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::result_type)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::result_type)`
|
||||||
|
|
||||||
error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
|
error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
|
||||||
--> $DIR/match_type_on_diag_item.rs:35:17
|
--> $DIR/match_type_on_diag_item.rs:34:17
|
||||||
|
|
|
|
||||||
LL | let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
|
LL | let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::Rc)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::Rc)`
|
||||||
|
|
Loading…
Reference in a new issue