1
1
# 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
9
7
[ ` Symbol ` ] s.
10
8
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:
17
15
18
16
``` rs
19
17
// This is the diagnostic item for this type vvvvvvv
20
18
#[cfg_attr(not(test), rustc_diagnostic_item = " Penguin" )]
21
19
struct Penguin ;
22
20
```
23
21
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 ) .
29
26
27
+ ## Adding diagnostic items
30
28
A new diagnostic item can be added with these two steps:
31
29
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:
37
36
38
37
``` rs
39
38
// This will be the new diagnostic item vvv
@@ -44,41 +43,45 @@ A new diagnostic item can be added with these two steps:
44
43
For the naming conventions of diagnostic items , please refer to
45
44
[* Naming Conventions * ](#naming - conventions ).
46
45
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
72
75
In 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
82
85
```rust
83
86
use rustc_span :: symbol :: sym;
84
87
@@ -92,8 +95,7 @@ fn example_1(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
92
95
}
93
96
```
94
97
95
- ### Check For A Trait Implementation
96
-
98
+ ### Example: Checking for a trait implementation
97
99
``` rust
98
100
/// This example checks if a given [`DefId`] from a method is part of a trait
99
101
/// implementation defined by a diagnostic item.
@@ -110,24 +112,23 @@ fn is_diag_trait_item(
110
112
```
111
113
112
114
### 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
117
119
[ ` clippy_utils::ty::get_iterator_item_ty() ` ] for an example usage of this.
118
120
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 ] .)
126
126
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 :)
129
130
130
- * [ rust #60966 ] : The Rust PR that introduced diagnostic items
131
+ * [ rust #60966 ] : The Rust PR that introduced diagnostic items
131
132
* [ rust-clippy #5393 ] : Clippy's tracking issue for moving away from hard coded paths to
132
133
diagnostic item
133
134
0 commit comments