Auto merge of #130572 - matthiaskrgr:rollup-0q3qyg9, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #128001 (Improve documentation for <integer>::from_str_radix) - #130553 ([Clippy] Get rid of most `std` `match_def_path` usage, swap to diagnostic items.) - #130554 (`pal::unsupported::process::ExitCode`: use an `u8` instead of a `bool`) - #130556 (Mark the `link_cfg` feature as internal) - #130558 (Support 128-bit atomics on s390x) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
506f22b466
@ -204,7 +204,7 @@ pub fn internal(&self, feature: Symbol) -> bool {
|
||||
/// Changes `impl Trait` to capture all lifetimes in scope.
|
||||
(unstable, lifetime_capture_rules_2024, "1.76.0", None),
|
||||
/// Allows `#[link(..., cfg(..))]`; perma-unstable per #37406
|
||||
(unstable, link_cfg, "1.14.0", None),
|
||||
(internal, link_cfg, "1.14.0", None),
|
||||
/// Allows using `?Trait` trait bounds in more contexts.
|
||||
(internal, more_maybe_bounds, "1.82.0", None),
|
||||
/// Allows the `multiple_supertrait_upcastable` lint.
|
||||
|
@ -342,6 +342,7 @@
|
||||
Upvars,
|
||||
Vec,
|
||||
VecDeque,
|
||||
Waker,
|
||||
Wrapper,
|
||||
Wrapping,
|
||||
Yield,
|
||||
@ -501,6 +502,7 @@
|
||||
black_box,
|
||||
block,
|
||||
bool,
|
||||
bool_then,
|
||||
borrowck_graphviz_format,
|
||||
borrowck_graphviz_postflow,
|
||||
box_new,
|
||||
@ -512,6 +514,8 @@
|
||||
breakpoint,
|
||||
bridge,
|
||||
bswap,
|
||||
btreemap_contains_key,
|
||||
btreemap_insert,
|
||||
btreeset_iter,
|
||||
builtin_syntax,
|
||||
c,
|
||||
@ -680,6 +684,7 @@
|
||||
crt_dash_static: "crt-static",
|
||||
csky_target_feature,
|
||||
cstr_type,
|
||||
cstring_as_c_str,
|
||||
cstring_type,
|
||||
ctlz,
|
||||
ctlz_nonzero,
|
||||
@ -835,6 +840,7 @@
|
||||
f16_nan,
|
||||
f16c_target_feature,
|
||||
f32,
|
||||
f32_epsilon,
|
||||
f32_legacy_const_digits,
|
||||
f32_legacy_const_epsilon,
|
||||
f32_legacy_const_infinity,
|
||||
@ -851,6 +857,7 @@
|
||||
f32_legacy_const_radix,
|
||||
f32_nan,
|
||||
f64,
|
||||
f64_epsilon,
|
||||
f64_legacy_const_digits,
|
||||
f64_legacy_const_epsilon,
|
||||
f64_legacy_const_infinity,
|
||||
@ -888,6 +895,7 @@
|
||||
field,
|
||||
field_init_shorthand,
|
||||
file,
|
||||
file_options,
|
||||
float,
|
||||
float_to_int_unchecked,
|
||||
floorf128,
|
||||
@ -973,7 +981,17 @@
|
||||
half_open_range_patterns,
|
||||
half_open_range_patterns_in_slices,
|
||||
hash,
|
||||
hashmap_contains_key,
|
||||
hashmap_drain_ty,
|
||||
hashmap_insert,
|
||||
hashmap_iter_mut_ty,
|
||||
hashmap_iter_ty,
|
||||
hashmap_keys_ty,
|
||||
hashmap_values_mut_ty,
|
||||
hashmap_values_ty,
|
||||
hashset_drain_ty,
|
||||
hashset_iter,
|
||||
hashset_iter_ty,
|
||||
hexagon_target_feature,
|
||||
hidden,
|
||||
homogeneous_aggregate,
|
||||
@ -1052,6 +1070,7 @@
|
||||
inline_const,
|
||||
inline_const_pat,
|
||||
inout,
|
||||
instant_now,
|
||||
instruction_set,
|
||||
integer_: "integer", // underscore to avoid clashing with the function `sym::integer` below
|
||||
integral,
|
||||
@ -1352,6 +1371,7 @@
|
||||
on,
|
||||
on_unimplemented,
|
||||
opaque,
|
||||
open_options_new,
|
||||
ops,
|
||||
opt_out_copy,
|
||||
optimize,
|
||||
@ -1359,10 +1379,14 @@
|
||||
optin_builtin_traits,
|
||||
option,
|
||||
option_env,
|
||||
option_expect,
|
||||
option_unwrap,
|
||||
options,
|
||||
or,
|
||||
or_patterns,
|
||||
ord_cmp_method,
|
||||
os_str_to_os_string,
|
||||
os_string_as_os_str,
|
||||
other,
|
||||
out,
|
||||
overflow_checks,
|
||||
@ -1416,10 +1440,14 @@
|
||||
pat_param,
|
||||
patchable_function_entry,
|
||||
path,
|
||||
path_main_separator,
|
||||
path_to_pathbuf,
|
||||
pathbuf_as_path,
|
||||
pattern_complexity,
|
||||
pattern_parentheses,
|
||||
pattern_type,
|
||||
pattern_types,
|
||||
permissions_from_mode,
|
||||
phantom_data,
|
||||
pic,
|
||||
pie,
|
||||
@ -1571,6 +1599,7 @@
|
||||
residual,
|
||||
result,
|
||||
result_ffi_guarantees,
|
||||
result_ok_method,
|
||||
resume,
|
||||
return_position_impl_trait_in_trait,
|
||||
return_type_notation,
|
||||
@ -1823,6 +1852,7 @@
|
||||
slice,
|
||||
slice_from_raw_parts,
|
||||
slice_from_raw_parts_mut,
|
||||
slice_into_vec,
|
||||
slice_iter,
|
||||
slice_len_fn,
|
||||
slice_patterns,
|
||||
@ -1857,16 +1887,25 @@
|
||||
store,
|
||||
str,
|
||||
str_chars,
|
||||
str_ends_with,
|
||||
str_from_utf8,
|
||||
str_from_utf8_mut,
|
||||
str_from_utf8_unchecked,
|
||||
str_from_utf8_unchecked_mut,
|
||||
str_len,
|
||||
str_split_whitespace,
|
||||
str_starts_with,
|
||||
str_trim,
|
||||
str_trim_end,
|
||||
str_trim_start,
|
||||
strict_provenance,
|
||||
string_as_mut_str,
|
||||
string_as_str,
|
||||
string_deref_patterns,
|
||||
string_from_utf8,
|
||||
string_insert_str,
|
||||
string_new,
|
||||
string_push_str,
|
||||
stringify,
|
||||
struct_field_attributes,
|
||||
struct_inherit,
|
||||
@ -2071,7 +2110,14 @@
|
||||
var,
|
||||
variant_count,
|
||||
vec,
|
||||
vec_as_mut_slice,
|
||||
vec_as_slice,
|
||||
vec_from_elem,
|
||||
vec_is_empty,
|
||||
vec_macro,
|
||||
vec_new,
|
||||
vec_pop,
|
||||
vec_with_capacity,
|
||||
vecdeque_iter,
|
||||
version,
|
||||
vfp2,
|
||||
|
@ -10,7 +10,7 @@ pub(crate) fn target() -> Target {
|
||||
// ABI. Pass the -vector feature string to LLVM to respect this assumption. On LLVM < 16, we
|
||||
// also strip v128 from the data_layout below to match the older LLVM's expectation.
|
||||
base.features = "-vector".into();
|
||||
base.max_atomic_width = Some(64);
|
||||
base.max_atomic_width = Some(128);
|
||||
base.min_global_align = Some(16);
|
||||
base.stack_probes = StackProbeType::Inline;
|
||||
base.supported_sanitizers =
|
||||
|
@ -10,7 +10,7 @@ pub(crate) fn target() -> Target {
|
||||
// ABI. Pass the -vector feature string to LLVM to respect this assumption. On LLVM < 16, we
|
||||
// also strip v128 from the data_layout below to match the older LLVM's expectation.
|
||||
base.features = "-vector".into();
|
||||
base.max_atomic_width = Some(64);
|
||||
base.max_atomic_width = Some(128);
|
||||
base.min_global_align = Some(16);
|
||||
base.static_position_independent_executables = true;
|
||||
base.stack_probes = StackProbeType::Inline;
|
||||
|
@ -916,6 +916,7 @@ pub fn pop_last(&mut self) -> Option<(K, V)>
|
||||
/// assert_eq!(map.contains_key(&2), false);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "btreemap_contains_key")]
|
||||
pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool
|
||||
where
|
||||
K: Borrow<Q> + Ord,
|
||||
@ -981,6 +982,7 @@ pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V>
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_confusables("push", "put", "set")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "btreemap_insert")]
|
||||
pub fn insert(&mut self, key: K, value: V) -> Option<V>
|
||||
where
|
||||
K: Ord,
|
||||
|
@ -576,6 +576,7 @@ pub fn as_bytes_with_nul(&self) -> &[u8] {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "as_c_str", since = "1.20.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "cstring_as_c_str")]
|
||||
pub fn as_c_str(&self) -> &CStr {
|
||||
&*self
|
||||
}
|
||||
|
@ -496,6 +496,7 @@ pub fn to_vec_in<A: Allocator>(&self, alloc: A) -> Vec<T, A>
|
||||
#[rustc_allow_incoherent_impl]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "slice_into_vec")]
|
||||
pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> {
|
||||
// N.B., see the `hack` module in this file for more details.
|
||||
hack::into_vec(self)
|
||||
|
@ -440,6 +440,7 @@ impl String {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[rustc_const_stable(feature = "const_string_new", since = "1.39.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "string_new")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[must_use]
|
||||
pub const fn new() -> String {
|
||||
@ -571,6 +572,7 @@ pub fn from_str(_: &str) -> String {
|
||||
/// [`into_bytes`]: String::into_bytes
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "string_from_utf8")]
|
||||
pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
|
||||
match str::from_utf8(&vec) {
|
||||
Ok(..) => Ok(String { vec }),
|
||||
@ -1073,6 +1075,7 @@ pub fn into_bytes(self) -> Vec<u8> {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "string_as_str", since = "1.7.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "string_as_str")]
|
||||
pub fn as_str(&self) -> &str {
|
||||
self
|
||||
}
|
||||
@ -1092,6 +1095,7 @@ pub fn as_str(&self) -> &str {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "string_as_str", since = "1.7.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "string_as_mut_str")]
|
||||
pub fn as_mut_str(&mut self) -> &mut str {
|
||||
self
|
||||
}
|
||||
@ -1111,6 +1115,7 @@ pub fn as_mut_str(&mut self) -> &mut str {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_confusables("append", "push")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "string_push_str")]
|
||||
pub fn push_str(&mut self, string: &str) {
|
||||
self.vec.extend_from_slice(string.as_bytes())
|
||||
}
|
||||
@ -1745,6 +1750,7 @@ unsafe fn insert_bytes(&mut self, idx: usize, bytes: &[u8]) {
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[inline]
|
||||
#[stable(feature = "insert_str", since = "1.16.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "string_insert_str")]
|
||||
pub fn insert_str(&mut self, idx: usize, string: &str) {
|
||||
assert!(self.is_char_boundary(idx));
|
||||
|
||||
|
@ -416,6 +416,7 @@ impl<T> Vec<T> {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[rustc_const_stable(feature = "const_vec_new", since = "1.39.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_new")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[must_use]
|
||||
pub const fn new() -> Self {
|
||||
@ -476,6 +477,7 @@ pub const fn new() -> Self {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[must_use]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_with_capacity")]
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
Self::with_capacity_in(capacity, Global)
|
||||
}
|
||||
@ -1545,6 +1547,7 @@ pub fn truncate(&mut self, len: usize) {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "vec_as_slice", since = "1.7.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_as_slice")]
|
||||
pub fn as_slice(&self) -> &[T] {
|
||||
self
|
||||
}
|
||||
@ -1562,6 +1565,7 @@ pub fn as_slice(&self) -> &[T] {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "vec_as_slice", since = "1.7.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_as_mut_slice")]
|
||||
pub fn as_mut_slice(&mut self) -> &mut [T] {
|
||||
self
|
||||
}
|
||||
@ -2380,6 +2384,7 @@ pub fn push_within_capacity(&mut self, value: T) -> Result<(), T> {
|
||||
/// Takes *O*(1) time.
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_pop")]
|
||||
pub fn pop(&mut self) -> Option<T> {
|
||||
if self.len == 0 {
|
||||
None
|
||||
@ -2573,6 +2578,7 @@ pub fn len(&self) -> usize {
|
||||
/// assert!(!v.is_empty());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_is_empty")]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
@ -3044,6 +3050,7 @@ pub fn dedup(&mut self) {
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_from_elem")]
|
||||
pub fn from_elem<T: Clone>(elem: T, n: usize) -> Vec<T> {
|
||||
<T as SpecFromElem>::from_elem(elem, n, Global)
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ pub fn then_some<T>(self, t: T) -> Option<T> {
|
||||
/// assert_eq!(a, 1);
|
||||
/// ```
|
||||
#[stable(feature = "lazy_bool_to_option", since = "1.50.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "bool_then")]
|
||||
#[inline]
|
||||
pub fn then<T, F: FnOnce() -> T>(self, f: F) -> Option<T> {
|
||||
if self { Some(f()) } else { None }
|
||||
|
@ -415,6 +415,7 @@ impl f32 {
|
||||
/// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon
|
||||
/// [`MANTISSA_DIGITS`]: f32::MANTISSA_DIGITS
|
||||
#[stable(feature = "assoc_int_consts", since = "1.43.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "f32_epsilon")]
|
||||
pub const EPSILON: f32 = 1.19209290e-07_f32;
|
||||
|
||||
/// Smallest finite `f32` value.
|
||||
|
@ -414,6 +414,7 @@ impl f64 {
|
||||
/// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon
|
||||
/// [`MANTISSA_DIGITS`]: f64::MANTISSA_DIGITS
|
||||
#[stable(feature = "assoc_int_consts", since = "1.43.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "f64_epsilon")]
|
||||
pub const EPSILON: f64 = 2.2204460492503131e-16_f64;
|
||||
|
||||
/// Smallest finite `f64` value.
|
||||
|
@ -23,6 +23,16 @@ macro_rules! unlikely {
|
||||
};
|
||||
}
|
||||
|
||||
// Use this when the generated code should differ between signed and unsigned types.
|
||||
macro_rules! sign_dependent_expr {
|
||||
(signed ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => {
|
||||
$signed_case
|
||||
};
|
||||
(unsigned ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => {
|
||||
$unsigned_case
|
||||
};
|
||||
}
|
||||
|
||||
// All these modules are technically private and only exposed for coretests:
|
||||
#[cfg(not(no_fp_fmt_parse))]
|
||||
pub mod bignum;
|
||||
@ -1410,15 +1420,25 @@ const fn from_str_radix_panic(radix: u32) {
|
||||
}
|
||||
|
||||
macro_rules! from_str_radix {
|
||||
($($int_ty:ty)+) => {$(
|
||||
($signedness:ident $($int_ty:ty)+) => {$(
|
||||
impl $int_ty {
|
||||
/// Converts a string slice in a given base to an integer.
|
||||
///
|
||||
/// The string is expected to be an optional `+` sign
|
||||
/// followed by digits.
|
||||
/// Leading and trailing whitespace represent an error.
|
||||
/// Digits are a subset of these characters, depending on `radix`:
|
||||
/// The string is expected to be an optional
|
||||
#[doc = sign_dependent_expr!{
|
||||
$signedness ?
|
||||
if signed {
|
||||
" `+` or `-` "
|
||||
}
|
||||
if unsigned {
|
||||
" `+` "
|
||||
}
|
||||
}]
|
||||
/// sign followed by only digits. Leading and trailing non-digit characters (including
|
||||
/// whitespace) represent an error. Underscores (which are accepted in rust literals)
|
||||
/// also represent an error.
|
||||
///
|
||||
/// Digits are a subset of these characters, depending on `radix`:
|
||||
/// * `0-9`
|
||||
/// * `a-z`
|
||||
/// * `A-Z`
|
||||
@ -1430,10 +1450,13 @@ impl $int_ty {
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
#[doc = concat!("assert_eq!(", stringify!($int_ty), "::from_str_radix(\"A\", 16), Ok(10));")]
|
||||
/// ```
|
||||
/// Trailing space returns error:
|
||||
/// ```
|
||||
#[doc = concat!("assert!(", stringify!($int_ty), "::from_str_radix(\"1 \", 10).is_err());")]
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_stable(feature = "const_int_from_str", since = "1.82.0")]
|
||||
pub const fn from_str_radix(src: &str, radix: u32) -> Result<$int_ty, ParseIntError> {
|
||||
@ -1535,20 +1558,31 @@ macro_rules! run_checked_loop {
|
||||
)+}
|
||||
}
|
||||
|
||||
from_str_radix! { i8 u8 i16 u16 i32 u32 i64 u64 i128 u128 }
|
||||
from_str_radix! { unsigned u8 u16 u32 u64 u128 }
|
||||
from_str_radix! { signed i8 i16 i32 i64 i128 }
|
||||
|
||||
// Re-use the relevant implementation of from_str_radix for isize and usize to avoid outputting two
|
||||
// identical functions.
|
||||
macro_rules! from_str_radix_size_impl {
|
||||
($($t:ident $size:ty),*) => {$(
|
||||
($($signedness:ident $t:ident $size:ty),*) => {$(
|
||||
impl $size {
|
||||
/// Converts a string slice in a given base to an integer.
|
||||
///
|
||||
/// The string is expected to be an optional `+` sign
|
||||
/// followed by digits.
|
||||
/// Leading and trailing whitespace represent an error.
|
||||
/// Digits are a subset of these characters, depending on `radix`:
|
||||
/// The string is expected to be an optional
|
||||
#[doc = sign_dependent_expr!{
|
||||
$signedness ?
|
||||
if signed {
|
||||
" `+` or `-` "
|
||||
}
|
||||
if unsigned {
|
||||
" `+` "
|
||||
}
|
||||
}]
|
||||
/// sign followed by only digits. Leading and trailing non-digit characters (including
|
||||
/// whitespace) represent an error. Underscores (which are accepted in rust literals)
|
||||
/// also represent an error.
|
||||
///
|
||||
/// Digits are a subset of these characters, depending on `radix`:
|
||||
/// * `0-9`
|
||||
/// * `a-z`
|
||||
/// * `A-Z`
|
||||
@ -1560,10 +1594,13 @@ impl $size {
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
#[doc = concat!("assert_eq!(", stringify!($size), "::from_str_radix(\"A\", 16), Ok(10));")]
|
||||
/// ```
|
||||
/// Trailing space returns error:
|
||||
/// ```
|
||||
#[doc = concat!("assert!(", stringify!($size), "::from_str_radix(\"1 \", 10).is_err());")]
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_stable(feature = "const_int_from_str", since = "1.82.0")]
|
||||
pub const fn from_str_radix(src: &str, radix: u32) -> Result<$size, ParseIntError> {
|
||||
@ -1576,8 +1613,8 @@ pub const fn from_str_radix(src: &str, radix: u32) -> Result<$size, ParseIntErro
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "16")]
|
||||
from_str_radix_size_impl! { i16 isize, u16 usize }
|
||||
from_str_radix_size_impl! { signed i16 isize, unsigned u16 usize }
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
from_str_radix_size_impl! { i32 isize, u32 usize }
|
||||
from_str_radix_size_impl! { signed i32 isize, unsigned u32 usize }
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
from_str_radix_size_impl! { i64 isize, u64 usize }
|
||||
from_str_radix_size_impl! { signed i64 isize, unsigned u64 usize }
|
||||
|
@ -1972,16 +1972,6 @@ pub const fn wrapping_neg(self) -> Self {
|
||||
};
|
||||
}
|
||||
|
||||
// Use this when the generated code should differ between signed and unsigned types.
|
||||
macro_rules! sign_dependent_expr {
|
||||
(signed ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => {
|
||||
$signed_case
|
||||
};
|
||||
(unsigned ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => {
|
||||
$unsigned_case
|
||||
};
|
||||
}
|
||||
|
||||
nonzero_integer! {
|
||||
Self = NonZeroU8,
|
||||
Primitive = unsigned u8,
|
||||
|
@ -923,6 +923,7 @@ pub const fn as_mut_slice(&mut self) -> &mut [T] {
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "option_expect")]
|
||||
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
|
||||
pub const fn expect(self, msg: &str) -> T {
|
||||
match self {
|
||||
@ -960,6 +961,7 @@ pub const fn expect(self, msg: &str) -> T {
|
||||
#[inline(always)]
|
||||
#[track_caller]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "option_unwrap")]
|
||||
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
|
||||
pub const fn unwrap(self) -> T {
|
||||
match self {
|
||||
|
@ -653,6 +653,7 @@ pub fn is_err_and(self, f: impl FnOnce(E) -> bool) -> bool {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "result_ok_method")]
|
||||
pub fn ok(self) -> Option<T> {
|
||||
match self {
|
||||
Ok(x) => Some(x),
|
||||
|
@ -134,6 +134,7 @@ impl str {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_stable(feature = "const_str_len", since = "1.39.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "str_len")]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub const fn len(&self) -> usize {
|
||||
@ -1157,6 +1158,7 @@ pub fn contains<P: Pattern>(&self, pat: P) -> bool {
|
||||
/// assert!(bananas.starts_with(&['a', 'b', 'c', 'd']));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "str_starts_with")]
|
||||
pub fn starts_with<P: Pattern>(&self, pat: P) -> bool {
|
||||
pat.is_prefix_of(self)
|
||||
}
|
||||
@ -1181,6 +1183,7 @@ pub fn starts_with<P: Pattern>(&self, pat: P) -> bool {
|
||||
/// assert!(!bananas.ends_with("nana"));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "str_ends_with")]
|
||||
pub fn ends_with<P: Pattern>(&self, pat: P) -> bool
|
||||
where
|
||||
for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
|
||||
|
@ -414,6 +414,7 @@ pub const fn build(self) -> Context<'a> {
|
||||
/// [`Wake`]: ../../alloc/task/trait.Wake.html
|
||||
#[repr(transparent)]
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "Waker")]
|
||||
pub struct Waker {
|
||||
waker: RawWaker,
|
||||
}
|
||||
|
@ -244,6 +244,8 @@ fn test_from_str_radix() {
|
||||
|
||||
assert_eq!($T::from_str_radix("Z", 35).ok(), None::<$T>);
|
||||
assert_eq!($T::from_str_radix("-9", 2).ok(), None::<$T>);
|
||||
assert_eq!($T::from_str_radix("10_0", 10).ok(), None::<$T>);
|
||||
assert_eq!(u32::from_str_radix("-9", 10).ok(), None::<u32>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1037,6 +1037,7 @@ pub unsafe fn get_many_unchecked_mut<Q: ?Sized, const N: usize>(
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_contains_key")]
|
||||
pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
@ -1100,6 +1101,7 @@ pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_confusables("push", "append", "put")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_insert")]
|
||||
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
|
||||
self.base.insert(k, v)
|
||||
}
|
||||
@ -1391,6 +1393,7 @@ fn index(&self, key: &Q) -> &V {
|
||||
/// let iter = map.iter();
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_iter_ty")]
|
||||
pub struct Iter<'a, K: 'a, V: 'a> {
|
||||
base: base::Iter<'a, K, V>,
|
||||
}
|
||||
@ -1429,6 +1432,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
/// let iter = map.iter_mut();
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_iter_mut_ty")]
|
||||
pub struct IterMut<'a, K: 'a, V: 'a> {
|
||||
base: base::IterMut<'a, K, V>,
|
||||
}
|
||||
@ -1489,6 +1493,7 @@ pub(super) fn iter(&self) -> Iter<'_, K, V> {
|
||||
/// let iter_keys = map.keys();
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_keys_ty")]
|
||||
pub struct Keys<'a, K: 'a, V: 'a> {
|
||||
inner: Iter<'a, K, V>,
|
||||
}
|
||||
@ -1527,6 +1532,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
/// let iter_values = map.values();
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_values_ty")]
|
||||
pub struct Values<'a, K: 'a, V: 'a> {
|
||||
inner: Iter<'a, K, V>,
|
||||
}
|
||||
@ -1565,6 +1571,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
/// let iter = map.drain();
|
||||
/// ```
|
||||
#[stable(feature = "drain", since = "1.6.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_drain_ty")]
|
||||
pub struct Drain<'a, K: 'a, V: 'a> {
|
||||
base: base::Drain<'a, K, V>,
|
||||
}
|
||||
@ -1622,6 +1629,7 @@ pub struct ExtractIf<'a, K, V, F>
|
||||
/// let iter_values = map.values_mut();
|
||||
/// ```
|
||||
#[stable(feature = "map_values_mut", since = "1.10.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_values_mut_ty")]
|
||||
pub struct ValuesMut<'a, K: 'a, V: 'a> {
|
||||
inner: IterMut<'a, K, V>,
|
||||
}
|
||||
|
@ -1271,6 +1271,7 @@ fn sub(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
|
||||
/// let mut iter = a.iter();
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "hashset_iter_ty")]
|
||||
pub struct Iter<'a, K: 'a> {
|
||||
base: base::Iter<'a, K>,
|
||||
}
|
||||
@ -1313,6 +1314,7 @@ pub struct IntoIter<K> {
|
||||
/// let mut drain = a.drain();
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "hashset_drain_ty")]
|
||||
pub struct Drain<'a, K: 'a> {
|
||||
base: base::Drain<'a, K>,
|
||||
}
|
||||
|
@ -196,6 +196,7 @@ pub unsafe fn from_encoded_bytes_unchecked(bytes: Vec<u8>) -> Self {
|
||||
/// let os_str = OsStr::new("foo");
|
||||
/// assert_eq!(os_string.as_os_str(), os_str);
|
||||
/// ```
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "os_string_as_os_str")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
@ -918,6 +919,7 @@ pub fn to_string_lossy(&self) -> Cow<'_, str> {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "os_str_to_os_string")]
|
||||
pub fn to_os_string(&self) -> OsString {
|
||||
OsString { inner: self.inner.to_owned() }
|
||||
}
|
||||
|
@ -466,6 +466,7 @@ pub fn create_new<P: AsRef<Path>>(path: P) -> io::Result<File> {
|
||||
/// ```
|
||||
#[must_use]
|
||||
#[stable(feature = "with_options", since = "1.58.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "file_options")]
|
||||
pub fn options() -> OpenOptions {
|
||||
OpenOptions::new()
|
||||
}
|
||||
@ -1009,6 +1010,7 @@ impl OpenOptions {
|
||||
/// let mut options = OpenOptions::new();
|
||||
/// let file = options.read(true).open("foo.txt");
|
||||
/// ```
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "open_options_new")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
|
@ -334,6 +334,7 @@ pub trait PermissionsExt {
|
||||
/// assert_eq!(permissions.mode(), 0o644);
|
||||
/// ```
|
||||
#[stable(feature = "fs_ext", since = "1.1.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "permissions_from_mode")]
|
||||
fn from_mode(mode: u32) -> Self;
|
||||
}
|
||||
|
||||
|
@ -263,6 +263,7 @@ pub fn is_separator(c: char) -> bool {
|
||||
///
|
||||
/// For example, `/` on Unix and `\` on Windows.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "path_main_separator")]
|
||||
pub const MAIN_SEPARATOR: char = crate::sys::path::MAIN_SEP;
|
||||
|
||||
/// The primary separator of path components for the current platform.
|
||||
@ -1226,6 +1227,7 @@ pub fn with_capacity(capacity: usize) -> PathBuf {
|
||||
/// let p = PathBuf::from("/test");
|
||||
/// assert_eq!(Path::new("/test"), p.as_path());
|
||||
/// ```
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "pathbuf_as_path")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
@ -2264,6 +2266,7 @@ pub fn to_string_lossy(&self) -> Cow<'_, str> {
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "path_to_pathbuf")]
|
||||
pub fn to_path_buf(&self) -> PathBuf {
|
||||
PathBuf::from(self.inner.to_os_string())
|
||||
}
|
||||
|
@ -255,11 +255,11 @@ pub fn code(self) -> Option<NonZero<i32>> {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
pub struct ExitCode(bool);
|
||||
pub struct ExitCode(u8);
|
||||
|
||||
impl ExitCode {
|
||||
pub const SUCCESS: ExitCode = ExitCode(false);
|
||||
pub const FAILURE: ExitCode = ExitCode(true);
|
||||
pub const SUCCESS: ExitCode = ExitCode(0);
|
||||
pub const FAILURE: ExitCode = ExitCode(1);
|
||||
|
||||
pub fn as_i32(&self) -> i32 {
|
||||
self.0 as i32
|
||||
@ -268,10 +268,7 @@ pub fn as_i32(&self) -> i32 {
|
||||
|
||||
impl From<u8> for ExitCode {
|
||||
fn from(code: u8) -> Self {
|
||||
match code {
|
||||
0 => Self::SUCCESS,
|
||||
1..=255 => Self::FAILURE,
|
||||
}
|
||||
Self(code)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -280,6 +280,7 @@ impl Instant {
|
||||
/// ```
|
||||
#[must_use]
|
||||
#[stable(feature = "time2", since = "1.8.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "instant_now")]
|
||||
pub fn now() -> Instant {
|
||||
Instant(time::Instant::now())
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::{reindent_multiline, snippet_indent, snippet_with_applicability, snippet_with_context};
|
||||
use clippy_utils::{
|
||||
can_move_expr_to_closure_no_visit, higher, is_expr_final_block_expr, is_expr_used_or_unified, match_def_path,
|
||||
paths, peel_hir_expr_while, SpanlessEq,
|
||||
can_move_expr_to_closure_no_visit, higher, is_expr_final_block_expr, is_expr_used_or_unified,
|
||||
peel_hir_expr_while, SpanlessEq,
|
||||
};
|
||||
use core::fmt::{self, Write};
|
||||
use rustc_errors::Applicability;
|
||||
@ -11,7 +11,7 @@
|
||||
use rustc_hir::{Block, Expr, ExprKind, HirId, Pat, Stmt, StmtKind, UnOp};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::{Span, SyntaxContext, DUMMY_SP};
|
||||
use rustc_span::{sym, Span, SyntaxContext, DUMMY_SP};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
@ -269,9 +269,9 @@ fn try_parse_contains<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Optio
|
||||
key,
|
||||
call_ctxt: expr.span.ctxt(),
|
||||
};
|
||||
if match_def_path(cx, id, &paths::BTREEMAP_CONTAINS_KEY) {
|
||||
if cx.tcx.is_diagnostic_item(sym::btreemap_contains_key, id) {
|
||||
Some((MapType::BTree, expr))
|
||||
} else if match_def_path(cx, id, &paths::HASHMAP_CONTAINS_KEY) {
|
||||
} else if cx.tcx.is_diagnostic_item(sym::hashmap_contains_key, id) {
|
||||
Some((MapType::Hash, expr))
|
||||
} else {
|
||||
None
|
||||
@ -306,7 +306,7 @@ struct InsertExpr<'tcx> {
|
||||
fn try_parse_insert<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<InsertExpr<'tcx>> {
|
||||
if let ExprKind::MethodCall(_, map, [key, value], _) = expr.kind {
|
||||
let id = cx.typeck_results().type_dependent_def_id(expr.hir_id)?;
|
||||
if match_def_path(cx, id, &paths::BTREEMAP_INSERT) || match_def_path(cx, id, &paths::HASHMAP_INSERT) {
|
||||
if cx.tcx.is_diagnostic_item(sym::btreemap_insert, id) || cx.tcx.is_diagnostic_item(sym::hashmap_insert, id) {
|
||||
Some(InsertExpr { map, key, value })
|
||||
} else {
|
||||
None
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use clippy_utils::{higher, match_def_path, paths};
|
||||
use clippy_utils::higher;
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind, LangItem, MatchSource};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
@ -70,7 +70,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
let arg = match expr.kind {
|
||||
ExprKind::MethodCall(_, _, [arg], _) => {
|
||||
if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
|
||||
&& match_def_path(cx, fn_def_id, &paths::PUSH_STR)
|
||||
&& cx.tcx.is_diagnostic_item(sym::string_push_str, fn_def_id)
|
||||
{
|
||||
arg
|
||||
} else {
|
||||
|
@ -112,7 +112,7 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
|
||||
fn is_instant_now_call(cx: &LateContext<'_>, expr_block: &'_ Expr<'_>) -> bool {
|
||||
if let ExprKind::Call(fn_expr, []) = expr_block.kind
|
||||
&& let Some(fn_id) = clippy_utils::path_def_id(cx, fn_expr)
|
||||
&& clippy_utils::match_def_path(cx, fn_id, &clippy_utils::paths::INSTANT_NOW)
|
||||
&& cx.tcx.is_diagnostic_item(sym::instant_now, fn_id)
|
||||
{
|
||||
true
|
||||
} else {
|
||||
|
@ -1,10 +1,5 @@
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::higher::ForLoop;
|
||||
use clippy_utils::match_any_def_paths;
|
||||
use clippy_utils::paths::{
|
||||
HASHMAP_DRAIN, HASHMAP_ITER, HASHMAP_ITER_MUT, HASHMAP_KEYS, HASHMAP_VALUES, HASHMAP_VALUES_MUT, HASHSET_DRAIN,
|
||||
HASHSET_ITER_TY,
|
||||
};
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
@ -44,28 +39,23 @@
|
||||
|
||||
impl LateLintPass<'_> for IterOverHashType {
|
||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>) {
|
||||
let hash_iter_tys = [
|
||||
sym::HashMap,
|
||||
sym::HashSet,
|
||||
sym::hashmap_keys_ty,
|
||||
sym::hashmap_values_ty,
|
||||
sym::hashmap_values_mut_ty,
|
||||
sym::hashmap_iter_ty,
|
||||
sym::hashmap_iter_mut_ty,
|
||||
sym::hashmap_drain_ty,
|
||||
sym::hashset_iter_ty,
|
||||
sym::hashset_drain_ty,
|
||||
];
|
||||
|
||||
if let Some(for_loop) = ForLoop::hir(expr)
|
||||
&& !for_loop.body.span.from_expansion()
|
||||
&& let ty = cx.typeck_results().expr_ty(for_loop.arg).peel_refs()
|
||||
&& let Some(adt) = ty.ty_adt_def()
|
||||
&& let did = adt.did()
|
||||
&& (match_any_def_paths(
|
||||
cx,
|
||||
did,
|
||||
&[
|
||||
&HASHMAP_KEYS,
|
||||
&HASHMAP_VALUES,
|
||||
&HASHMAP_VALUES_MUT,
|
||||
&HASHMAP_ITER,
|
||||
&HASHMAP_ITER_MUT,
|
||||
&HASHMAP_DRAIN,
|
||||
&HASHSET_ITER_TY,
|
||||
&HASHSET_DRAIN,
|
||||
],
|
||||
)
|
||||
.is_some()
|
||||
|| is_type_diagnostic_item(cx, ty, sym::HashMap)
|
||||
|| is_type_diagnostic_item(cx, ty, sym::HashSet))
|
||||
&& hash_iter_tys.into_iter().any(|sym| is_type_diagnostic_item(cx, ty, sym))
|
||||
{
|
||||
span_lint(
|
||||
cx,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
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 clippy_utils::{is_diag_item_method, is_trait_method, path_to_local_id};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Body, Closure, Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
@ -96,7 +96,7 @@ fn should_lint(cx: &LateContext<'_>, args: &[Expr<'_>], method_str: &str) -> boo
|
||||
ExprKind::Path(qpath) => cx
|
||||
.qpath_res(qpath, fm_arg.hir_id)
|
||||
.opt_def_id()
|
||||
.is_some_and(|did| match_def_path(cx, did, &paths::CORE_RESULT_OK_METHOD)),
|
||||
.is_some_and(|did| cx.tcx.is_diagnostic_item(sym::result_ok_method, did)),
|
||||
// Detect `|x| x.ok()`
|
||||
ExprKind::Closure(Closure { body, .. }) => {
|
||||
if let Body {
|
||||
|
@ -1,10 +1,10 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::{match_def_path, paths, SpanlessEq};
|
||||
use clippy_utils::SpanlessEq;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, Pat, Stmt, StmtKind, UnOp};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::{sym, Symbol, Span};
|
||||
use std::borrow::Cow;
|
||||
|
||||
use super::MANUAL_WHILE_LET_SOME;
|
||||
@ -47,20 +47,20 @@ fn report_lint(cx: &LateContext<'_>, pop_span: Span, pop_stmt_kind: PopStmt<'_>,
|
||||
);
|
||||
}
|
||||
|
||||
fn match_method_call(cx: &LateContext<'_>, expr: &Expr<'_>, method: &[&str]) -> bool {
|
||||
fn match_method_call(cx: &LateContext<'_>, expr: &Expr<'_>, method: Symbol) -> bool {
|
||||
if let ExprKind::MethodCall(..) = expr.kind
|
||||
&& let Some(id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
|
||||
{
|
||||
match_def_path(cx, id, method)
|
||||
cx.tcx.is_diagnostic_item(method, id)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_vec_pop_unwrap(cx: &LateContext<'_>, expr: &Expr<'_>, is_empty_recv: &Expr<'_>) -> bool {
|
||||
if (match_method_call(cx, expr, &paths::OPTION_UNWRAP) || match_method_call(cx, expr, &paths::OPTION_EXPECT))
|
||||
if (match_method_call(cx, expr, sym::option_unwrap) || match_method_call(cx, expr, sym::option_expect))
|
||||
&& let ExprKind::MethodCall(_, unwrap_recv, ..) = expr.kind
|
||||
&& match_method_call(cx, unwrap_recv, &paths::VEC_POP)
|
||||
&& match_method_call(cx, unwrap_recv, sym::vec_pop)
|
||||
&& let ExprKind::MethodCall(_, pop_recv, ..) = unwrap_recv.kind
|
||||
{
|
||||
// make sure they're the same `Vec`
|
||||
@ -96,7 +96,7 @@ fn check_call_arguments(cx: &LateContext<'_>, stmt: &Stmt<'_>, is_empty_recv: &E
|
||||
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, full_cond: &'tcx Expr<'_>, body: &'tcx Expr<'_>, loop_span: Span) {
|
||||
if let ExprKind::Unary(UnOp::Not, cond) = full_cond.kind
|
||||
&& let ExprKind::MethodCall(_, is_empty_recv, _, _) = cond.kind
|
||||
&& match_method_call(cx, cond, &paths::VEC_IS_EMPTY)
|
||||
&& match_method_call(cx, cond, sym::vec_is_empty)
|
||||
&& let ExprKind::Block(body, _) = body.kind
|
||||
&& let Some(stmt) = body.stmts.first()
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
use clippy_config::msrvs::{self, Msrv};
|
||||
use clippy_config::Conf;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::{is_trait_method, match_def_path, paths, peel_hir_expr_refs};
|
||||
use clippy_utils::{is_trait_method, peel_hir_expr_refs};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::{Expr, ExprKind, Mutability, QPath};
|
||||
@ -56,7 +56,7 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||
&& let Res::Def(DefKind::Const, receiver_def_id) = path.res
|
||||
&& is_trait_method(cx, target, sym::ToString)
|
||||
&& self.msrv.meets(msrvs::PATH_MAIN_SEPARATOR_STR)
|
||||
&& match_def_path(cx, receiver_def_id, &paths::PATH_MAIN_SEPARATOR)
|
||||
&& cx.tcx.is_diagnostic_item(sym::path_main_separator, receiver_def_id)
|
||||
&& let ty::Ref(_, ty, Mutability::Not) = cx.typeck_results().expr_ty_adjusted(expr).kind()
|
||||
&& ty.is_str()
|
||||
{
|
||||
|
@ -4,7 +4,7 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::usage::mutated_variables;
|
||||
use clippy_utils::{eq_expr_value, higher, match_def_path, paths};
|
||||
use clippy_utils::{eq_expr_value, higher};
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::Res;
|
||||
@ -14,7 +14,7 @@
|
||||
use rustc_middle::ty;
|
||||
use rustc_session::impl_lint_pass;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::{sym, Span};
|
||||
use std::iter;
|
||||
|
||||
declare_clippy_lint! {
|
||||
@ -76,9 +76,9 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
&& self.msrv.meets(msrvs::STR_STRIP_PREFIX)
|
||||
&& let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(cond.hir_id)
|
||||
{
|
||||
let strip_kind = if match_def_path(cx, method_def_id, &paths::STR_STARTS_WITH) {
|
||||
let strip_kind = if cx.tcx.is_diagnostic_item(sym::str_starts_with, method_def_id) {
|
||||
StripKind::Prefix
|
||||
} else if match_def_path(cx, method_def_id, &paths::STR_ENDS_WITH) {
|
||||
} else if cx.tcx.is_diagnostic_item(sym::str_ends_with, method_def_id) {
|
||||
StripKind::Suffix
|
||||
} else {
|
||||
return;
|
||||
@ -137,7 +137,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
fn len_arg<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
|
||||
if let ExprKind::MethodCall(_, arg, [], _) = expr.kind
|
||||
&& let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
|
||||
&& match_def_path(cx, method_def_id, &paths::STR_LEN)
|
||||
&& cx.tcx.is_diagnostic_item(sym::str_len, method_def_id)
|
||||
{
|
||||
Some(arg)
|
||||
} else {
|
||||
|
@ -1,9 +1,8 @@
|
||||
use super::FILTER_MAP_BOOL_THEN;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::paths::BOOL_THEN;
|
||||
use clippy_utils::source::SpanRangeExt;
|
||||
use clippy_utils::ty::is_copy;
|
||||
use clippy_utils::{is_from_proc_macro, is_trait_method, match_def_path, peel_blocks};
|
||||
use clippy_utils::{is_from_proc_macro, is_trait_method, peel_blocks};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LintContext};
|
||||
@ -35,7 +34,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &
|
||||
&& let ExprKind::Closure(then_closure) = then_arg.kind
|
||||
&& let then_body = peel_blocks(cx.tcx.hir().body(then_closure.body).value)
|
||||
&& let Some(def_id) = cx.typeck_results().type_dependent_def_id(value.hir_id)
|
||||
&& match_def_path(cx, def_id, &BOOL_THEN)
|
||||
&& cx.tcx.is_diagnostic_item(sym::bool_then, def_id)
|
||||
&& !is_from_proc_macro(cx, expr)
|
||||
// Count the number of derefs needed to get to the bool because we need those in the suggestion
|
||||
&& let needed_derefs = cx.typeck_results().expr_adjustments(recv)
|
||||
|
@ -126,17 +126,18 @@ fn get_open_options(
|
||||
&& let ExprKind::Path(path) = callee.kind
|
||||
&& let Some(did) = cx.qpath_res(&path, callee.hir_id).opt_def_id()
|
||||
{
|
||||
match_any_def_paths(
|
||||
cx,
|
||||
did,
|
||||
&[
|
||||
let std_file_options = [
|
||||
sym::file_options,
|
||||
sym::open_options_new,
|
||||
];
|
||||
|
||||
let tokio_file_options: &[&[&str]] = &[
|
||||
&paths::TOKIO_IO_OPEN_OPTIONS_NEW,
|
||||
&paths::OPEN_OPTIONS_NEW,
|
||||
&paths::FILE_OPTIONS,
|
||||
&paths::TOKIO_FILE_OPTIONS,
|
||||
],
|
||||
)
|
||||
.is_some()
|
||||
];
|
||||
|
||||
let is_std_options = std_file_options.into_iter().any(|sym| cx.tcx.is_diagnostic_item(sym, did));
|
||||
is_std_options || match_any_def_paths(cx, did, tokio_file_options).is_some()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
@ -2,12 +2,12 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{match_def_path, path_to_local_id, paths, peel_blocks};
|
||||
use clippy_utils::{path_to_local_id, peel_blocks};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty;
|
||||
use rustc_span::sym;
|
||||
use rustc_span::{sym, Symbol};
|
||||
|
||||
use super::OPTION_AS_REF_DEREF;
|
||||
|
||||
@ -31,14 +31,14 @@ pub(super) fn check(
|
||||
return;
|
||||
}
|
||||
|
||||
let deref_aliases: [&[&str]; 7] = [
|
||||
&paths::CSTRING_AS_C_STR,
|
||||
&paths::OS_STRING_AS_OS_STR,
|
||||
&paths::PATH_BUF_AS_PATH,
|
||||
&paths::STRING_AS_STR,
|
||||
&paths::STRING_AS_MUT_STR,
|
||||
&paths::VEC_AS_SLICE,
|
||||
&paths::VEC_AS_MUT_SLICE,
|
||||
let deref_aliases: [Symbol; 7] = [
|
||||
sym::cstring_as_c_str,
|
||||
sym::os_string_as_os_str,
|
||||
sym::pathbuf_as_path,
|
||||
sym::string_as_str,
|
||||
sym::string_as_mut_str,
|
||||
sym::vec_as_slice,
|
||||
sym::vec_as_mut_slice,
|
||||
];
|
||||
|
||||
let is_deref = match map_arg.kind {
|
||||
@ -48,7 +48,7 @@ pub(super) fn check(
|
||||
.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))
|
||||
|| deref_aliases.iter().any(|&sym| cx.tcx.is_diagnostic_item(sym, fun_def_id))
|
||||
})
|
||||
},
|
||||
hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
|
||||
@ -69,7 +69,7 @@ pub(super) fn check(
|
||||
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))
|
||||
|| deref_aliases.iter().any(|&sym| cx.tcx.is_diagnostic_item(sym, method_did))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
use crate::methods::{single_char_insert_string, single_char_push_string};
|
||||
use clippy_utils::{match_def_path, paths};
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::sym;
|
||||
|
||||
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
|
||||
if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {
|
||||
if match_def_path(cx, fn_def_id, &paths::PUSH_STR) {
|
||||
if cx.tcx.is_diagnostic_item(sym::string_push_str, fn_def_id) {
|
||||
single_char_push_string::check(cx, expr, receiver, args);
|
||||
} else if match_def_path(cx, fn_def_id, &paths::INSERT_STR) {
|
||||
} else if cx.tcx.is_diagnostic_item(sym::string_insert_str, fn_def_id) {
|
||||
single_char_insert_string::check(cx, expr, receiver, args);
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy, is_type_diagnostic_item, is_type_lang_item};
|
||||
use clippy_utils::visitors::find_all_ret_expressions;
|
||||
use clippy_utils::{
|
||||
fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, match_def_path, paths, peel_middle_ty_refs,
|
||||
fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, peel_middle_ty_refs,
|
||||
return_ty,
|
||||
};
|
||||
use rustc_errors::Applicability;
|
||||
@ -250,7 +250,7 @@ fn check_string_from_utf8<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>,
|
||||
if let Some((call, arg)) = skip_addr_of_ancestors(cx, expr)
|
||||
&& !arg.span.from_expansion()
|
||||
&& let ExprKind::Call(callee, _) = call.kind
|
||||
&& fn_def_id(cx, call).is_some_and(|did| match_def_path(cx, did, &paths::STRING_FROM_UTF8))
|
||||
&& fn_def_id(cx, call).is_some_and(|did| cx.tcx.is_diagnostic_item(sym::string_from_utf8, did))
|
||||
&& let Some(unwrap_call) = get_parent_expr(cx, call)
|
||||
&& let ExprKind::MethodCall(unwrap_method_name, ..) = unwrap_call.kind
|
||||
&& matches!(unwrap_method_name.ident.name, sym::unwrap | sym::expect)
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::{is_trait_method, match_def_path, paths};
|
||||
use clippy_utils::is_trait_method;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::LateContext;
|
||||
@ -12,7 +12,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'
|
||||
let ty = cx.typeck_results().expr_ty(recv);
|
||||
|
||||
if let Some(did) = ty.ty_adt_def()
|
||||
&& match_def_path(cx, did.did(), &paths::WAKER)
|
||||
&& cx.tcx.is_diagnostic_item(sym::Waker, did.did())
|
||||
&& let ExprKind::MethodCall(_, waker_ref, &[], _) = recv.kind
|
||||
&& is_trait_method(cx, recv, sym::Clone)
|
||||
{
|
||||
|
@ -1,6 +1,5 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::{snippet_with_applicability, SpanRangeExt};
|
||||
use clippy_utils::{match_def_path, paths};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
@ -63,7 +62,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||
ExprKind::Call(func, [param]) => {
|
||||
if let ExprKind::Path(ref path) = func.kind
|
||||
&& let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id()
|
||||
&& match_def_path(cx, def_id, &paths::PERMISSIONS_FROM_MODE)
|
||||
&& cx.tcx.is_diagnostic_item(sym::permissions_from_mode, def_id)
|
||||
&& let ExprKind::Lit(_) = param.kind
|
||||
&& param.span.eq_ctxt(expr.span)
|
||||
&& param
|
||||
|
@ -1,12 +1,12 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::{match_def_path, paths, sugg};
|
||||
use clippy_utils::sugg;
|
||||
use rustc_ast::util::parser::AssocOp;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::{sym, source_map::Spanned};
|
||||
|
||||
use super::FLOAT_EQUALITY_WITHOUT_ABS;
|
||||
|
||||
@ -36,7 +36,7 @@ pub(crate) fn check<'tcx>(
|
||||
// right hand side matches either f32::EPSILON or f64::EPSILON
|
||||
&& let ExprKind::Path(ref epsilon_path) = rhs.kind
|
||||
&& let Res::Def(DefKind::AssocConst, def_id) = cx.qpath_res(epsilon_path, rhs.hir_id)
|
||||
&& (match_def_path(cx, def_id, &paths::F32_EPSILON) || match_def_path(cx, def_id, &paths::F64_EPSILON))
|
||||
&& ([sym::f32_epsilon, sym::f64_epsilon].into_iter().any(|sym| cx.tcx.is_diagnostic_item(sym, def_id)))
|
||||
|
||||
// values of the subtractions on the left hand side are of the type float
|
||||
&& let t_val_l = cx.typeck_results().expr_ty(val_l)
|
||||
|
@ -2,7 +2,7 @@
|
||||
use clippy_utils::mir::{visit_local_usage, LocalUsage, PossibleBorrowerMap};
|
||||
use clippy_utils::source::SpanRangeExt;
|
||||
use clippy_utils::ty::{has_drop, is_copy, is_type_diagnostic_item, is_type_lang_item, walk_ptrs_ty_depth};
|
||||
use clippy_utils::{fn_has_unsatisfiable_preds, match_def_path, paths};
|
||||
use clippy_utils::fn_has_unsatisfiable_preds;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{def_id, Body, FnDecl, LangItem};
|
||||
@ -102,8 +102,8 @@ fn check_fn(
|
||||
&& is_type_lang_item(cx, arg_ty, LangItem::String));
|
||||
|
||||
let from_deref = !from_borrow
|
||||
&& (match_def_path(cx, fn_def_id, &paths::PATH_TO_PATH_BUF)
|
||||
|| match_def_path(cx, fn_def_id, &paths::OS_STR_TO_OS_STRING));
|
||||
&& (cx.tcx.is_diagnostic_item(sym::path_to_pathbuf, fn_def_id)
|
||||
|| cx.tcx.is_diagnostic_item(sym::os_str_to_os_string, fn_def_id));
|
||||
|
||||
if !from_borrow && !from_deref {
|
||||
continue;
|
||||
|
@ -3,7 +3,7 @@
|
||||
use clippy_utils::higher::VecArgs;
|
||||
use clippy_utils::macros::matching_root_macro_call;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::{expr_or_init, fn_def_id, match_def_path, paths};
|
||||
use clippy_utils::{expr_or_init, fn_def_id};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
@ -67,7 +67,7 @@ fn emit_lint(cx: &LateContext<'_>, span: Span, kind: &str, note: &'static str, s
|
||||
fn check_vec_macro(cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||
if matching_root_macro_call(cx, expr.span, sym::vec_macro).is_some()
|
||||
&& let Some(VecArgs::Repeat(repeat_expr, len_expr)) = VecArgs::hir(cx, expr)
|
||||
&& fn_def_id(cx, repeat_expr).is_some_and(|did| match_def_path(cx, did, &paths::VEC_WITH_CAPACITY))
|
||||
&& fn_def_id(cx, repeat_expr).is_some_and(|did| cx.tcx.is_diagnostic_item(sym::vec_with_capacity, did))
|
||||
&& !len_expr.span.from_expansion()
|
||||
&& let Some(Constant::Int(2..)) = ConstEvalCtxt::new(cx).eval(expr_or_init(cx, len_expr))
|
||||
{
|
||||
@ -91,7 +91,7 @@ fn check_repeat_fn(cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||
if !expr.span.from_expansion()
|
||||
&& fn_def_id(cx, expr).is_some_and(|did| cx.tcx.is_diagnostic_item(sym::iter_repeat, did))
|
||||
&& let ExprKind::Call(_, [repeat_expr]) = expr.kind
|
||||
&& fn_def_id(cx, repeat_expr).is_some_and(|did| match_def_path(cx, did, &paths::VEC_WITH_CAPACITY))
|
||||
&& fn_def_id(cx, repeat_expr).is_some_and(|did| cx.tcx.is_diagnostic_item(sym::vec_with_capacity, did))
|
||||
&& !repeat_expr.span.from_expansion()
|
||||
{
|
||||
emit_lint(
|
||||
|
@ -2,8 +2,8 @@
|
||||
use clippy_utils::macros::matching_root_macro_call;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::{
|
||||
get_enclosing_block, is_expr_path_def_path, is_integer_literal, is_path_diagnostic_item, path_to_local,
|
||||
path_to_local_id, paths, SpanlessEq,
|
||||
get_enclosing_block, is_integer_literal, is_path_diagnostic_item, path_to_local,
|
||||
path_to_local_id, SpanlessEq,
|
||||
};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::{walk_block, walk_expr, walk_stmt, Visitor};
|
||||
@ -150,10 +150,10 @@ fn as_vec_initializer<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Opt
|
||||
}
|
||||
|
||||
if let ExprKind::Call(func, [len_expr]) = expr.kind
|
||||
&& is_expr_path_def_path(cx, func, &paths::VEC_WITH_CAPACITY)
|
||||
&& is_path_diagnostic_item(cx, func, sym::vec_with_capacity)
|
||||
{
|
||||
Some(InitializedSize::Initialized(len_expr))
|
||||
} else if matches!(expr.kind, ExprKind::Call(func, _) if is_expr_path_def_path(cx, func, &paths::VEC_NEW)) {
|
||||
} else if matches!(expr.kind, ExprKind::Call(func, _) if is_path_diagnostic_item(cx, func, sym::vec_new)) {
|
||||
Some(InitializedSize::Uninitialized)
|
||||
} else {
|
||||
None
|
||||
|
@ -1,6 +1,5 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use clippy_utils::{match_def_path, paths};
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};
|
||||
@ -42,7 +41,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||
&& let ty::Ref(_, inner_str, _) = cx.typeck_results().expr_ty_adjusted(expr).kind()
|
||||
&& inner_str.is_str()
|
||||
{
|
||||
if match_def_path(cx, fun_def_id, &paths::STRING_NEW) {
|
||||
if cx.tcx.is_diagnostic_item(sym::string_new, fun_def_id) {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
UNNECESSARY_OWNED_EMPTY_STRINGS,
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
use crate::consts::{ConstEvalCtxt, Constant};
|
||||
use crate::ty::is_type_diagnostic_item;
|
||||
use crate::{is_expn_of, match_def_path, paths};
|
||||
use crate::is_expn_of;
|
||||
|
||||
use rustc_ast::ast;
|
||||
use rustc_hir as hir;
|
||||
@ -297,10 +297,10 @@ pub fn hir(cx: &LateContext<'_>, expr: &'a Expr<'_>) -> Option<VecArgs<'a>> {
|
||||
&& is_expn_of(fun.span, "vec").is_some()
|
||||
&& let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()
|
||||
{
|
||||
return if match_def_path(cx, fun_def_id, &paths::VEC_FROM_ELEM) && args.len() == 2 {
|
||||
return if cx.tcx.is_diagnostic_item(sym::vec_from_elem, fun_def_id) && args.len() == 2 {
|
||||
// `vec![elem; size]` case
|
||||
Some(VecArgs::Repeat(&args[0], &args[1]))
|
||||
} else if match_def_path(cx, fun_def_id, &paths::SLICE_INTO_VEC) && args.len() == 1 {
|
||||
} else if cx.tcx.is_diagnostic_item(sym::slice_into_vec, fun_def_id) && args.len() == 1 {
|
||||
// `vec![a, b, c]` case
|
||||
if let ExprKind::Call(_, [arg]) = &args[0].kind
|
||||
&& let ExprKind::Array(args) = arg.kind
|
||||
@ -309,7 +309,7 @@ pub fn hir(cx: &LateContext<'_>, expr: &'a Expr<'_>) -> Option<VecArgs<'a>> {
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else if match_def_path(cx, fun_def_id, &paths::VEC_NEW) && args.is_empty() {
|
||||
} else if cx.tcx.is_diagnostic_item(sym::vec_new, fun_def_id) && args.is_empty() {
|
||||
Some(VecArgs::Vec(&[]))
|
||||
} else {
|
||||
None
|
||||
|
@ -4,6 +4,7 @@
|
||||
//! Whenever possible, please consider diagnostic items over hardcoded paths.
|
||||
//! See <https://github.com/rust-lang/rust-clippy/issues/5393> for more information.
|
||||
|
||||
// Paths inside rustc
|
||||
pub const APPLICABILITY: [&str; 2] = ["rustc_lint_defs", "Applicability"];
|
||||
pub const APPLICABILITY_VALUES: [[&str; 3]; 4] = [
|
||||
["rustc_lint_defs", "Applicability", "Unspecified"],
|
||||
@ -12,50 +13,37 @@
|
||||
["rustc_lint_defs", "Applicability", "MachineApplicable"],
|
||||
];
|
||||
pub const DIAG: [&str; 2] = ["rustc_errors", "Diag"];
|
||||
pub const BTREEMAP_CONTAINS_KEY: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "contains_key"];
|
||||
pub const BTREEMAP_INSERT: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "insert"];
|
||||
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 EARLY_CONTEXT: [&str; 2] = ["rustc_lint", "EarlyContext"];
|
||||
pub const EARLY_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "EarlyLintPass"];
|
||||
pub const F32_EPSILON: [&str; 4] = ["core", "f32", "<impl f32>", "EPSILON"];
|
||||
pub const F64_EPSILON: [&str; 4] = ["core", "f64", "<impl f64>", "EPSILON"];
|
||||
pub const FILE_OPTIONS: [&str; 4] = ["std", "fs", "File", "options"];
|
||||
#[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
|
||||
pub const FUTURES_IO_ASYNCWRITEEXT: [&str; 3] = ["futures_util", "io", "AsyncWriteExt"];
|
||||
pub const HASHMAP_CONTAINS_KEY: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "contains_key"];
|
||||
pub const HASHMAP_INSERT: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "insert"];
|
||||
pub const HASHMAP_ITER: [&str; 5] = ["std", "collections", "hash", "map", "Iter"];
|
||||
pub const HASHMAP_ITER_MUT: [&str; 5] = ["std", "collections", "hash", "map", "IterMut"];
|
||||
pub const HASHMAP_KEYS: [&str; 5] = ["std", "collections", "hash", "map", "Keys"];
|
||||
pub const HASHMAP_VALUES: [&str; 5] = ["std", "collections", "hash", "map", "Values"];
|
||||
pub const HASHMAP_DRAIN: [&str; 5] = ["std", "collections", "hash", "map", "Drain"];
|
||||
pub const HASHMAP_VALUES_MUT: [&str; 5] = ["std", "collections", "hash", "map", "ValuesMut"];
|
||||
pub const HASHSET_ITER_TY: [&str; 5] = ["std", "collections", "hash", "set", "Iter"];
|
||||
pub const HASHSET_DRAIN: [&str; 5] = ["std", "collections", "hash", "set", "Drain"];
|
||||
pub const IDENT: [&str; 3] = ["rustc_span", "symbol", "Ident"];
|
||||
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 ITERTOOLS_NEXT_TUPLE: [&str; 3] = ["itertools", "Itertools", "next_tuple"];
|
||||
pub const KW_MODULE: [&str; 3] = ["rustc_span", "symbol", "kw"];
|
||||
pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"];
|
||||
pub const LATE_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "LateLintPass"];
|
||||
pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"];
|
||||
pub const SYMBOL: [&str; 3] = ["rustc_span", "symbol", "Symbol"];
|
||||
pub const SYMBOL_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Symbol", "as_str"];
|
||||
pub const SYMBOL_INTERN: [&str; 4] = ["rustc_span", "symbol", "Symbol", "intern"];
|
||||
pub const SYMBOL_TO_IDENT_STRING: [&str; 4] = ["rustc_span", "symbol", "Symbol", "to_ident_string"];
|
||||
pub const SYM_MODULE: [&str; 3] = ["rustc_span", "symbol", "sym"];
|
||||
pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"];
|
||||
|
||||
// Paths in `core`/`alloc`/`std`. This should be avoided and cleaned up by adding diagnostic items.
|
||||
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"];
|
||||
|
||||
// Paths in clippy itself
|
||||
pub const MSRV: [&str; 3] = ["clippy_config", "msrvs", "Msrv"];
|
||||
pub const OPEN_OPTIONS_NEW: [&str; 4] = ["std", "fs", "OpenOptions", "new"];
|
||||
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"];
|
||||
|
||||
// Paths in external crates
|
||||
#[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
|
||||
pub const FUTURES_IO_ASYNCWRITEEXT: [&str; 3] = ["futures_util", "io", "AsyncWriteExt"];
|
||||
pub const ITERTOOLS_NEXT_TUPLE: [&str; 3] = ["itertools", "Itertools", "next_tuple"];
|
||||
pub const PARKING_LOT_MUTEX_GUARD: [&str; 3] = ["lock_api", "mutex", "MutexGuard"];
|
||||
pub const PARKING_LOT_RWLOCK_READ_GUARD: [&str; 3] = ["lock_api", "rwlock", "RwLockReadGuard"];
|
||||
pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 3] = ["lock_api", "rwlock", "RwLockWriteGuard"];
|
||||
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"];
|
||||
#[cfg_attr(not(unix), allow(clippy::invalid_paths))]
|
||||
pub const PERMISSIONS_FROM_MODE: [&str; 6] = ["std", "os", "unix", "fs", "PermissionsExt", "from_mode"];
|
||||
pub const PUSH_STR: [&str; 4] = ["alloc", "string", "String", "push_str"];
|
||||
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"];
|
||||
@ -64,22 +52,6 @@
|
||||
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_INTO_VEC: [&str; 4] = ["alloc", "slice", "<impl [T]>", "into_vec"];
|
||||
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 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"];
|
||||
pub const STR_ENDS_WITH: [&str; 4] = ["core", "str", "<impl str>", "ends_with"];
|
||||
pub const STR_LEN: [&str; 4] = ["core", "str", "<impl str>", "len"];
|
||||
pub const STR_STARTS_WITH: [&str; 4] = ["core", "str", "<impl str>", "starts_with"];
|
||||
pub const SYMBOL: [&str; 3] = ["rustc_span", "symbol", "Symbol"];
|
||||
pub const SYMBOL_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Symbol", "as_str"];
|
||||
pub const SYMBOL_INTERN: [&str; 4] = ["rustc_span", "symbol", "Symbol", "intern"];
|
||||
pub const SYMBOL_TO_IDENT_STRING: [&str; 4] = ["rustc_span", "symbol", "Symbol", "to_ident_string"];
|
||||
pub const SYM_MODULE: [&str; 3] = ["rustc_span", "symbol", "sym"];
|
||||
pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"];
|
||||
pub const STRING_FROM_UTF8: [&str; 4] = ["alloc", "string", "String", "from_utf8"];
|
||||
#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
|
||||
pub const TOKIO_FILE_OPTIONS: [&str; 5] = ["tokio", "fs", "file", "File", "options"];
|
||||
#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
|
||||
@ -90,15 +62,3 @@
|
||||
pub const TOKIO_IO_OPEN_OPTIONS: [&str; 4] = ["tokio", "fs", "open_options", "OpenOptions"];
|
||||
#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
|
||||
pub const TOKIO_IO_OPEN_OPTIONS_NEW: [&str; 5] = ["tokio", "fs", "open_options", "OpenOptions", "new"];
|
||||
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_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 INSTANT_NOW: [&str; 4] = ["std", "time", "Instant", "now"];
|
||||
pub const VEC_IS_EMPTY: [&str; 4] = ["alloc", "vec", "Vec", "is_empty"];
|
||||
pub const VEC_POP: [&str; 4] = ["alloc", "vec", "Vec", "pop"];
|
||||
pub const WAKER: [&str; 4] = ["core", "task", "wake", "Waker"];
|
||||
pub const OPTION_UNWRAP: [&str; 4] = ["core", "option", "Option", "unwrap"];
|
||||
pub const OPTION_EXPECT: [&str; 4] = ["core", "option", "Option", "expect"];
|
||||
pub const BOOL_THEN: [&str; 4] = ["core", "bool", "<impl bool>", "then"];
|
||||
|
Loading…
Reference in New Issue
Block a user