Skip to content

Add diagnostic items for Clippy #142787

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,7 @@ symbols! {
cfi_encoding,
char,
char_is_ascii,
char_to_digit,
child_id,
child_kill,
client,
Expand Down Expand Up @@ -1217,6 +1218,8 @@ symbols! {
intrinsics,
intrinsics_unaligned_volatile_load,
intrinsics_unaligned_volatile_store,
io_error_new,
io_errorkind,
io_stderr,
io_stdout,
irrefutable_let_patterns,
Expand Down Expand Up @@ -1306,6 +1309,7 @@ symbols! {
m68k_target_feature,
macro_at_most_once_rep,
macro_attributes_in_derive_output,
macro_concat,
macro_escape,
macro_export,
macro_lifetime_matcher,
Expand Down Expand Up @@ -1340,6 +1344,7 @@ symbols! {
maybe_uninit,
maybe_uninit_uninit,
maybe_uninit_zeroed,
mem_align_of,
mem_discriminant,
mem_drop,
mem_forget,
Expand Down Expand Up @@ -1707,6 +1712,7 @@ symbols! {
question_mark,
quote,
range_inclusive_new,
range_step,
raw_dylib,
raw_dylib_elf,
raw_eq,
Expand Down Expand Up @@ -2023,6 +2029,7 @@ symbols! {
slice,
slice_from_raw_parts,
slice_from_raw_parts_mut,
slice_from_ref,
slice_get_unchecked,
slice_into_vec,
slice_iter,
Expand Down
1 change: 1 addition & 0 deletions library/core/src/char/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ impl char {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_char_convert", since = "1.67.0")]
#[rustc_diagnostic_item = "char_to_digit"]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
Expand Down
1 change: 1 addition & 0 deletions library/core/src/iter/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u6
///
/// The *successor* operation moves towards values that compare greater.
/// The *predecessor* operation moves towards values that compare lesser.
#[rustc_diagnostic_item = "range_step"]
#[unstable(feature = "step_trait", issue = "42168")]
pub trait Step: Clone + PartialOrd + Sized {
/// Returns the bounds on the number of *successor* steps required to get from `start` to `end`
Expand Down
1 change: 1 addition & 0 deletions library/core/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,7 @@ pub(crate) mod builtin {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_builtin_macro]
#[rustc_diagnostic_item = "macro_concat"]
#[macro_export]
macro_rules! concat {
($($e:expr),* $(,)?) => {{ /* compiler built-in */ }};
Expand Down
1 change: 1 addition & 0 deletions library/core/src/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ pub fn min_align_of_val<T: ?Sized>(val: &T) -> usize {
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_promotable]
#[rustc_const_stable(feature = "const_align_of", since = "1.24.0")]
#[rustc_diagnostic_item = "mem_align_of"]
pub const fn align_of<T>() -> usize {
intrinsics::align_of::<T>()
}
Expand Down
1 change: 1 addition & 0 deletions library/core/src/slice/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a m
/// Converts a reference to T into a slice of length 1 (without copying).
#[stable(feature = "from_ref", since = "1.28.0")]
#[rustc_const_stable(feature = "const_slice_from_ref_shared", since = "1.63.0")]
#[rustc_diagnostic_item = "slice_from_ref"]
#[must_use]
pub const fn from_ref<T>(s: &T) -> &[T] {
array::from_ref(s)
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/io/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ struct Custom {
/// the recognized error kinds and fail in those cases.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "io_errorkind")]
#[allow(deprecated)]
#[non_exhaustive]
pub enum ErrorKind {
Expand Down Expand Up @@ -562,6 +563,7 @@ impl Error {
/// let eof_error = Error::from(ErrorKind::UnexpectedEof);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "io_error_new")]
#[inline(never)]
pub fn new<E>(kind: ErrorKind, error: E) -> Error
where
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::SpanRangeExt;
use clippy_utils::{expr_or_init, path_def_id, paths, std_or_core};
use clippy_utils::{expr_or_init, is_path_diagnostic_item, std_or_core, sym};
use rustc_ast::LitKind;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, GenericArg, Mutability, QPath, Ty, TyKind};
Expand Down Expand Up @@ -53,8 +53,7 @@ fn is_expr_const_aligned(cx: &LateContext<'_>, expr: &Expr<'_>, to: &Ty<'_>) ->

fn is_align_of_call(cx: &LateContext<'_>, fun: &Expr<'_>, to: &Ty<'_>) -> bool {
if let ExprKind::Path(QPath::Resolved(_, path)) = fun.kind
&& let Some(fun_id) = path_def_id(cx, fun)
&& paths::ALIGN_OF.matches(cx, fun_id)
&& is_path_diagnostic_item(cx, fun, sym::mem_align_of)
&& let Some(args) = path.segments.last().and_then(|seg| seg.args)
&& let [GenericArg::Type(generic_ty)] = args.args
{
Expand Down
4 changes: 2 additions & 2 deletions src/tools/clippy/clippy_lints/src/manual_option_as_slice.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use clippy_config::Conf;
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
use clippy_utils::msrvs::Msrv;
use clippy_utils::{is_none_arm, msrvs, paths, peel_hir_expr_refs, sym};
use clippy_utils::{is_none_arm, msrvs, peel_hir_expr_refs, sym};
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{Arm, Expr, ExprKind, LangItem, Pat, PatKind, QPath, is_range_literal};
Expand Down Expand Up @@ -220,5 +220,5 @@ fn is_empty_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
}

fn is_slice_from_ref(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
paths::SLICE_FROM_REF.matches_path(cx, expr)
clippy_utils::is_path_diagnostic_item(cx, expr, sym::slice_from_ref)
}
9 changes: 6 additions & 3 deletions src/tools/clippy/clippy_lints/src/methods/io_other_error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::{expr_or_init, paths};
use clippy_utils::{expr_or_init, is_path_diagnostic_item, sym};
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, QPath};
use rustc_lint::LateContext;
Expand All @@ -10,8 +10,11 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, path: &Expr<'_>, args
&& !expr.span.from_expansion()
&& !error_kind.span.from_expansion()
&& let ExprKind::Path(QPath::TypeRelative(_, new_segment)) = path.kind
&& paths::IO_ERROR_NEW.matches_path(cx, path)
&& paths::IO_ERRORKIND_OTHER_CTOR.matches_path(cx, expr_or_init(cx, error_kind))
&& is_path_diagnostic_item(cx, path, sym::io_error_new)
&& let ExprKind::Path(QPath::Resolved(_, init_path)) = &expr_or_init(cx, error_kind).kind
&& let [.., error_kind_ty, error_kind_variant] = init_path.segments
&& cx.tcx.is_diagnostic_item(sym::io_errorkind, error_kind_ty.res.def_id())
&& error_kind_variant.ident.name == sym::Other
&& msrv.meets(cx, msrvs::IO_ERROR_OTHER)
{
span_lint_and_then(
Expand Down
4 changes: 2 additions & 2 deletions src/tools/clippy/clippy_lints/src/single_range_in_vec_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use clippy_utils::higher::VecArgs;
use clippy_utils::macros::root_macro_call_first_node;
use clippy_utils::source::SpanRangeExt;
use clippy_utils::ty::implements_trait;
use clippy_utils::{is_no_std_crate, paths};
use clippy_utils::{is_no_std_crate, sym};
use rustc_ast::{LitIntType, LitKind, UintTy};
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, LangItem, QPath, StructTailExpr};
Expand Down Expand Up @@ -100,7 +100,7 @@ impl LateLintPass<'_> for SingleRangeInVecInit {
&& let Some(start_snippet) = start.span.get_source_text(cx)
&& let Some(end_snippet) = end.span.get_source_text(cx)
{
let should_emit_every_value = if let Some(step_def_id) = paths::ITER_STEP.only(cx)
let should_emit_every_value = if let Some(step_def_id) = cx.tcx.get_diagnostic_item(sym::range_step)
&& implements_trait(cx, ty, step_def_id, &[])
{
true
Expand Down
4 changes: 2 additions & 2 deletions src/tools/clippy/clippy_lints/src/to_digit_is_some.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::{is_in_const_context, paths, sym};
use clippy_utils::{is_in_const_context, is_path_diagnostic_item, sym};
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass};
Expand Down Expand Up @@ -62,7 +62,7 @@ impl<'tcx> LateLintPass<'tcx> for ToDigitIsSome {
}
},
hir::ExprKind::Call(to_digits_call, [char_arg, radix_arg]) => {
if paths::CHAR_TO_DIGIT.matches_path(cx, to_digits_call) {
if is_path_diagnostic_item(cx, to_digits_call, sym::char_to_digit) {
Some((false, char_arg, radix_arg))
} else {
None
Expand Down
5 changes: 2 additions & 3 deletions src/tools/clippy/clippy_lints/src/useless_concat.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::macros::macro_backtrace;
use clippy_utils::paths::CONCAT;
use clippy_utils::source::snippet_opt;
use clippy_utils::tokenize_with_text;
use clippy_utils::{sym, tokenize_with_text};
use rustc_ast::LitKind;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
Expand Down Expand Up @@ -43,7 +42,7 @@ impl LateLintPass<'_> for UselessConcat {
// Get the direct parent of the expression.
&& let Some(macro_call) = macro_backtrace(expr.span).next()
// Check if the `concat` macro from the `core` library.
&& CONCAT.matches(cx, macro_call.def_id)
&& cx.tcx.is_diagnostic_item(sym::macro_concat, macro_call.def_id)
// We get the original code to parse it.
&& let Some(original_code) = snippet_opt(cx, macro_call.span)
// This check allows us to ensure that the code snippet:
Expand Down
9 changes: 0 additions & 9 deletions src/tools/clippy/clippy_utils/src/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,6 @@ path_macros! {
macro_path: PathNS::Macro,
}

// Paths in `core`/`alloc`/`std`. This should be avoided and cleaned up by adding diagnostic items.
pub static ALIGN_OF: PathLookup = value_path!(core::mem::align_of);
pub static CHAR_TO_DIGIT: PathLookup = value_path!(char::to_digit);
pub static CONCAT: PathLookup = macro_path!(core::concat);
pub static IO_ERROR_NEW: PathLookup = value_path!(std::io::Error::new);
pub static IO_ERRORKIND_OTHER_CTOR: PathLookup = value_path!(std::io::ErrorKind::Other);
pub static ITER_STEP: PathLookup = type_path!(core::iter::Step);
pub static SLICE_FROM_REF: PathLookup = value_path!(core::slice::from_ref);

// Paths in external crates
pub static FUTURES_IO_ASYNCREADEXT: PathLookup = type_path!(futures_util::AsyncReadExt);
pub static FUTURES_IO_ASYNCWRITEEXT: PathLookup = type_path!(futures_util::AsyncWriteExt);
Expand Down
10 changes: 0 additions & 10 deletions tests/ui/range/range-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,6 @@ error[E0277]: the trait bound `bool: Step` is not satisfied
LL | for i in false..true {}
| ^^^^^^^^^^^ the trait `Step` is not implemented for `bool`
|
= help: the following other types implement trait `Step`:
Char
Ipv4Addr
Ipv6Addr
char
i128
i16
i32
i64
and 8 others
= note: required for `std::ops::Range<bool>` to implement `Iterator`
= note: required for `std::ops::Range<bool>` to implement `IntoIterator`

Expand Down
Loading