Use diagnostic items for Vec
, VecDeque
and connected refactorings
This commit is contained in:
parent
6ce6b29527
commit
ecf85f4bdc
@ -1,9 +1,10 @@
|
||||
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 rustc_hir::{BorrowKind, Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for iteration that is guaranteed to be infinite.
|
||||
@ -202,15 +203,15 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
|
||||
];
|
||||
|
||||
/// the paths of types that are known to be infinitely allocating
|
||||
const INFINITE_COLLECTORS: [&[&str]; 8] = [
|
||||
&paths::BINARY_HEAP,
|
||||
&paths::BTREEMAP,
|
||||
&paths::BTREESET,
|
||||
&paths::HASHMAP,
|
||||
&paths::HASHSET,
|
||||
&paths::LINKED_LIST,
|
||||
&paths::VEC,
|
||||
&paths::VEC_DEQUE,
|
||||
const INFINITE_COLLECTORS: &[Symbol] = &[
|
||||
sym::BinaryHeap,
|
||||
sym::BTreeMap,
|
||||
sym::BTreeSet,
|
||||
sym::hashmap_type,
|
||||
sym::hashset_type,
|
||||
sym::LinkedList,
|
||||
sym::vec_type,
|
||||
sym::vecdeque_type,
|
||||
];
|
||||
|
||||
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) {
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ fn get_pointee_ty_and_count_expr(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -
|
||||
const FUNCTIONS: [&[&str]; 8] = [
|
||||
&paths::PTR_COPY_NONOVERLAPPING,
|
||||
&paths::PTR_COPY,
|
||||
&paths::WRITE_BYTES,
|
||||
&paths::PTR_WRITE_BYTES,
|
||||
&paths::PTR_SWAP_NONOVERLAPPING,
|
||||
&paths::PTR_SLICE_FROM_RAW_PARTS,
|
||||
&paths::PTR_SLICE_FROM_RAW_PARTS_MUT,
|
||||
|
@ -1,20 +1,21 @@
|
||||
use super::utils::is_layout_incompatible;
|
||||
use super::UNSOUND_COLLECTION_TRANSMUTE;
|
||||
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_lint::LateContext;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
|
||||
// used to check for UNSOUND_COLLECTION_TRANSMUTE
|
||||
static COLLECTIONS: &[&[&str]] = &[
|
||||
&paths::VEC,
|
||||
&paths::VEC_DEQUE,
|
||||
&paths::BINARY_HEAP,
|
||||
&paths::BTREESET,
|
||||
&paths::BTREEMAP,
|
||||
&paths::HASHSET,
|
||||
&paths::HASHMAP,
|
||||
static COLLECTIONS: &[Symbol] = &[
|
||||
sym::vec_type,
|
||||
sym::vecdeque_type,
|
||||
sym::BinaryHeap,
|
||||
sym::BTreeSet,
|
||||
sym::BTreeMap,
|
||||
sym::hashset_type,
|
||||
sym::hashmap_type,
|
||||
];
|
||||
|
||||
/// Checks for `unsound_collection_transmute` lint.
|
||||
@ -22,7 +23,7 @@
|
||||
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()) {
|
||||
(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;
|
||||
}
|
||||
if from_substs
|
||||
|
@ -21,17 +21,11 @@
|
||||
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_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
|
||||
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_ENTRY: [&str; 6] = ["alloc", "collections", "btree", "map", "entry", "Entry"];
|
||||
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 CMP_MAX: [&str; 3] = ["core", "cmp", "max"];
|
||||
pub const CMP_MIN: [&str; 3] = ["core", "cmp", "min"];
|
||||
@ -59,13 +53,9 @@
|
||||
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 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_ENTRY: [&str; 5] = ["std", "collections", "hash", "map", "Entry"];
|
||||
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")]
|
||||
pub const IDENT: [&str; 3] = ["rustc_span", "symbol", "Ident"];
|
||||
#[cfg(feature = "internal-lints")]
|
||||
@ -83,8 +73,6 @@
|
||||
#[cfg(feature = "internal-lints")]
|
||||
pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"];
|
||||
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"))]
|
||||
pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"];
|
||||
pub const MEM_DISCRIMINANT: [&str; 3] = ["core", "mem", "discriminant"];
|
||||
@ -182,14 +170,10 @@
|
||||
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 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_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_NEW: [&str; 4] = ["alloc", "vec", "Vec", "new"];
|
||||
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"];
|
||||
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) {
|
||||
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, &["core", "result", "Result"]);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
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);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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)]`
|
||||
|
||||
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"]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::Rc)`
|
||||
|
Loading…
Reference in New Issue
Block a user