Rollup merge of #116198 - Jarcho:diag_items, r=WaffleLapkin

Add more diagnostic items for clippy
This commit is contained in:
Guillaume Gomez 2023-10-06 13:18:34 +02:00 committed by GitHub
commit 3785fed021
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
75 changed files with 289 additions and 270 deletions

View File

@ -129,9 +129,11 @@ symbols! {
Alignment,
Any,
Arc,
ArcWeak,
Argument,
ArgumentMethods,
Arguments,
ArrayIntoIter,
AsMut,
AsRef,
AssertParamIsClone,
@ -164,6 +166,7 @@ symbols! {
Capture,
Center,
Clone,
Command,
ConstParamTy,
Context,
Continue,
@ -171,6 +174,7 @@ symbols! {
Count,
Cow,
Debug,
DebugStruct,
Decodable,
Decoder,
DecorateLint,
@ -194,6 +198,8 @@ symbols! {
From,
FromIterator,
FromResidual,
FsOpenOptions,
FsPermissions,
Future,
FutureOutput,
FxHashMap,
@ -207,16 +213,22 @@ symbols! {
Implied,
IndexOutput,
Input,
Instant,
Into,
IntoDiagnostic,
IntoFuture,
IntoIterator,
IoLines,
IoRead,
IoSeek,
IoWrite,
IpAddr,
IrTyKind,
Is,
ItemContext,
IterEmpty,
IterOnce,
IterPeekable,
Iterator,
IteratorItem,
Layout,
@ -227,6 +239,7 @@ symbols! {
Mutex,
MutexGuard,
N,
NonNull,
NonZeroI128,
NonZeroI16,
NonZeroI32,
@ -259,15 +272,19 @@ symbols! {
ProcMacro,
ProceduralMasqueradeDummyType,
Range,
RangeBounds,
RangeFrom,
RangeFull,
RangeInclusive,
RangeTo,
RangeToInclusive,
Rc,
RcWeak,
Ready,
Receiver,
RefCell,
RefCellRef,
RefCellRefMut,
Relaxed,
Release,
Result,
@ -284,6 +301,7 @@ symbols! {
Send,
SeqCst,
SliceIndex,
SliceIter,
Some,
String,
StructuralEq,
@ -561,6 +579,7 @@ symbols! {
constant,
constructor,
context,
convert_identity,
copy,
copy_closures,
copy_nonoverlapping,
@ -616,6 +635,7 @@ symbols! {
declare_lint_pass,
decode,
default_alloc_error_handler,
default_fn,
default_lib_allocator,
default_method_body_is_const,
default_type_parameter_fallback,
@ -628,6 +648,7 @@ symbols! {
deref,
deref_method,
deref_mut,
deref_mut_method,
deref_target,
derive,
derive_const,
@ -777,11 +798,14 @@ symbols! {
from_desugaring,
from_fn,
from_iter,
from_iter_fn,
from_output,
from_residual,
from_size_align_unchecked,
from_str_method,
from_usize,
from_yeet,
fs_create_dir,
fsub_fast,
fundamental,
future,
@ -868,6 +892,10 @@ symbols! {
into_iter,
intra_doc_pointers,
intrinsics,
intrinsics_unaligned_volatile_load,
intrinsics_unaligned_volatile_store,
io_stderr,
io_stdout,
irrefutable_let_patterns,
isa_attribute,
isize,
@ -962,6 +990,7 @@ symbols! {
mem_replace,
mem_size_of,
mem_size_of_val,
mem_swap,
mem_uninitialized,
mem_variant_count,
mem_zeroed,
@ -1091,6 +1120,7 @@ symbols! {
options,
or,
or_patterns,
ord_cmp_method,
other,
out,
overflow_checks,
@ -1171,6 +1201,7 @@ symbols! {
proc_macro_mod,
proc_macro_non_items,
proc_macro_path_invoc,
process_exit,
profiler_builtins,
profiler_runtime,
ptr,
@ -1178,6 +1209,10 @@ symbols! {
ptr_cast_const,
ptr_cast_mut,
ptr_const_is_null,
ptr_copy,
ptr_copy_nonoverlapping,
ptr_drop_in_place,
ptr_eq,
ptr_from_ref,
ptr_guaranteed_cmp,
ptr_is_null,
@ -1186,8 +1221,17 @@ symbols! {
ptr_null_mut,
ptr_offset_from,
ptr_offset_from_unsigned,
ptr_read,
ptr_read_unaligned,
ptr_read_volatile,
ptr_replace,
ptr_slice_from_raw_parts,
ptr_slice_from_raw_parts_mut,
ptr_swap,
ptr_swap_nonoverlapping,
ptr_unique,
ptr_write,
ptr_write_bytes,
ptr_write_unaligned,
ptr_write_volatile,
pub_macro_rules,
@ -1478,6 +1522,8 @@ symbols! {
sized,
skip,
slice,
slice_from_raw_parts,
slice_from_raw_parts_mut,
slice_len_fn,
slice_patterns,
slicing_syntax,
@ -1565,7 +1611,9 @@ symbols! {
thumb2,
thumb_mode: "thumb-mode",
tmm_reg,
to_owned_method,
to_string,
to_string_method,
to_vec,
todo_macro,
tool_attributes,
@ -1588,6 +1636,7 @@ symbols! {
try_blocks,
try_capture,
try_from,
try_from_fn,
try_into,
try_trait_v2,
tt,

View File

@ -55,6 +55,7 @@ pub trait ToOwned {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "cloning is often expensive and is not expected to have side effects"]
#[cfg_attr(not(test), rustc_diagnostic_item = "to_owned_method")]
fn to_owned(&self) -> Self::Owned;
/// Uses borrowed data to replace owned data, usually by cloning.

View File

@ -2701,6 +2701,7 @@ impl<T, I: iter::TrustedLen<Item = T>> ToRcSlice<T> for I {
///
/// [`upgrade`]: Weak::upgrade
#[stable(feature = "rc_weak", since = "1.4.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "RcWeak")]
pub struct Weak<
T: ?Sized,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,

View File

@ -2435,6 +2435,7 @@ pub trait ToString {
/// ```
#[rustc_conversion_suggestion]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "to_string_method")]
fn to_string(&self) -> String;
}

View File

@ -311,6 +311,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
///
/// [`upgrade`]: Weak::upgrade
#[stable(feature = "arc_weak", since = "1.4.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "ArcWeak")]
pub struct Weak<
T: ?Sized,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,

View File

@ -13,6 +13,7 @@ use crate::{
/// A by-value [array] iterator.
#[stable(feature = "array_value_iter", since = "1.51.0")]
#[rustc_insignificant_dtor]
#[rustc_diagnostic_item = "ArrayIntoIter"]
pub struct IntoIter<T, const N: usize> {
/// This is the array we are iterating over.
///

View File

@ -1423,6 +1423,7 @@ impl Clone for BorrowRef<'_> {
/// See the [module-level documentation](self) for more.
#[stable(feature = "rust1", since = "1.0.0")]
#[must_not_suspend = "holding a Ref across suspend points can cause BorrowErrors"]
#[rustc_diagnostic_item = "RefCellRef"]
pub struct Ref<'b, T: ?Sized + 'b> {
// NB: we use a pointer instead of `&'b T` to avoid `noalias` violations, because a
// `Ref` argument doesn't hold immutability for its whole scope, only until it drops.
@ -1804,6 +1805,7 @@ impl<'b> BorrowRefMut<'b> {
/// See the [module-level documentation](self) for more.
#[stable(feature = "rust1", since = "1.0.0")]
#[must_not_suspend = "holding a RefMut across suspend points can cause BorrowErrors"]
#[rustc_diagnostic_item = "RefCellRefMut"]
pub struct RefMut<'b, T: ?Sized + 'b> {
// NB: we use a pointer instead of `&'b mut T` to avoid `noalias` violations, because a
// `RefMut` argument doesn't hold exclusivity for its whole scope, only until it drops.

View File

@ -809,6 +809,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "ord_cmp_method"]
fn cmp(&self, other: &Self) -> Ordering;
/// Compares and returns the maximum of two values.

View File

@ -100,6 +100,7 @@ pub use num::FloatToInt;
#[stable(feature = "convert_id", since = "1.33.0")]
#[rustc_const_stable(feature = "const_identity", since = "1.33.0")]
#[inline(always)]
#[rustc_diagnostic_item = "convert_identity"]
pub const fn identity<T>(x: T) -> T {
x
}
@ -642,6 +643,7 @@ pub trait TryFrom<T>: Sized {
/// Performs the conversion.
#[stable(feature = "try_from", since = "1.34.0")]
#[rustc_diagnostic_item = "try_from_fn"]
fn try_from(value: T) -> Result<Self, Self::Error>;
}

View File

@ -130,6 +130,7 @@ pub trait Default: Sized {
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "default_fn"]
fn default() -> Self;
}

View File

@ -84,6 +84,7 @@ impl fmt::Write for PadAdapter<'_, '_> {
#[must_use = "must eventually call `finish()` on Debug builders"]
#[allow(missing_debug_implementations)]
#[stable(feature = "debug_builders", since = "1.2.0")]
#[rustc_diagnostic_item = "DebugStruct"]
pub struct DebugStruct<'a, 'b: 'a> {
fmt: &'a mut fmt::Formatter<'b>,
result: fmt::Result,

View File

@ -239,6 +239,7 @@ impl<W: Write + ?Sized> Write for &mut W {
/// documentation of the methods defined on `Formatter` below.
#[allow(missing_debug_implementations)]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "Formatter"]
pub struct Formatter<'a> {
flags: u32,
fill: char,

View File

@ -1509,12 +1509,14 @@ extern "rust-intrinsic" {
///
/// This intrinsic does not have a stable counterpart.
#[rustc_nounwind]
#[rustc_diagnostic_item = "intrinsics_unaligned_volatile_load"]
pub fn unaligned_volatile_load<T>(src: *const T) -> T;
/// Performs a volatile store to the `dst` pointer.
/// The pointer is not required to be aligned.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_nounwind]
#[rustc_diagnostic_item = "intrinsics_unaligned_volatile_store"]
pub fn unaligned_volatile_store<T>(dst: *mut T, val: T);
/// Returns the square root of an `f32`
@ -2666,6 +2668,7 @@ pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -
#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
#[inline(always)]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
#[rustc_diagnostic_item = "ptr_copy_nonoverlapping"]
pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
extern "rust-intrinsic" {
#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
@ -2761,6 +2764,7 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
#[inline(always)]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
#[rustc_diagnostic_item = "ptr_copy"]
pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
extern "rust-intrinsic" {
#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
@ -2834,6 +2838,7 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
#[inline(always)]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
#[rustc_diagnostic_item = "ptr_write_bytes"]
pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
extern "rust-intrinsic" {
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]

View File

@ -12,6 +12,7 @@ use crate::ops::{ControlFlow, Try};
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "IterPeekable"]
pub struct Peekable<I: Iterator> {
iter: I,
/// Remember a peeked value, even if it was None.

View File

@ -27,6 +27,7 @@ pub const fn empty<T>() -> Empty<T> {
/// This `struct` is created by the [`empty()`] function. See its documentation for more.
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "iter_empty", since = "1.2.0")]
#[rustc_diagnostic_item = "IterEmpty"]
pub struct Empty<T>(marker::PhantomData<fn() -> T>);
#[stable(feature = "core_impl_debug", since = "1.9.0")]

View File

@ -61,6 +61,7 @@ pub fn once<T>(value: T) -> Once<T> {
/// This `struct` is created by the [`once()`] function. See its documentation for more.
#[derive(Clone, Debug)]
#[stable(feature = "iter_once", since = "1.2.0")]
#[rustc_diagnostic_item = "IterOnce"]
pub struct Once<T> {
inner: crate::option::IntoIter<T>,
}

View File

@ -146,6 +146,7 @@ pub trait FromIterator<A>: Sized {
/// assert_eq!(v, vec![5, 5, 5, 5, 5]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "from_iter_fn"]
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
}

View File

@ -723,6 +723,7 @@ pub unsafe fn uninitialized<T>() -> T {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
#[rustc_diagnostic_item = "mem_swap"]
pub const fn swap<T>(x: &mut T, y: &mut T) {
// NOTE(eddyb) SPIR-V's Logical addressing model doesn't allow for arbitrary
// reinterpretation of values as (chunkable) byte arrays, and the loop in the

View File

@ -180,6 +180,7 @@ impl<T: ?Sized> Deref for &mut T {
pub trait DerefMut: Deref {
/// Mutably dereferences the value.
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "deref_mut_method"]
fn deref_mut(&mut self) -> &mut Self::Target;
}

View File

@ -758,6 +758,7 @@ impl<T: Clone> Bound<&T> {
/// `RangeBounds` is implemented by Rust's built-in range types, produced
/// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`.
#[stable(feature = "collections_range", since = "1.28.0")]
#[rustc_diagnostic_item = "RangeBounds"]
pub trait RangeBounds<T: ?Sized> {
/// Start index bound.
///

View File

@ -494,6 +494,7 @@ mod mut_ptr;
#[stable(feature = "drop_in_place", since = "1.8.0")]
#[lang = "drop_in_place"]
#[allow(unconditional_recursion)]
#[rustc_diagnostic_item = "ptr_drop_in_place"]
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
// Code here does not matter - this is replaced by the
// real drop glue by the compiler.
@ -740,6 +741,7 @@ pub const fn from_mut<T: ?Sized>(r: &mut T) -> *mut T {
#[stable(feature = "slice_from_raw_parts", since = "1.42.0")]
#[rustc_const_stable(feature = "const_slice_from_raw_parts", since = "1.64.0")]
#[rustc_allow_const_fn_unstable(ptr_metadata)]
#[rustc_diagnostic_item = "ptr_slice_from_raw_parts"]
pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
from_raw_parts(data.cast(), len)
}
@ -772,6 +774,7 @@ pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
#[inline]
#[stable(feature = "slice_from_raw_parts", since = "1.42.0")]
#[rustc_const_unstable(feature = "const_slice_from_raw_parts_mut", issue = "67456")]
#[rustc_diagnostic_item = "ptr_slice_from_raw_parts_mut"]
pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
from_raw_parts_mut(data.cast(), len)
}
@ -850,6 +853,7 @@ pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
#[rustc_diagnostic_item = "ptr_swap"]
pub const unsafe fn swap<T>(x: *mut T, y: *mut T) {
// Give ourselves some scratch space to work with.
// We do not have to worry about drops: `MaybeUninit` does nothing when dropped.
@ -911,6 +915,7 @@ pub const unsafe fn swap<T>(x: *mut T, y: *mut T) {
#[inline]
#[stable(feature = "swap_nonoverlapping", since = "1.27.0")]
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
#[rustc_diagnostic_item = "ptr_swap_nonoverlapping"]
pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
#[allow(unused)]
macro_rules! attempt_swap_as_chunks {
@ -1022,6 +1027,7 @@ const unsafe fn swap_nonoverlapping_simple_untyped<T>(x: *mut T, y: *mut T, coun
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
#[rustc_diagnostic_item = "ptr_replace"]
pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
// SAFETY: the caller must guarantee that `dst` is valid to be
// cast to a mutable reference (valid for writes, aligned, initialized),
@ -1147,6 +1153,7 @@ pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
#[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
#[rustc_allow_const_fn_unstable(const_mut_refs, const_maybe_uninit_as_mut_ptr)]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
#[rustc_diagnostic_item = "ptr_read"]
pub const unsafe fn read<T>(src: *const T) -> T {
// It would be semantically correct to implement this via `copy_nonoverlapping`
// and `MaybeUninit`, as was done before PR #109035. Calling `assume_init`
@ -1264,6 +1271,7 @@ pub const unsafe fn read<T>(src: *const T) -> T {
#[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
#[rustc_allow_const_fn_unstable(const_mut_refs, const_maybe_uninit_as_mut_ptr)]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
#[rustc_diagnostic_item = "ptr_read_unaligned"]
pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
let mut tmp = MaybeUninit::<T>::uninit();
// SAFETY: the caller must guarantee that `src` is valid for reads.
@ -1539,6 +1547,7 @@ pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
#[inline]
#[stable(feature = "volatile", since = "1.9.0")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
#[rustc_diagnostic_item = "ptr_read_volatile"]
pub unsafe fn read_volatile<T>(src: *const T) -> T {
// SAFETY: the caller must uphold the safety contract for `volatile_load`.
unsafe {
@ -1865,6 +1874,7 @@ pub(crate) const unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usiz
#[stable(feature = "ptr_eq", since = "1.17.0")]
#[inline(always)]
#[must_use = "pointer comparison produces a value"]
#[rustc_diagnostic_item = "ptr_eq"]
pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool {
a == b
}

View File

@ -68,6 +68,7 @@ use crate::slice::{self, SliceIndex};
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)]
#[rustc_nonnull_optimization_guaranteed]
#[rustc_diagnostic_item = "NonNull"]
pub struct NonNull<T: ?Sized> {
pointer: *const T,
}

View File

@ -59,6 +59,7 @@ impl<'a, T> IntoIterator for &'a mut [T] {
/// [slices]: slice
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[rustc_diagnostic_item = "SliceIter"]
pub struct Iter<'a, T: 'a> {
/// The pointer to the next element to return, or the past-the-end location
/// if the iterator is empty.

View File

@ -90,6 +90,7 @@ use crate::ptr;
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_slice_from_raw_parts", since = "1.64.0")]
#[must_use]
#[rustc_diagnostic_item = "slice_from_raw_parts"]
pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
// SAFETY: the caller must uphold the safety contract for `from_raw_parts`.
unsafe {
@ -136,6 +137,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_slice_from_raw_parts_mut", issue = "67456")]
#[must_use]
#[rustc_diagnostic_item = "slice_from_raw_parts_mut"]
pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
// SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`.
unsafe {

View File

@ -624,6 +624,7 @@ pub trait FromStr: Sized {
/// assert_eq!(5, x);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "from_str_method"]
fn from_str(s: &str) -> Result<Self, Self::Err>;
}

View File

@ -184,6 +184,7 @@ pub struct DirEntry(fs_imp::DirEntry);
/// ```
#[derive(Clone, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "FsOpenOptions")]
pub struct OpenOptions(fs_imp::OpenOptions);
/// Representation of the various timestamps on a file.
@ -201,6 +202,7 @@ pub struct FileTimes(fs_imp::FileTimes);
/// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt
#[derive(Clone, PartialEq, Eq, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "FsPermissions")]
pub struct Permissions(fs_imp::FilePermissions);
/// A structure representing a type of file with accessors for each file type.
@ -2241,6 +2243,7 @@ pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
/// ```
#[doc(alias = "mkdir")]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "fs_create_dir")]
pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
DirBuilder::new().create(path.as_ref())
}

View File

@ -1830,6 +1830,7 @@ pub trait Write {
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "IoSeek")]
pub trait Seek {
/// Seek to an offset, in bytes, in a stream.
///
@ -2893,6 +2894,7 @@ impl<B: BufRead> Iterator for Split<B> {
/// [`lines`]: BufRead::lines
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Debug)]
#[cfg_attr(not(test), rustc_diagnostic_item = "IoLines")]
pub struct Lines<B> {
buf: B,
}

View File

@ -611,6 +611,7 @@ static STDOUT: OnceLock<ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>> = OnceLo
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "io_stdout")]
pub fn stdout() -> Stdout {
Stdout {
inner: STDOUT
@ -847,6 +848,7 @@ pub struct StderrLock<'a> {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "io_stderr")]
pub fn stderr() -> Stderr {
// Note that unlike `stdout()` we don't use `at_exit` here to register a
// destructor. Stderr is not buffered, so there's no need to run a

View File

@ -526,6 +526,7 @@ impl fmt::Debug for ChildStderr {
/// list_dir.status().expect("process failed to execute");
/// ```
#[stable(feature = "process", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "Command")]
pub struct Command {
inner: imp::Command,
}
@ -2196,6 +2197,7 @@ impl Child {
/// process::exit(0x0100);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "process_exit")]
pub fn exit(code: i32) -> ! {
crate::rt::cleanup();
crate::sys::os::exit(code)

View File

@ -153,6 +153,7 @@ pub use core::time::TryFromFloatSecsError;
///
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[stable(feature = "time2", since = "1.8.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "Instant")]
pub struct Instant(time::Instant);
/// A measurement of the system clock, useful for talking to

View File

@ -287,5 +287,5 @@ fn is_mutex_guard(cx: &LateContext<'_>, def_id: DefId) -> bool {
}
fn is_refcell_ref(cx: &LateContext<'_>, def_id: DefId) -> bool {
match_def_path(cx, def_id, &paths::REFCELL_REF) || match_def_path(cx, def_id, &paths::REFCELL_REFMUT)
matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::RefCellRef | sym::RefCellRefMut))
}

View File

@ -1,10 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::macros::macro_backtrace;
use clippy_utils::ty::expr_sig;
use clippy_utils::{get_parent_node, is_default_equivalent, match_path, path_def_id, paths};
use clippy_utils::{get_parent_node, is_default_equivalent, path_def_id};
use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_ty, Visitor};
use rustc_hir::{Block, Expr, ExprKind, Local, Node, QPath, TyKind};
use rustc_hir::{def::Res, Block, Expr, ExprKind, Local, Node, QPath, TyKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::print::with_forced_trimmed_paths;
@ -55,7 +55,7 @@ impl LateLintPass<'_> for BoxDefault {
expr.span,
"`Box::new(_)` of default value",
"try",
if is_plain_default(arg_path) || given_type(cx, expr) {
if is_plain_default(cx, arg_path) || given_type(cx, expr) {
"Box::default()".into()
} else if let Some(arg_ty) = cx.typeck_results().expr_ty(arg).make_suggestable(cx.tcx, true) {
with_forced_trimmed_paths!(format!("Box::<{arg_ty}>::default()"))
@ -68,11 +68,13 @@ impl LateLintPass<'_> for BoxDefault {
}
}
fn is_plain_default(arg_path: &Expr<'_>) -> bool {
fn is_plain_default(cx: &LateContext<'_>, arg_path: &Expr<'_>) -> bool {
// we need to match the actual path so we don't match e.g. "u8::default"
if let ExprKind::Path(QPath::Resolved(None, path)) = &arg_path.kind {
if let ExprKind::Path(QPath::Resolved(None, path)) = &arg_path.kind
&& let Res::Def(_, def_id) = path.res
{
// avoid generic parameters
match_path(path, &paths::DEFAULT_TRAIT_METHOD) && path.segments.iter().all(|seg| seg.args.is_none())
cx.tcx.is_diagnostic_item(sym::default_fn, def_id) && path.segments.iter().all(|seg| seg.args.is_none())
} else {
false
}

View File

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint;
use clippy_utils::ty::is_c_void;
use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, match_any_def_paths, paths};
use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant};
use rustc_hir::{Expr, ExprKind, GenericArg};
use rustc_lint::LateContext;
use rustc_middle::ty::layout::LayoutOf;
@ -75,16 +75,17 @@ fn is_used_as_unaligned(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
}
},
ExprKind::Call(func, [arg, ..]) if arg.hir_id == e.hir_id => {
static PATHS: &[&[&str]] = &[
paths::PTR_READ_UNALIGNED.as_slice(),
paths::PTR_UNALIGNED_VOLATILE_LOAD.as_slice(),
paths::PTR_UNALIGNED_VOLATILE_STORE.as_slice(),
];
if let ExprKind::Path(path) = &func.kind
&& let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id()
&& (match_any_def_paths(cx, def_id, PATHS).is_some()
|| cx.tcx.is_diagnostic_item(sym::ptr_write_unaligned, def_id))
&& matches!(
cx.tcx.get_diagnostic_name(def_id),
Some(
sym::ptr_write_unaligned
| sym::ptr_read_unaligned
| sym::intrinsics_unaligned_volatile_load
| sym::intrinsics_unaligned_volatile_store
)
)
{
true
} else {

View File

@ -1,13 +1,13 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_context;
use clippy_utils::{match_def_path, paths};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::def_id::DefId;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty};
use rustc_span::sym;
use super::CAST_SLICE_FROM_RAW_PARTS;
@ -17,12 +17,10 @@ enum RawPartsKind {
}
fn raw_parts_kind(cx: &LateContext<'_>, did: DefId) -> Option<RawPartsKind> {
if match_def_path(cx, did, &paths::SLICE_FROM_RAW_PARTS) {
Some(RawPartsKind::Immutable)
} else if match_def_path(cx, did, &paths::SLICE_FROM_RAW_PARTS_MUT) {
Some(RawPartsKind::Mutable)
} else {
None
match cx.tcx.get_diagnostic_name(did)? {
sym::slice_from_raw_parts => Some(RawPartsKind::Immutable),
sym::slice_from_raw_parts_mut => Some(RawPartsKind::Mutable),
_ => None,
}
}

View File

@ -1,11 +1,11 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet;
use clippy_utils::{match_def_path, paths};
use if_chain::if_chain;
use rustc_errors::Applicability;
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
@ -37,7 +37,7 @@ impl LateLintPass<'_> for CreateDir {
if let ExprKind::Call(func, [arg, ..]) = expr.kind;
if let ExprKind::Path(ref path) = func.kind;
if let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id();
if match_def_path(cx, def_id, &paths::STD_FS_CREATE_DIR);
if cx.tcx.is_diagnostic_item(sym::fs_create_dir, def_id);
then {
span_lint_and_sugg(
cx,

View File

@ -1,9 +1,7 @@
use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg};
use clippy_utils::source::snippet_with_context;
use clippy_utils::ty::{has_drop, is_copy};
use clippy_utils::{
any_parent_is_automatically_derived, contains_name, get_parent_expr, is_from_proc_macro, match_def_path, paths,
};
use clippy_utils::{any_parent_is_automatically_derived, contains_name, get_parent_expr, is_from_proc_macro};
use if_chain::if_chain;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
@ -14,7 +12,7 @@ use rustc_middle::ty;
use rustc_middle::ty::print::with_forced_trimmed_paths;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::symbol::{Ident, Symbol};
use rustc_span::Span;
use rustc_span::{sym, Span};
declare_clippy_lint! {
/// ### What it does
@ -91,7 +89,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
if !any_parent_is_automatically_derived(cx.tcx, expr.hir_id);
if let ExprKind::Path(ref qpath) = path.kind;
if let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id();
if match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD);
if cx.tcx.is_diagnostic_item(sym::default_fn, def_id);
if !is_update_syntax_base(cx, expr);
// Detect and ignore <Foo as Default>::default() because these calls do explicitly name the type.
if let QPath::Resolved(None, _path) = qpath;
@ -268,7 +266,7 @@ fn is_expr_default<'tcx>(expr: &'tcx Expr<'tcx>, cx: &LateContext<'tcx>) -> bool
if let Res::Def(_, def_id) = cx.qpath_res(qpath, fn_expr.hir_id);
then {
// right hand side of assignment is `Default::default`
match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD)
cx.tcx.is_diagnostic_item(sym::default_fn, def_id)
} else {
false
}

View File

@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::{is_ty_alias, match_def_path, paths};
use clippy_utils::is_ty_alias;
use hir::def::Res;
use hir::ExprKind;
use rustc_errors::Applicability;
@ -7,6 +7,7 @@ use rustc_hir as hir;
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
@ -63,7 +64,7 @@ impl LateLintPass<'_> for DefaultConstructedUnitStructs {
// `<Foo as Bar>::Assoc` cannot be used as a constructor
if !is_alias(*base);
if let Res::Def(_, def_id) = cx.qpath_res(qpath, fn_expr.hir_id);
if match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD);
if cx.tcx.is_diagnostic_item(sym::default_fn, def_id);
// make sure we have a struct with no fields (unit struct)
if let ty::Adt(def, ..) = cx.typeck_results().expr_ty(expr).kind();
if def.is_struct();

View File

@ -1,11 +1,11 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_context;
use clippy_utils::{last_path_segment, match_def_path, paths};
use clippy_utils::last_path_segment;
use rustc_errors::Applicability;
use rustc_hir::{def, Expr, ExprKind, GenericArg, QPath, TyKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::SyntaxContext;
use rustc_span::{sym, SyntaxContext};
declare_clippy_lint! {
/// ### What it does
@ -37,7 +37,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultIterEmpty {
&& let TyKind::Path(ty_path) = &ty.kind
&& let QPath::Resolved(None, path) = ty_path
&& let def::Res::Def(_, def_id) = &path.res
&& match_def_path(cx, *def_id, &paths::ITER_EMPTY)
&& cx.tcx.is_diagnostic_item(sym::IterEmpty, *def_id)
&& let ctxt = expr.span.ctxt()
&& ty.span.ctxt() == ctxt
{

View File

@ -1,9 +1,10 @@
use clippy_utils::diagnostics::span_lint;
use clippy_utils::{is_entrypoint_fn, match_def_path, paths};
use clippy_utils::{is_entrypoint_fn};
use if_chain::if_chain;
use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
declare_clippy_lint! {
/// ### What it does
@ -45,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for Exit {
if let ExprKind::Call(path_expr, _args) = e.kind;
if let ExprKind::Path(ref path) = path_expr.kind;
if let Some(def_id) = cx.qpath_res(path, path_expr.hir_id).opt_def_id();
if match_def_path(cx, def_id, &paths::EXIT);
if cx.tcx.is_diagnostic_item(sym::process_exit, def_id);
let parent = cx.tcx.hir().get_parent_item(e.hir_id).def_id;
if let Some(Node::Item(Item{kind: ItemKind::Fn(..), ..})) = cx.tcx.hir().find_by_def_id(parent);
// If the next item up is a function we check if it is an entry point

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::macros::{find_format_args, format_args_inputs_span};
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::{is_expn_of, match_function_call, paths};
use clippy_utils::{is_expn_of, path_def_id};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::def::Res;
@ -47,18 +47,19 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
if let ExprKind::MethodCall(unwrap_fun, write_call, [], _) = expr.kind
&& unwrap_fun.ident.name == sym::unwrap
// match call to write_fmt
&& let ExprKind::MethodCall(write_fun, write_recv, [write_arg], _) = look_in_block(cx, &write_call.kind)
&& let ExprKind::MethodCall(write_fun, write_recv, [write_arg], _) = *look_in_block(cx, &write_call.kind)
&& let ExprKind::Call(write_recv_path, _) = write_recv.kind
&& write_fun.ident.name == sym!(write_fmt)
// match calls to std::io::stdout() / std::io::stderr ()
&& let Some(dest_name) = if match_function_call(cx, write_recv, &paths::STDOUT).is_some() {
Some("stdout")
} else if match_function_call(cx, write_recv, &paths::STDERR).is_some() {
Some("stderr")
} else {
None
}
&& let Some(format_args) = find_format_args(cx, write_arg, ExpnId::root())
&& let Some(def_id) = path_def_id(cx, write_recv_path)
{
// match calls to std::io::stdout() / std::io::stderr ()
let (dest_name, prefix) = match cx.tcx.get_diagnostic_name(def_id) {
Some(sym::io_stdout) => ("stdout", ""),
Some(sym::io_stderr) => ("stderr", "e"),
_ => return,
};
let Some(format_args) = find_format_args(cx, write_arg, ExpnId::root()) else { return; };
// ordering is important here, since `writeln!` uses `write!` internally
let calling_macro = if is_expn_of(write_call.span, "writeln").is_some() {
Some("writeln")
@ -67,11 +68,6 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
} else {
None
};
let prefix = if dest_name == "stderr" {
"e"
} else {
""
};
// We need to remove the last trailing newline from the string because the
// underlying `fmt::write` function doesn't know whether `println!` or `print!` was

View File

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::is_c_void;
use clippy_utils::{match_def_path, path_def_id, paths};
use clippy_utils::path_def_id;
use rustc_hir::def_id::DefId;
use rustc_hir::{Expr, ExprKind, QPath};
use rustc_lint::{LateContext, LateLintPass};
@ -68,7 +68,7 @@ fn def_id_matches_type(cx: &LateContext<'_>, def_id: DefId) -> Option<&'static s
}
}
if match_def_path(cx, def_id, &paths::WEAK_RC) || match_def_path(cx, def_id, &paths::WEAK_ARC) {
if matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::RcWeak | sym::ArcWeak)) {
Some("Weak")
} else {
None

View File

@ -130,11 +130,7 @@ fn is_instant_now_call(cx: &LateContext<'_>, expr_block: &'_ Expr<'_>) -> bool {
fn is_an_instant(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
let expr_ty = cx.typeck_results().expr_ty(expr);
match expr_ty.kind() {
rustc_middle::ty::Adt(def, _) => clippy_utils::match_def_path(cx, def.did(), &clippy_utils::paths::INSTANT),
_ => false,
}
ty::is_type_diagnostic_item(cx, expr_ty, sym::Instant)
}
fn is_a_duration(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {

View File

@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::ty::match_type;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{is_diag_item_method, is_trait_method, match_def_path, path_to_local_id, paths};
use rustc_errors::Applicability;
use rustc_hir::{Body, Closure, Expr, ExprKind};
@ -62,7 +62,7 @@ impl LateLintPass<'_> for LinesFilterMapOk {
if let ExprKind::MethodCall(fm_method, fm_receiver, [fm_arg], fm_span) = expr.kind &&
is_trait_method(cx, expr, sym::Iterator) &&
(fm_method.ident.as_str() == "filter_map" || fm_method.ident.as_str() == "flat_map") &&
match_type(cx, cx.typeck_results().expr_ty_adjusted(fm_receiver), &paths::STD_IO_LINES)
is_type_diagnostic_item(cx, cx.typeck_results().expr_ty_adjusted(fm_receiver), sym::IoLines)
{
let lint = match &fm_arg.kind {
// Detect `Result::ok`

View File

@ -135,7 +135,7 @@ fn check_to_owned(
if msrv.meets(msrvs::STRING_RETAIN)
&& let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind
&& let Some(to_owned_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id)
&& match_def_path(cx, to_owned_def_id, &paths::TO_OWNED_METHOD)
&& cx.tcx.is_diagnostic_item(sym::to_owned_method, to_owned_def_id)
&& let hir::ExprKind::MethodCall(_, chars_expr, [_], _) = &filter_expr.kind
&& let Some(filter_def_id) = cx.typeck_results().type_dependent_def_id(filter_expr.hir_id)
&& match_def_path(cx, filter_def_id, &paths::CORE_ITER_FILTER)

View File

@ -1,8 +1,8 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::match_type;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::visitors::is_local_used;
use clippy_utils::{path_to_local_id, paths, peel_blocks, peel_ref_operators, strip_pat_refs};
use clippy_utils::{path_to_local_id, peel_blocks, peel_ref_operators, strip_pat_refs};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Closure, Expr, ExprKind, PatKind};
@ -25,9 +25,9 @@ pub(super) fn check<'tcx>(
if let PatKind::Binding(_, arg_id, _, _) = strip_pat_refs(param.pat).kind;
if let ExprKind::Binary(ref op, l, r) = body.value.kind;
if op.node == BinOpKind::Eq;
if match_type(cx,
if is_type_diagnostic_item(cx,
cx.typeck_results().expr_ty(filter_recv).peel_refs(),
&paths::SLICE_ITER);
sym::SliceIter);
let operand_is_arg = |expr| {
let expr = peel_ref_operators(cx, peel_blocks(expr));
path_to_local_id(expr, arg_id)

View File

@ -1,7 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::paths;
use clippy_utils::source::snippet_with_context;
use clippy_utils::ty::{is_type_diagnostic_item, match_type};
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
@ -22,15 +20,14 @@ pub(super) fn check(
}
let obj_ty = cx.typeck_results().expr_ty(receiver).peel_refs();
if let ty::Adt(_, subst) = obj_ty.kind() {
let caller_type = if is_type_diagnostic_item(cx, obj_ty, sym::Rc) {
"Rc"
} else if is_type_diagnostic_item(cx, obj_ty, sym::Arc) {
"Arc"
} else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) {
"Weak"
} else {
return;
if let ty::Adt(adt, subst) = obj_ty.kind()
&& let Some(name) = cx.tcx.get_diagnostic_name(adt.did())
{
let caller_type = match name {
sym::Rc => "Rc",
sym::Arc => "Arc",
sym::RcWeak | sym::ArcWeak => "Weak",
_ => return,
};
// Sometimes unnecessary ::<_> after Rc/Arc/Weak

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::implements_trait;
use clippy_utils::{is_expr_path_def_path, paths, sugg};
use clippy_utils::{is_path_diagnostic_item, sugg};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
@ -13,7 +13,7 @@ use super::FROM_ITER_INSTEAD_OF_COLLECT;
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>], func: &hir::Expr<'_>) {
if_chain! {
if is_expr_path_def_path(cx, func, &paths::FROM_ITERATOR_METHOD);
if is_path_diagnostic_item(cx, func, sym::from_iter_fn);
let ty = cx.typeck_results().expr_ty(expr);
let arg_ty = cx.typeck_results().expr_ty(&args[0]);
if let Some(iter_id) = cx.tcx.get_diagnostic_item(sym::Iterator);

View File

@ -1,7 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::{is_type_lang_item, walk_ptrs_ty_depth};
use clippy_utils::{match_def_path, paths};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
@ -22,7 +21,7 @@ pub fn check(
if_chain! {
if args.is_empty() && method_name == sym::to_string;
if let Some(to_string_meth_did) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
if match_def_path(cx, to_string_meth_did, &paths::TO_STRING_METHOD);
if cx.tcx.is_diagnostic_item(sym::to_string_method, to_string_meth_did);
if let Some(args) = cx.typeck_results().node_args_opt(expr.hir_id);
let arg_ty = cx.typeck_results().expr_ty_adjusted(receiver);
let self_ty = args.type_at(0);

View File

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_note;
use clippy_utils::higher::VecArgs;
use clippy_utils::{expr_or_init, is_trait_method, match_def_path, paths};
use clippy_utils::{expr_or_init, is_trait_method};
use rustc_ast::LitKind;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext;
@ -26,14 +26,14 @@ fn get_iterator_length<'tcx>(cx: &LateContext<'tcx>, iter: &'tcx Expr<'tcx>) ->
};
let did = adt.did();
if match_def_path(cx, did, &paths::ARRAY_INTO_ITER) {
if cx.tcx.is_diagnostic_item(sym::ArrayIntoIter, did) {
// For array::IntoIter<T, const N: usize>, the length is the second generic
// parameter.
substs
.const_at(1)
.try_eval_target_usize(cx.tcx, cx.param_env)
.map(u128::from)
} else if match_def_path(cx, did, &paths::SLICE_ITER)
} else if cx.tcx.is_diagnostic_item(sym::SliceIter, did)
&& let ExprKind::MethodCall(_, recv, ..) = iter.kind
{
if let ty::Array(_, len) = cx.typeck_results().expr_ty(recv).peel_refs().kind() {
@ -47,9 +47,9 @@ fn get_iterator_length<'tcx>(cx: &LateContext<'tcx>, iter: &'tcx Expr<'tcx>) ->
} else {
None
}
} else if match_def_path(cx, did, &paths::ITER_EMPTY) {
} else if cx.tcx.is_diagnostic_item(sym::IterEmpty, did) {
Some(0)
} else if match_def_path(cx, did, &paths::ITER_ONCE) {
} else if cx.tcx.is_diagnostic_item(sym::IterOnce, did) {
Some(1)
} else {
None

View File

@ -1,17 +1,17 @@
use clippy_utils::diagnostics::span_lint;
use clippy_utils::paths;
use clippy_utils::ty::match_type;
use clippy_utils::ty::is_type_diagnostic_item;
use rustc_ast::ast::LitKind;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext;
use rustc_span::source_map::{Span, Spanned};
use rustc_span::sym;
use super::NONSENSICAL_OPEN_OPTIONS;
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) {
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
&& let Some(impl_id) = cx.tcx.impl_of_method(method_id)
&& match_type(cx, cx.tcx.type_of(impl_id).instantiate_identity(), &paths::OPEN_OPTIONS)
&& is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::FsOpenOptions)
{
let mut options = Vec::new();
get_open_options(cx, recv, &mut options);
@ -40,7 +40,7 @@ fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec
let obj_ty = cx.typeck_results().expr_ty(receiver).peel_refs();
// Only proceed if this is a call on some object of type std::fs::OpenOptions
if match_type(cx, obj_ty, &paths::OPEN_OPTIONS) && !arguments.is_empty() {
if is_type_diagnostic_item(cx, obj_ty, sym::FsOpenOptions) && !arguments.is_empty() {
let argument_option = match arguments[0].kind {
ExprKind::Lit(span) => {
if let Spanned {

View File

@ -32,8 +32,7 @@ pub(super) fn check(
return;
}
let deref_aliases: [&[&str]; 8] = [
&paths::DEREF_MUT_TRAIT_METHOD,
let deref_aliases: [&[&str]; 7] = [
&paths::CSTRING_AS_C_STR,
&paths::OS_STRING_AS_OS_STR,
&paths::PATH_BUF_AS_PATH,
@ -49,6 +48,7 @@ pub(super) fn check(
.opt_def_id()
.map_or(false, |fun_def_id| {
cx.tcx.is_diagnostic_item(sym::deref_method, fun_def_id)
|| cx.tcx.is_diagnostic_item(sym::deref_mut_method, fun_def_id)
|| deref_aliases.iter().any(|path| match_def_path(cx, fun_def_id, path))
})
},
@ -70,6 +70,7 @@ pub(super) fn check(
then {
let method_did = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id).unwrap();
cx.tcx.is_diagnostic_item(sym::deref_method, method_did)
|| cx.tcx.is_diagnostic_item(sym::deref_mut_method, method_did)
|| deref_aliases.iter().any(|path| match_def_path(cx, method_did, path))
} else {
false

View File

@ -2,18 +2,19 @@ use rustc_ast::ast::{LitIntType, LitKind};
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext;
use rustc_span::sym;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::implements_trait;
use clippy_utils::{get_trait_def_id, match_def_path, paths};
use clippy_utils::{match_def_path, paths};
use super::SEEK_FROM_CURRENT;
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'tcx Expr<'_>, arg: &'tcx Expr<'_>) {
let ty = cx.typeck_results().expr_ty(recv);
if let Some(def_id) = get_trait_def_id(cx, &paths::STD_IO_SEEK) {
if let Some(def_id) = cx.tcx.get_diagnostic_item(sym::IoSeek) {
if implements_trait(cx, ty, def_id, &[]) && arg_is_seek_from_current(cx, arg) {
let mut applicability = Applicability::MachineApplicable;
let snip = snippet_with_applicability(cx, recv.span, "..", &mut applicability);

View File

@ -1,11 +1,11 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::ty::implements_trait;
use clippy_utils::{get_trait_def_id, is_expr_used_or_unified, match_def_path, paths};
use clippy_utils::{is_expr_used_or_unified, match_def_path, paths};
use rustc_ast::ast::{LitIntType, LitKind};
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext;
use rustc_span::Span;
use rustc_span::{sym, Span};
use super::SEEK_TO_START_INSTEAD_OF_REWIND;
@ -23,7 +23,7 @@ pub(super) fn check<'tcx>(
return;
}
if let Some(seek_trait_id) = get_trait_def_id(cx, &paths::STD_IO_SEEK) &&
if let Some(seek_trait_id) = cx.tcx.get_diagnostic_item(sym::IoSeek) &&
implements_trait(cx, ty, seek_trait_id, &[]) &&
let ExprKind::Call(func, args1) = arg.kind &&
let ExprKind::Path(ref path) = func.kind &&

View File

@ -1,9 +1,8 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::paths;
use clippy_utils::ty::match_type;
use clippy_utils::ty::is_type_diagnostic_item;
use rustc_errors::{Applicability, Diagnostic};
use rustc_lint::LateContext;
use rustc_span::Span;
use rustc_span::{sym, Span};
use {rustc_ast as ast, rustc_hir as hir};
use super::SUSPICIOUS_COMMAND_ARG_SPACE;
@ -11,7 +10,7 @@ use super::SUSPICIOUS_COMMAND_ARG_SPACE;
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, recv: &'tcx hir::Expr<'_>, arg: &'tcx hir::Expr<'_>, span: Span) {
let ty = cx.typeck_results().expr_ty(recv).peel_refs();
if match_type(cx, ty, &paths::STD_PROCESS_COMMAND)
if is_type_diagnostic_item(cx, ty, sym::Command)
&& let hir::ExprKind::Lit(lit) = &arg.kind
&& let ast::LitKind::Str(s, _) = &lit.node
&& let Some((arg1, arg2)) = s.as_str().split_once(' ')

View File

@ -1,9 +1,9 @@
use std::ops::ControlFlow;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::ty::match_type;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::visitors::{for_each_expr, Visitable};
use clippy_utils::{is_path_lang_item, paths};
use clippy_utils::is_path_lang_item;
use rustc_ast::LitKind;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def::{DefKind, Res};
@ -114,9 +114,11 @@ fn should_lint<'tcx>(
if let ExprKind::MethodCall(path, recv, ..) = &expr.kind {
let recv_ty = typeck_results.expr_ty(recv).peel_refs();
if path.ident.name == sym::debug_struct && match_type(cx, recv_ty, &paths::FORMATTER) {
if path.ident.name == sym::debug_struct && is_type_diagnostic_item(cx, recv_ty, sym::Formatter) {
has_debug_struct = true;
} else if path.ident.name == sym!(finish_non_exhaustive) && match_type(cx, recv_ty, &paths::DEBUG_STRUCT) {
} else if path.ident.name == sym!(finish_non_exhaustive)
&& is_type_diagnostic_item(cx, recv_ty, sym::DebugStruct)
{
has_finish_non_exhaustive = true;
}
}
@ -137,7 +139,7 @@ fn as_field_call<'tcx>(
) -> Option<Symbol> {
if let ExprKind::MethodCall(path, recv, [debug_field, _], _) = &expr.kind
&& let recv_ty = typeck_results.expr_ty(recv).peel_refs()
&& match_type(cx, recv_ty, &paths::DEBUG_STRUCT)
&& is_type_diagnostic_item(cx, recv_ty, sym::DebugStruct)
&& path.ident.name == sym::field
&& let ExprKind::Lit(lit) = &debug_field.kind
&& let LitKind::Str(sym, ..) = lit.node

View File

@ -4,7 +4,7 @@ use clippy_utils::source::{snippet, snippet_opt};
use clippy_utils::ty::{
implements_trait, implements_trait_with_env_from_iter, is_copy, is_type_diagnostic_item, is_type_lang_item,
};
use clippy_utils::{get_trait_def_id, is_self, paths};
use clippy_utils::is_self;
use if_chain::if_chain;
use rustc_ast::ast::Attribute;
use rustc_errors::{Applicability, Diagnostic};
@ -115,7 +115,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
need!(cx.tcx.lang_items().fn_trait()),
need!(cx.tcx.lang_items().fn_once_trait()),
need!(cx.tcx.lang_items().fn_mut_trait()),
need!(get_trait_def_id(cx, &paths::RANGE_ARGUMENT_TRAIT)),
need!(cx.tcx.get_diagnostic_item(sym::RangeBounds)),
];
let sized_trait = need!(cx.tcx.lang_items().sized_trait());

View File

@ -1,7 +1,6 @@
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::paths::ORD_CMP;
use clippy_utils::ty::implements_trait;
use clippy_utils::{get_parent_node, is_res_lang_ctor, last_path_segment, match_def_path, path_res, std_or_core};
use clippy_utils::{get_parent_node, is_res_lang_ctor, last_path_segment, path_res, std_or_core};
use rustc_errors::Applicability;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, LangItem, Node, UnOp};
@ -261,7 +260,7 @@ fn self_cmp_call<'tcx>(
match cmp_expr.kind {
ExprKind::Call(path, [_self, _other]) => path_res(cx, path)
.opt_def_id()
.is_some_and(|def_id| match_def_path(cx, def_id, &ORD_CMP)),
.is_some_and(|def_id| cx.tcx.is_diagnostic_item(sym::ord_cmp_method, def_id)),
ExprKind::MethodCall(_, _, [_other], ..) => {
// We can set this to true here no matter what as if it's a `MethodCall` and goes to the
// `else` branch, it must be a method named `cmp` that isn't `Ord::cmp`
@ -273,7 +272,7 @@ fn self_cmp_call<'tcx>(
cx.tcx
.typeck(def_id)
.type_dependent_def_id(cmp_expr.hir_id)
.is_some_and(|def_id| match_def_path(cx, def_id, &ORD_CMP))
.is_some_and(|def_id| cx.tcx.is_diagnostic_item(sym::ord_cmp_method, def_id))
},
_ => false,
}

View File

@ -1,6 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::{snippet_opt, snippet_with_applicability};
use clippy_utils::ty::{is_type_diagnostic_item, match_type};
use clippy_utils::{match_def_path, paths};
use if_chain::if_chain;
use rustc_errors::Applicability;
@ -45,13 +44,12 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
match &expr.kind {
ExprKind::MethodCall(path, func, [param], _) => {
let obj_ty = cx.typeck_results().expr_ty(func).peel_refs();
if_chain! {
if let Some(adt) = cx.typeck_results().expr_ty(func).peel_refs().ty_adt_def();
if (path.ident.name == sym!(mode)
&& (match_type(cx, obj_ty, &paths::OPEN_OPTIONS)
|| is_type_diagnostic_item(cx, obj_ty, sym::DirBuilder)))
|| (path.ident.name == sym!(set_mode) && match_type(cx, obj_ty, &paths::PERMISSIONS));
&& matches!(cx.tcx.get_diagnostic_name(adt.did()), Some(sym::FsOpenOptions | sym::DirBuilder)))
|| (path.ident.name == sym!(set_mode)
&& cx.tcx.is_diagnostic_item(sym::FsPermissions, adt.did()));
if let ExprKind::Lit(_) = param.kind;
if param.span.ctxt() == expr.span.ctxt();

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet;
use clippy_utils::ty::{implements_trait, is_copy};
use clippy_utils::{is_lint_allowed, match_def_path, paths};
use clippy_utils::is_lint_allowed;
use rustc_ast::ImplPolarity;
use rustc_hir::def_id::DefId;
use rustc_hir::{FieldDef, Item, ItemKind, Node};
@ -233,7 +233,7 @@ fn contains_pointer_like<'tcx>(cx: &LateContext<'tcx>, target_ty: Ty<'tcx>) -> b
return true;
},
ty::Adt(adt_def, _) => {
if match_def_path(cx, adt_def.did(), &paths::PTR_NON_NULL) {
if cx.tcx.is_diagnostic_item(sym::NonNull, adt_def.did()) {
return true;
}
},

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet;
use clippy_utils::ty::{implements_trait, is_copy};
use clippy_utils::{match_def_path, path_def_id, paths};
use clippy_utils::path_def_id;
use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
use rustc_lint::LateContext;
@ -50,7 +50,7 @@ fn check_op(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool)
},
ExprKind::Call(path, [arg])
if path_def_id(cx, path).map_or(false, |did| {
if match_def_path(cx, did, &paths::FROM_STR_METHOD) {
if cx.tcx.is_diagnostic_item(sym::from_str_method, did) {
true
} else if cx.tcx.is_diagnostic_item(sym::from_fn, did) {
!is_copy(cx, typeck.expr_ty(expr))

View File

@ -1,10 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::paths;
use clippy_utils::ty::match_type;
use clippy_utils::ty::is_type_diagnostic_item;
use rustc_ast::ast::LitKind;
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
@ -31,7 +31,7 @@ declare_lint_pass!(PermissionsSetReadonlyFalse => [PERMISSIONS_SET_READONLY_FALS
impl<'tcx> LateLintPass<'tcx> for PermissionsSetReadonlyFalse {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
if let ExprKind::MethodCall(path, receiver, [arg], _) = &expr.kind
&& match_type(cx, cx.typeck_results().expr_ty(receiver), &paths::PERMISSIONS)
&& is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(receiver), sym::FsPermissions)
&& path.ident.name == sym!(set_readonly)
&& let ExprKind::Lit(lit) = &arg.kind
&& LitKind::Bool(false) == lit.node

View File

@ -4,9 +4,8 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_the
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::expr_sig;
use clippy_utils::visitors::contains_unsafe_block;
use clippy_utils::{get_expr_use_or_unification_node, is_lint_allowed, path_def_id, path_to_local, paths};
use clippy_utils::{get_expr_use_or_unification_node, is_lint_allowed, path_def_id, path_to_local};
use hir::LifetimeName;
use if_chain::if_chain;
use rustc_errors::{Applicability, MultiSpan};
use rustc_hir::def_id::DefId;
use rustc_hir::hir_id::HirIdMap;
@ -271,60 +270,43 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
}
fn check_invalid_ptr_usage<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// (fn_path, arg_indices) - `arg_indices` are the `arg` positions where null would cause U.B.
const INVALID_NULL_PTR_USAGE_TABLE: [(&[&str], &[usize]); 13] = [
(&paths::SLICE_FROM_RAW_PARTS, &[0]),
(&paths::SLICE_FROM_RAW_PARTS_MUT, &[0]),
(&paths::PTR_COPY, &[0, 1]),
(&paths::PTR_COPY_NONOVERLAPPING, &[0, 1]),
(&paths::PTR_READ, &[0]),
(&paths::PTR_READ_UNALIGNED, &[0]),
(&paths::PTR_READ_VOLATILE, &[0]),
(&paths::PTR_REPLACE, &[0]),
(&paths::PTR_SLICE_FROM_RAW_PARTS, &[0]),
(&paths::PTR_SLICE_FROM_RAW_PARTS_MUT, &[0]),
(&paths::PTR_SWAP, &[0, 1]),
(&paths::PTR_SWAP_NONOVERLAPPING, &[0, 1]),
(&paths::PTR_WRITE_BYTES, &[0]),
];
let invalid_null_ptr_usage_table_diag_items: [(Option<DefId>, &[usize]); 3] = [
(cx.tcx.get_diagnostic_item(sym::ptr_write), &[0]),
(cx.tcx.get_diagnostic_item(sym::ptr_write_unaligned), &[0]),
(cx.tcx.get_diagnostic_item(sym::ptr_write_volatile), &[0]),
];
if let ExprKind::Call(fun, args) = expr.kind
&& let ExprKind::Path(ref qpath) = fun.kind
&& let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()
&& let Some(name) = cx.tcx.get_diagnostic_name(fun_def_id)
{
// `arg` positions where null would cause U.B.
let arg_indices: &[_] = match name {
sym::ptr_read
| sym::ptr_read_unaligned
| sym::ptr_read_volatile
| sym::ptr_replace
| sym::ptr_slice_from_raw_parts
| sym::ptr_slice_from_raw_parts_mut
| sym::ptr_write
| sym::ptr_write_bytes
| sym::ptr_write_unaligned
| sym::ptr_write_volatile
| sym::slice_from_raw_parts
| sym::slice_from_raw_parts_mut => &[0],
sym::ptr_copy
| sym::ptr_copy_nonoverlapping
| sym::ptr_swap
| sym::ptr_swap_nonoverlapping => &[0, 1],
_ => return,
};
if_chain! {
if let ExprKind::Call(fun, args) = expr.kind;
if let ExprKind::Path(ref qpath) = fun.kind;
if let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id();
let fun_def_path = cx.get_def_path(fun_def_id).into_iter().map(Symbol::to_ident_string).collect::<Vec<_>>();
if let Some(arg_indices) = INVALID_NULL_PTR_USAGE_TABLE
.iter()
.find_map(|&(fn_path, indices)| if fn_path == fun_def_path { Some(indices) } else { None })
.or_else(|| {
invalid_null_ptr_usage_table_diag_items
.iter()
.find_map(|&(def_id, indices)| {
if def_id == Some(fun_def_id) {
Some(indices)
} else {
None
}
})
});
then {
for &arg_idx in arg_indices {
if let Some(arg) = args.get(arg_idx).filter(|arg| is_null_path(cx, arg)) {
span_lint_and_sugg(
cx,
INVALID_NULL_PTR_USAGE,
arg.span,
"pointer must be non-null",
"change this to",
"core::ptr::NonNull::dangling().as_ptr()".to_string(),
Applicability::MachineApplicable,
);
}
for &arg_idx in arg_indices {
if let Some(arg) = args.get(arg_idx).filter(|arg| is_null_path(cx, arg)) {
span_lint_and_sugg(
cx,
INVALID_NULL_PTR_USAGE,
arg.span,
"pointer must be non-null",
"change this to",
"core::ptr::NonNull::dangling().as_ptr()".to_string(),
Applicability::MachineApplicable,
);
}
}
}

View File

@ -2,11 +2,11 @@ use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::higher::VecArgs;
use clippy_utils::macros::root_macro_call_first_node;
use clippy_utils::source::{indent_of, snippet};
use clippy_utils::ty::match_type;
use clippy_utils::{last_path_segment, paths};
use clippy_utils::last_path_segment;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, QPath, TyKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{sym, Span, Symbol};
@ -133,8 +133,9 @@ fn ref_init(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<(Symbol, Span)> {
return Some((symbol, func.span));
}
let ty_path = cx.typeck_results().expr_ty(expr);
if match_type(cx, ty_path, &paths::WEAK_RC) || match_type(cx, ty_path, &paths::WEAK_ARC) {
if let ty::Adt(adt, _) = *cx.typeck_results().expr_ty(expr).kind()
&& matches!(cx.tcx.get_diagnostic_name(adt.did()), Some(sym::RcWeak | sym::ArcWeak))
{
return Some((Symbol::intern("Weak"), func.span));
}
}

View File

@ -99,8 +99,8 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone {
unwrap_or_continue!(is_call_with_ref_arg(cx, mir, &terminator.kind));
let from_borrow = match_def_path(cx, fn_def_id, &paths::CLONE_TRAIT_METHOD)
|| match_def_path(cx, fn_def_id, &paths::TO_OWNED_METHOD)
|| (match_def_path(cx, fn_def_id, &paths::TO_STRING_METHOD)
|| cx.tcx.is_diagnostic_item(sym::to_owned_method, fn_def_id)
|| (cx.tcx.is_diagnostic_item(sym::to_string_method, fn_def_id)
&& is_type_lang_item(cx, arg_ty, LangItem::String));
let from_deref = !from_borrow

View File

@ -2,7 +2,6 @@
//! expecting a count of T
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::{match_def_path, paths};
use if_chain::if_chain;
use rustc_hir::{BinOpKind, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
@ -67,16 +66,6 @@ fn get_pointee_ty_and_count_expr<'tcx>(
cx: &LateContext<'tcx>,
expr: &'tcx Expr<'_>,
) -> Option<(Ty<'tcx>, &'tcx Expr<'tcx>)> {
const FUNCTIONS: [&[&str]; 8] = [
&paths::PTR_COPY_NONOVERLAPPING,
&paths::PTR_COPY,
&paths::PTR_WRITE_BYTES,
&paths::PTR_SWAP_NONOVERLAPPING,
&paths::PTR_SLICE_FROM_RAW_PARTS,
&paths::PTR_SLICE_FROM_RAW_PARTS_MUT,
&paths::SLICE_FROM_RAW_PARTS,
&paths::SLICE_FROM_RAW_PARTS_MUT,
];
const METHODS: [&str; 11] = [
"write_bytes",
"copy_to",
@ -97,7 +86,16 @@ fn get_pointee_ty_and_count_expr<'tcx>(
if let ExprKind::Call(func, [.., count]) = 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 FUNCTIONS.iter().any(|func_path| match_def_path(cx, def_id, func_path));
if matches!(cx.tcx.get_diagnostic_name(def_id), Some(
sym::ptr_copy
| sym::ptr_copy_nonoverlapping
| sym::ptr_slice_from_raw_parts
| sym::ptr_slice_from_raw_parts_mut
| sym::ptr_swap_nonoverlapping
| sym::ptr_write_bytes
| sym::slice_from_raw_parts
| sym::slice_from_raw_parts_mut
));
// Get the pointee type
if let Some(pointee_ty) = cx.typeck_results().node_args(func.hir_id).types().next();

View File

@ -1,11 +1,11 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_with_context;
use clippy_utils::{match_def_path, path_def_id, paths};
use clippy_utils::path_def_id;
use rustc_errors::Applicability;
use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, UnOp};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{Span, SyntaxContext};
use rustc_span::{sym, Span, SyntaxContext};
declare_clippy_lint! {
/// ### What it does
@ -42,7 +42,7 @@ impl LateLintPass<'_> for SwapPtrToRef {
fn check_expr(&mut self, cx: &LateContext<'_>, e: &Expr<'_>) {
if let ExprKind::Call(fn_expr, [arg1, arg2]) = e.kind
&& let Some(fn_id) = path_def_id(cx, fn_expr)
&& match_def_path(cx, fn_id, &paths::MEM_SWAP)
&& cx.tcx.is_diagnostic_item(sym::mem_swap, fn_id)
&& let ctxt = e.span.ctxt()
&& let (from_ptr1, arg1_span) = is_ptr_to_ref(cx, arg1, ctxt)
&& let (from_ptr2, arg2_span) = is_ptr_to_ref(cx, arg2, ctxt)

View File

@ -1,10 +1,10 @@
use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
use clippy_utils::{match_def_path, paths};
use if_chain::if_chain;
use rustc_hir::{BinOpKind, 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
@ -96,7 +96,7 @@ impl LateLintPass<'_> for UnnamedAddress {
if let ExprKind::Call(func, [ref _left, ref _right]) = 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::PTR_EQ);
if cx.tcx.is_diagnostic_item(sym::ptr_eq, def_id);
let ty_param = cx.typeck_results().node_args(func.hir_id).type_at(0);
if ty_param.is_trait();
then {

View File

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::{match_type, peel_mid_ty_refs_is_mutable};
use clippy_utils::{fn_def_id, is_trait_method, path_to_local_id, paths, peel_ref_operators};
use clippy_utils::ty::{is_type_diagnostic_item, peel_mid_ty_refs_is_mutable};
use clippy_utils::{fn_def_id, is_trait_method, path_to_local_id, peel_ref_operators};
use rustc_ast::Mutability;
use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{Block, Expr, ExprKind, HirId, Local, Node, PatKind, PathSegment, StmtKind};
@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedPeekable {
// Don't lint `Peekable`s returned from a block
if let Some(expr) = block.expr
&& let Some(ty) = cx.typeck_results().expr_ty_opt(peel_ref_operators(cx, expr))
&& match_type(cx, ty, &paths::PEEKABLE)
&& is_type_diagnostic_item(cx, ty, sym::IterPeekable)
{
return;
}
@ -62,7 +62,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedPeekable {
&& !init.span.from_expansion()
&& let Some(ty) = cx.typeck_results().expr_ty_opt(init)
&& let (ty, _, Mutability::Mut) = peel_mid_ty_refs_is_mutable(ty)
&& match_type(cx, ty, &paths::PEEKABLE)
&& is_type_diagnostic_item(cx, ty, sym::IterPeekable)
{
let mut vis = PeekableVisitor::new(cx, binding);
@ -222,7 +222,7 @@ impl<'tcx> Visitor<'tcx> for PeekableVisitor<'_, 'tcx> {
fn arg_is_mut_peekable(cx: &LateContext<'_>, arg: &Expr<'_>) -> bool {
if let Some(ty) = cx.typeck_results().expr_ty_opt(arg)
&& let (ty, _, Mutability::Mut) = peel_mid_ty_refs_is_mutable(ty)
&& match_type(cx, ty, &paths::PEEKABLE)
&& is_type_diagnostic_item(cx, ty, sym::IterPeekable)
{
true
} else {

View File

@ -2,7 +2,7 @@ use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lin
use clippy_utils::source::{snippet, snippet_with_applicability, snippet_with_context};
use clippy_utils::sugg::Sugg;
use clippy_utils::ty::{is_copy, is_type_diagnostic_item, same_type_and_consts};
use clippy_utils::{get_parent_expr, is_trait_method, is_ty_alias, match_def_path, path_to_local, paths};
use clippy_utils::{get_parent_expr, is_trait_method, is_ty_alias, path_to_local};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::def::DefKind;
@ -331,7 +331,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
let a = cx.typeck_results().expr_ty(e);
let b = cx.typeck_results().expr_ty(arg);
if_chain! {
if match_def_path(cx, def_id, &paths::TRY_FROM);
if cx.tcx.is_diagnostic_item(sym::try_from_fn, def_id);
if is_type_diagnostic_item(cx, a, sym::Result);
if let ty::Adt(_, args) = a.kind();
if let Some(a_type) = args.types().next();

View File

@ -457,7 +457,7 @@ pub fn get_vec_init_kind<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -
};
},
ExprKind::Path(QPath::Resolved(_, path))
if match_def_path(cx, path.res.opt_def_id()?, &paths::DEFAULT_TRAIT_METHOD)
if cx.tcx.is_diagnostic_item(sym::default_fn, path.res.opt_def_id()?)
&& is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(expr), sym::Vec) =>
{
return Some(VecInitKind::Default);

View File

@ -2076,7 +2076,7 @@ pub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool
match expr.kind {
ExprKind::Closure(&Closure { body, .. }) => is_body_identity_function(cx, cx.tcx.hir().body(body)),
_ => path_def_id(cx, expr).map_or(false, |id| match_def_path(cx, id, &paths::CONVERT_IDENTITY)),
_ => path_def_id(cx, expr).map_or(false, |id| cx.tcx.is_diagnostic_item(sym::convert_identity, id)),
}
}

View File

@ -25,17 +25,12 @@ pub const CORE_ITER_COPIED: [&str; 6] = ["core", "iter", "traits", "iterator", "
pub const CORE_ITER_FILTER: [&str; 6] = ["core", "iter", "traits", "iterator", "Iterator", "filter"];
pub const CORE_RESULT_OK_METHOD: [&str; 4] = ["core", "result", "Result", "ok"];
pub const CSTRING_AS_C_STR: [&str; 5] = ["alloc", "ffi", "c_str", "CString", "as_c_str"];
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"];
#[cfg(feature = "internal")]
pub const EARLY_CONTEXT: [&str; 2] = ["rustc_lint", "EarlyContext"];
#[cfg(feature = "internal")]
pub const EARLY_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "EarlyLintPass"];
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 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"];
#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
pub const FUTURES_IO_ASYNCREADEXT: [&str; 3] = ["futures_util", "io", "AsyncReadExt"];
#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
@ -48,8 +43,6 @@ pub const IDENT: [&str; 3] = ["rustc_span", "symbol", "Ident"];
#[cfg(feature = "internal")]
pub const IDENT_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Ident", "as_str"];
pub const INSERT_STR: [&str; 4] = ["alloc", "string", "String", "insert_str"];
pub const ITER_EMPTY: [&str; 5] = ["core", "iter", "sources", "empty", "Empty"];
pub const ITER_ONCE: [&str; 5] = ["core", "iter", "sources", "once", "Once"];
pub const ITERTOOLS_NEXT_TUPLE: [&str; 3] = ["itertools", "Itertools", "next_tuple"];
#[cfg(feature = "internal")]
pub const KW_MODULE: [&str; 3] = ["rustc_span", "symbol", "kw"];
@ -59,10 +52,8 @@ pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"];
pub const LATE_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "LateLintPass"];
#[cfg(feature = "internal")]
pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"];
pub const MEM_SWAP: [&str; 3] = ["core", "mem", "swap"];
#[cfg(feature = "internal")]
pub const MSRV: [&str; 3] = ["clippy_utils", "msrvs", "Msrv"];
pub const OPEN_OPTIONS: [&str; 3] = ["std", "fs", "OpenOptions"];
pub const OS_STRING_AS_OS_STR: [&str; 5] = ["std", "ffi", "os_str", "OsString", "as_os_str"];
pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to_os_string"];
pub const PARKING_LOT_MUTEX_GUARD: [&str; 3] = ["lock_api", "mutex", "MutexGuard"];
@ -71,28 +62,9 @@ pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 3] = ["lock_api", "rwlock", "Rw
pub const PATH_BUF_AS_PATH: [&str; 4] = ["std", "path", "PathBuf", "as_path"];
pub const PATH_MAIN_SEPARATOR: [&str; 3] = ["std", "path", "MAIN_SEPARATOR"];
pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"];
pub const PEEKABLE: [&str; 5] = ["core", "iter", "adapters", "peekable", "Peekable"];
pub const PERMISSIONS: [&str; 3] = ["std", "fs", "Permissions"];
#[cfg_attr(not(unix), allow(clippy::invalid_paths))]
pub const PERMISSIONS_FROM_MODE: [&str; 6] = ["std", "os", "unix", "fs", "PermissionsExt", "from_mode"];
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"];
pub const PTR_SLICE_FROM_RAW_PARTS: [&str; 3] = ["core", "ptr", "slice_from_raw_parts"];
pub const PTR_SLICE_FROM_RAW_PARTS_MUT: [&str; 3] = ["core", "ptr", "slice_from_raw_parts_mut"];
pub const PTR_SWAP_NONOVERLAPPING: [&str; 3] = ["core", "ptr", "swap_nonoverlapping"];
pub const PTR_READ: [&str; 3] = ["core", "ptr", "read"];
pub const PTR_READ_UNALIGNED: [&str; 3] = ["core", "ptr", "read_unaligned"];
pub const PTR_READ_VOLATILE: [&str; 3] = ["core", "ptr", "read_volatile"];
pub const PTR_REPLACE: [&str; 3] = ["core", "ptr", "replace"];
pub const PTR_SWAP: [&str; 3] = ["core", "ptr", "swap"];
pub const PTR_UNALIGNED_VOLATILE_LOAD: [&str; 3] = ["core", "intrinsics", "unaligned_volatile_load"];
pub const PTR_UNALIGNED_VOLATILE_STORE: [&str; 3] = ["core", "intrinsics", "unaligned_volatile_store"];
pub const PTR_WRITE_BYTES: [&str; 3] = ["core", "intrinsics", "write_bytes"];
pub const PUSH_STR: [&str; 4] = ["alloc", "string", "String", "push_str"];
pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["core", "ops", "RangeBounds"];
pub const REFCELL_REF: [&str; 3] = ["core", "cell", "Ref"];
pub const REFCELL_REFMUT: [&str; 3] = ["core", "cell", "RefMut"];
pub const REGEX_BUILDER_NEW: [&str; 3] = ["regex", "RegexBuilder", "new"];
pub const REGEX_BYTES_BUILDER_NEW: [&str; 4] = ["regex", "bytes", "RegexBuilder", "new"];
pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "bytes", "Regex", "new"];
@ -101,21 +73,11 @@ pub const REGEX_NEW: [&str; 3] = ["regex", "Regex", "new"];
pub const REGEX_SET_NEW: [&str; 3] = ["regex", "RegexSet", "new"];
pub const SERDE_DESERIALIZE: [&str; 3] = ["serde", "de", "Deserialize"];
pub const SERDE_DE_VISITOR: [&str; 3] = ["serde", "de", "Visitor"];
pub const SLICE_FROM_RAW_PARTS: [&str; 4] = ["core", "slice", "raw", "from_raw_parts"];
pub const SLICE_FROM_RAW_PARTS_MUT: [&str; 4] = ["core", "slice", "raw", "from_raw_parts_mut"];
pub const SLICE_GET: [&str; 4] = ["core", "slice", "<impl [T]>", "get"];
pub const SLICE_INTO_VEC: [&str; 4] = ["alloc", "slice", "<impl [T]>", "into_vec"];
pub const SLICE_INTO: [&str; 4] = ["core", "slice", "<impl [T]>", "iter"];
pub const SLICE_ITER: [&str; 4] = ["core", "slice", "iter", "Iter"];
pub const STDERR: [&str; 4] = ["std", "io", "stdio", "stderr"];
pub const STDOUT: [&str; 4] = ["std", "io", "stdio", "stdout"];
pub const CONVERT_IDENTITY: [&str; 3] = ["core", "convert", "identity"];
pub const STD_FS_CREATE_DIR: [&str; 3] = ["std", "fs", "create_dir"];
pub const STD_IO_LINES: [&str; 3] = ["std", "io", "Lines"];
pub const STD_IO_SEEK: [&str; 3] = ["std", "io", "Seek"];
pub const STD_IO_SEEK_FROM_CURRENT: [&str; 4] = ["std", "io", "SeekFrom", "Current"];
pub const STD_IO_SEEKFROM_START: [&str; 4] = ["std", "io", "SeekFrom", "Start"];
pub const STD_PROCESS_COMMAND: [&str; 3] = ["std", "process", "Command"];
pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"];
pub const STRING_AS_STR: [&str; 4] = ["alloc", "string", "String", "as_str"];
pub const STRING_NEW: [&str; 4] = ["alloc", "string", "String", "new"];
@ -136,13 +98,11 @@ pub const SYMBOL_TO_IDENT_STRING: [&str; 4] = ["rustc_span", "symbol", "Symbol",
pub const SYM_MODULE: [&str; 3] = ["rustc_span", "symbol", "sym"];
#[cfg(feature = "internal")]
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_STRING_METHOD: [&str; 4] = ["alloc", "string", "ToString", "to_string"];
#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
pub const TOKIO_IO_ASYNCREADEXT: [&str; 5] = ["tokio", "io", "util", "async_read_ext", "AsyncReadExt"];
#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
pub const TOKIO_IO_ASYNCWRITEEXT: [&str; 5] = ["tokio", "io", "util", "async_write_ext", "AsyncWriteExt"];
pub const TRY_FROM: [&str; 4] = ["core", "convert", "TryFrom", "try_from"];
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_ITER: [&str; 5] = ["alloc", "collections", "vec_deque", "VecDeque", "iter"];
@ -150,18 +110,10 @@ pub const VEC_FROM_ELEM: [&str; 3] = ["alloc", "vec", "from_elem"];
pub const VEC_NEW: [&str; 4] = ["alloc", "vec", "Vec", "new"];
pub const VEC_WITH_CAPACITY: [&str; 4] = ["alloc", "vec", "Vec", "with_capacity"];
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 PTR_NON_NULL: [&str; 4] = ["core", "ptr", "non_null", "NonNull"];
pub const INSTANT_NOW: [&str; 4] = ["std", "time", "Instant", "now"];
pub const INSTANT: [&str; 3] = ["std", "time", "Instant"];
pub const VEC_IS_EMPTY: [&str; 4] = ["alloc", "vec", "Vec", "is_empty"];
pub const VEC_POP: [&str; 4] = ["alloc", "vec", "Vec", "pop"];
pub const OPTION_UNWRAP: [&str; 4] = ["core", "option", "Option", "unwrap"];
pub const OPTION_EXPECT: [&str; 4] = ["core", "option", "Option", "expect"];
pub const FORMATTER: [&str; 3] = ["core", "fmt", "Formatter"];
pub const DEBUG_STRUCT: [&str; 4] = ["core", "fmt", "builders", "DebugStruct"];
pub const ORD_CMP: [&str; 4] = ["core", "cmp", "Ord", "cmp"];
#[expect(clippy::invalid_paths)] // not sure why it thinks this, it works so
pub const BOOL_THEN: [&str; 4] = ["core", "bool", "<impl bool>", "then"];
pub const ARRAY_INTO_ITER: [&str; 4] = ["core", "array", "iter", "IntoIter"];

View File

@ -31,7 +31,7 @@ use rustc_trait_selection::traits::{Obligation, ObligationCause};
use std::assert_matches::debug_assert_matches;
use std::iter;
use crate::{match_def_path, path_res, paths};
use crate::{match_def_path, path_res};
mod type_certainty;
pub use type_certainty::expr_type_is_certain;
@ -461,10 +461,8 @@ pub fn needs_ordered_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
else if is_type_lang_item(cx, ty, LangItem::OwnedBox)
|| matches!(
get_type_diagnostic_name(cx, ty),
Some(sym::HashSet | sym::Rc | sym::Arc | sym::cstring_type)
Some(sym::HashSet | sym::Rc | sym::Arc | sym::cstring_type | sym::RcWeak | sym::ArcWeak)
)
|| match_type(cx, ty, &paths::WEAK_RC)
|| match_type(cx, ty, &paths::WEAK_ARC)
{
// Check all of the generic arguments.
if let ty::Adt(_, subs) = ty.kind() {

View File

@ -11,6 +11,6 @@ fn main() {
const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"];
const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref", "deref"];
// Don't lint, not yet a diagnostic or language item
const DEREF_MUT_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "DerefMut", "deref_mut"];
// Don't lint, not a diagnostic or language item
const OPS_MOD: [&str; 5] = ["core", "ops"];
}

View File

@ -19,8 +19,8 @@ LL | const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"]
error: hardcoded path to a diagnostic item
--> $DIR/unnecessary_def_path_hardcoded_path.rs:12:43
|
LL | const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref", "deref"];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | const OPS_MOD: [&str; 5] = ["core", "ops"];
| ^^^^^^^^^^^^^^^
|
= help: convert all references to use `sym::deref_method`