Home Explore Blog CI



rustc

2nd chunk of `src/diagnostics/diagnostic-items.md`
fc98b35a510245a72aef8e503bd4fa8cfe0472f1a3172e520000000100000efc
    #[cfg_attr(not(test), rustc_diagnostic_item = "Cat")]
    struct Cat;
    ```

    For the naming conventions of diagnostic items, please refer to
    [*Naming Conventions*](#naming-conventions).

2. <!-- date-check: Feb 2023 -->
   Diagnostic items in code are accessed via symbols in
   [`rustc_span::symbol::sym`].
   To add your newly-created diagnostic item,
   simply open the module file,
   and add the name (In this case `Cat`) at the correct point in the list.

Now you can create a pull request with your changes. :tada:

> NOTE:
> When using diagnostic items in other projects like Clippy,
> it might take some time until the repos get synchronized.

## Naming conventions

Diagnostic items don't have a naming convention yet.
Following are some guidelines that should be used in future,
but might differ from existing names:

* Types, traits, and enums are named using UpperCamelCase
  (Examples: `Iterator` and `HashMap`)
* For type names that are used multiple times,
  like `Writer`,
  it's good to choose a more precise name,
  maybe by adding the module to it
  (Example: `IoWriter`)
* Associated items should not get their own diagnostic items,
  but instead be accessed indirectly by the diagnostic item
  of the type they're originating from.
* Freestanding functions like `std::mem::swap()` should be named using
  `snake_case` with one important (export) module as a prefix
  (Examples: `mem_swap` and `cmp_max`)
* Modules should usually not have a diagnostic item attached to them.
  Diagnostic items were added to avoid the usage of paths,
  and using them on modules would therefore most likely be counterproductive.

## Using diagnostic items

In rustc, diagnostic items are looked up via [`Symbol`]s from inside the
[`rustc_span::symbol::sym`] module. These can then be mapped to [`DefId`]s
using [`TyCtxt::get_diagnostic_item()`] or checked if they match a [`DefId`]
using [`TyCtxt::is_diagnostic_item()`]. When mapping from a diagnostic item to
a [`DefId`], the method will return a `Option<DefId>`. This can be `None` if
either the symbol isn't a diagnostic item or the type is not registered, for
instance when compiling with `#[no_std]`.
All the following examples are based on [`DefId`]s and their usage.

### Example: Checking for a type

```rust
use rustc_span::symbol::sym;

/// This example checks if the given type (`ty`) has the type `HashMap` using
/// `TyCtxt::is_diagnostic_item()`
fn example_1(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
    match ty.kind() {
        ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(sym::HashMap, adt.did()),
        _ => false,
    }
}
```

### Example: Checking for a trait implementation

```rust
/// This example checks if a given [`DefId`] from a method is part of a trait
/// implementation defined by a diagnostic item.
fn is_diag_trait_item(
    cx: &LateContext<'_>,
    def_id: DefId,
    diag_item: Symbol
) -> bool {
    if let Some(trait_did) = cx.tcx.trait_of_item(def_id) {
        return cx.tcx.is_diagnostic_item(diag_item, trait_did);
    }
    false
}
```

### Associated Types

Associated types of diagnostic items can be accessed indirectly by first
getting the [`DefId`] of the trait and then calling
[`TyCtxt::associated_items()`]. This returns an [`AssocItems`] object which can
be used for further checks. Checkout
[`clippy_utils::ty::get_iterator_item_ty()`] for an example usage of this.

### Usage in Clippy

Clippy tries to use diagnostic items where possible and has developed some
wrapper and utility functions. Please also refer to its documentation when
using diagnostic items in Clippy. (See [*Common tools for writing
lints*][clippy-Common-tools-for-writing-lints].)

## Related issues

These are probably only interesting to people
who really want to take a deep dive into the topic :)

  diagnostic item

<!-- Links -->


Title: Diagnostic Item Naming Conventions, Usage, and Related Issues
Summary
This section covers the naming conventions for diagnostic items, suggesting UpperCamelCase for types/traits/enums, precise names for frequently used types, and snake_case with a module prefix for freestanding functions. It advises against diagnostic items for associated items and modules. It details how to use diagnostic items in `rustc` via `rustc_span::symbol::sym`, mapping to `DefId`s using `TyCtxt` methods. Examples are provided for checking types and trait implementations, as well as accessing associated types indirectly. The section also touches on Clippy's usage of diagnostic items and links to related issues for deeper exploration.