11# Diagnostic Items
2-
3- ## Background
4-
5- While writing lints it's common to check for specific types, traits and functions. This raises
6- the question on how to check for these. Types can be checked by their complete type path.
7- However, this requires hard coding paths and can lead to misclassifications in some edge cases.
8- To counteract this, rustc has introduced diagnostic items that are used to identify types via
2+ While writing lints it's common to check for specific types, traits and
3+ functions. This raises the question on how to check for these. Types can be
4+ checked by their complete type path. However, this requires hard coding paths
5+ and can lead to misclassifications in some edge cases. To counteract this,
6+ rustc has introduced diagnostic items that are used to identify types via
97[ ` Symbol ` ] s.
108
11- ## How To Find Diagnostic Items
12-
13- Diagnostic items are added to items inside ` rustc ` / ` std ` / ` core ` with the ` rustc_diagnostic_item `
14- attribute. The item for a specific type can be found by opening the source code in the
15- documentation and looking for this attribute. Note that it's often added with the ` cfg_attr `
16- attribute to avoid compilation errors during tests. A definition often looks like this:
9+ ## Finding diagnostic items
10+ Diagnostic items are added to items inside ` rustc ` / ` std ` / ` core ` with the
11+ ` rustc_diagnostic_item ` attribute. The item for a specific type can be found by
12+ opening the source code in the documentation and looking for this attribute.
13+ Note that it's often added with the ` cfg_attr ` attribute to avoid compilation
14+ errors during tests. A definition often looks like this:
1715
1816``` rs
1917// This is the diagnostic item for this type vvvvvvv
2018#[cfg_attr(not(test), rustc_diagnostic_item = " Penguin" )]
2119struct Penguin ;
2220```
2321
24- Diagnostic items are usually only added to traits, types and standalone functions. If the goal
25- is to check for an associated type or method, please use the diagnostic item of the item and
26- reference [ * How To Use Diagnostic Items* ] ( #how-to-use-diagnostic-items ) .
27-
28- ## How To Add Diagnostic Items
22+ Diagnostic items are usually only added to traits, types and standalone
23+ functions. If the goal is to check for an associated type or method, please use
24+ the diagnostic item of the item and reference [ * How To Use Diagnostic
25+ Items* ] ( #how-to-use-diagnostic-items ) .
2926
27+ ## Adding diagnostic items
3028A new diagnostic item can be added with these two steps:
3129
32- 1 . Find the target item inside the Rust repo. Now add the diagnostic item as a string via the
33- ` rustc_diagnostic_item ` attribute. This can sometimes cause compilation errors while running
34- tests. These errors can be avoided by using the ` cfg_attr ` attribute with the ` not(test) `
35- condition (it's fine adding then for all ` rustc_diagnostic_item ` attributes as a preventive
36- manner). At the end, it should look like this:
30+ 1 . Find the target item inside the Rust repo. Now add the diagnostic item as a
31+ string via the ` rustc_diagnostic_item ` attribute. This can sometimes cause
32+ compilation errors while running tests. These errors can be avoided by using
33+ the ` cfg_attr ` attribute with the ` not(test) ` condition (it's fine adding
34+ then for all ` rustc_diagnostic_item ` attributes as a preventive manner). At
35+ the end, it should look like this:
3736
3837 ``` rs
3938 // This will be the new diagnostic item vvv
@@ -44,41 +43,45 @@ A new diagnostic item can be added with these two steps:
4443 For the naming conventions of diagnostic items , please refer to
4544 [* Naming Conventions * ](#naming - conventions ).
4645
47- 2 . As of <! -- date : 2022 - 02 - -> February 2022 , diagnostic items in code are accessed via symbols in
48- [`rustc_span :: symbol :: sym `]. To add your newly created diagnostic item simply open the
49- module file and add the name (In this case `Cat `) at the correct point in the list .
50-
51- Now you can create a pull request with your changes . : tada : (Note that when using diagnostic
52- items in other projects like Clippy , it might take some time until the repos get synchronized . )
53-
54- ## Naming Conventions
55-
56- Diagnostic items don 't have a set in stone naming convention yet . These are some guidelines that
57- should be used for the future , but might differ from existing names :
58-
59- * Types , traits and enums are named using UpperCamelCase (Examples : `Iterator `, `HashMap `, ... )
60- * For type names that are used multiple times like `Writer ` it 's good to choose a more precise
61- name , maybe by adding the module to it . (Example : `IoWriter `)
62- * Associated items should not get their own diagnostic items , but instead be accessed indirectly
63- by the diagnostic item of the type they 're originating from .
64- * Freestanding functions like `std :: mem :: swap ()` should be named using `snake_case ` with one
65- important (export ) module as a prefix (Example : `mem_swap `, `cmp_max `)
66- * Modules should usually not have a diagnostic item attached to them . Diagnostic items were
67- added to avoid the usage of paths , using them on modules would therefore most likely to be
68- counterproductive .
69-
70- ## How To Use Diagnostic Items
71-
46+ 2 . As of <! -- date : 2022 - 02 - -> February 2022 , diagnostic items in code are
47+ accessed via symbols in [`rustc_span :: symbol :: sym `]. To add your newly
48+ created diagnostic item simply open the module file and add the name (In
49+ this case `Cat `) at the correct point in the list .
50+
51+ Now you can create a pull request with your changes . : tada : (Note that when
52+ using diagnostic items in other projects like Clippy , it might take some time
53+ until the repos get synchronized . )
54+
55+ ## Naming conventions
56+ Diagnostic items don 't have a set in stone naming convention yet . These are
57+ some guidelines that should be used for the future , but might differ from
58+ existing names :
59+
60+ * Types , traits and enums are named using UpperCamelCase (Examples : `Iterator `,
61+ * `HashMap `, ... )
62+ * For type names that are used multiple times like `Writer ` it 's good to choose
63+ a more precise name , maybe by adding the module to it . (Example : `IoWriter `)
64+ * Associated items should not get their own diagnostic items , but instead be
65+ accessed indirectly by the diagnostic item of the type they 're originating
66+ from .
67+ * Freestanding functions like `std :: mem :: swap ()` should be named using
68+ `snake_case ` with one important (export ) module as a prefix (Example :
69+ `mem_swap `, `cmp_max `)
70+ * Modules should usually not have a diagnostic item attached to them .
71+ Diagnostic items were added to avoid the usage of paths , using them on
72+ modules would therefore most likely to be counterproductive .
73+
74+ ## Using diagnostic items
7275In rustc , diagnostic items are looked up via [`Symbol `]s from inside the
73- [`rustc_span :: symbol :: sym `] module . These can then be mapped to [`DefId `]s using
74- [`TyCtxt :: get_diagnostic_item ()`] or checked if they match a [`DefId `] using
75- [`TyCtxt :: is_diagnostic_item ()`]. When mapping from a diagnostic item to a [` DefId `] the method
76- will return a `Option <DefId >`. This can be `None ` if either the symbol isn ' t a diagnostic item
77- or the type is not registered , for instance when compiling with `#[no_std]` . All following
78- examples are based on [` DefId `] s and their usage .
79-
80- ### Check For A Type
81-
76+ [`rustc_span :: symbol :: sym `] module . These can then be mapped to [`DefId `]s
77+ using [`TyCtxt :: get_diagnostic_item ()`] or checked if they match a [`DefId `]
78+ using [`TyCtxt :: is_diagnostic_item ()`]. When mapping from a diagnostic item to
79+ a [` DefId `] the method will return a `Option <DefId >`. This can be `None ` if
80+ either the symbol isn ' t a diagnostic item or the type is not registered , for
81+ instance when compiling with `#[no_std]` . All following examples are based on
82+ [` DefId `] s and their usage .
83+
84+ ### Example : Checking for a type
8285```rust
8386use rustc_span :: symbol :: sym;
8487
@@ -92,8 +95,7 @@ fn example_1(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
9295}
9396```
9497
95- ### Check For A Trait Implementation
96-
98+ ### Example: Checking for a trait implementation
9799``` rust
98100/// This example checks if a given [`DefId`] from a method is part of a trait
99101/// implementation defined by a diagnostic item.
@@ -110,24 +112,23 @@ fn is_diag_trait_item(
110112```
111113
112114### Associated Types
113-
114- Associated types of diagnostic items can be accessed indirectly by first getting the [ ` DefId ` ]
115- of the trait and then calling [ ` TyCtxt::associated_items() ` ] . This returns an [ ` AssocItems ` ]
116- object which can be used for further checks. Checkout
115+ Associated types of diagnostic items can be accessed indirectly by first
116+ getting the [ ` DefId ` ] of the trait and then calling
117+ [ ` TyCtxt::associated_items() ` ] . This returns an [ ` AssocItems ` ] object which can
118+ be used for further checks. Checkout
117119[ ` clippy_utils::ty::get_iterator_item_ty() ` ] for an example usage of this.
118120
119- ### Usage In Clippy
120-
121- Clippy tries to use diagnostic items where possible and has developed some wrapper and utility
122- functions. Please also refer to its documentation when using diagnostic items in Clippy. (See
123- [ * Common tools for writing lints* ] [ clippy-Common-tools-for-writing-lints ] .)
124-
125- ## Related Issues
121+ ### Usage in Clippy
122+ Clippy tries to use diagnostic items where possible and has developed some
123+ wrapper and utility functions. Please also refer to its documentation when
124+ using diagnostic items in Clippy. (See [ * Common tools for writing
125+ lints* ] [ clippy-Common-tools-for-writing-lints ] .)
126126
127- This lists some related issues. These are probably only interesting to people who really want to
128- take a deep dive into the topic :)
127+ ## Related issues
128+ This lists some related issues. These are probably only interesting to people
129+ who really want to take a deep dive into the topic :)
129130
130- * [ rust #60966 ] : The Rust PR that introduced diagnostic items
131+ * [ rust #60966 ] : The Rust PR that introduced diagnostic items
131132* [ rust-clippy #5393 ] : Clippy's tracking issue for moving away from hard coded paths to
132133 diagnostic item
133134
0 commit comments