11# Diagnostic Items  
2+ 
23While writing lints it's common to check for specific types, traits and
34functions. This raises the question on how to check for these. Types can be
45checked by their complete type path. However, this requires hard coding paths
@@ -7,7 +8,8 @@ rustc has introduced diagnostic items that are used to identify types via
78[ ` Symbol ` ] s.
89
910## Finding diagnostic items  
10- Diagnostic items are added to items inside ` rustc ` /` std ` /` core `  with the
11+ 
12+ Diagnostic items are added to items inside ` rustc ` /` std ` /` core ` /` alloc `  with the
1113` rustc_diagnostic_item `  attribute. The item for a specific type can be found by
1214opening the source code in the documentation and looking for this attribute.
1315Note that it's often added with the ` cfg_attr `  attribute to avoid compilation
@@ -19,12 +21,15 @@ errors during tests. A definition often looks like this:
1921struct  Penguin ;
2022``` 
2123
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 ) .
24+ Diagnostic items are usually only added to traits,
25+ types,
26+ and standalone functions.
27+ If the goal is to check for an associated type or method,
28+ please use the diagnostic item of the item and reference
29+ [ * Using Diagnostic Items* ] ( #using-diagnostic-items ) .
2630
2731## Adding diagnostic items  
32+ 
2833A new diagnostic item can be added with these two steps:
2934
30351 .  Find the target item inside the Rust repo. Now add the diagnostic item as a
@@ -43,45 +48,55 @@ A new diagnostic item can be added with these two steps:
4348    For  the  naming  conventions  of  diagnostic  items , please  refer  to 
4449    [* Naming  Conventions * ](#naming - conventions ). 
4550
46- 2 .  As  of  <! --  date - check  - ->  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 . 
51+ 2 .  <! --  date - check :  Aug  2022  - -> 
52+    Diagnostic  items  in  code  are  accessed  via  symbols  in 
53+    [`rustc_span :: symbol :: sym `]. 
54+    To  add  your  newly - created  diagnostic  item ,
55+    simply  open  the  module  file ,
56+    and  add  the  name  (In  this  case  `Cat `) at  the  correct  point  in  the  list . 
5057
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 . )
58+ Now  you  can  create  a  pull  request  with  your  changes .  : tada : 
59+ 
60+ > NOTE : 
61+ > When  using  diagnostic  items  in  other  projects  like  Clippy ,
62+ > it  might  take  some  time  until  the  repos  get  synchronized . 
5463
5564## 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 . 
65+ 
66+ Diagnostic  items  don 't  have  a  naming  convention  yet . 
67+ Following  are  some  guidelines  that  should  be  used  in  future ,
68+ but  might  differ  from  existing  names : 
69+ 
70+ *  Types , traits , and  enums  are  named  using  UpperCamelCase 
71+   (Examples :  `Iterator ` and  `HashMap `)
72+ *  For  type  names  that  are  used  multiple  times ,
73+   like  `Writer `,
74+   it 's  good  to  choose  a  more  precise  name ,
75+   maybe  by  adding  the  module  to  it 
76+   (Example :  `IoWriter `)
77+ *  Associated  items  should  not  get  their  own  diagnostic  items ,
78+   but  instead  be  accessed  indirectly  by  the  diagnostic  item 
79+   of  the  type  they 're  originating  from . 
6780*  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 `)
81+   `snake_case ` with  one  important  (export ) module  as  a  prefix 
82+   ( Examples :   `mem_swap `  and  `cmp_max `)
7083*  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 . 
84+   Diagnostic  items  were  added  to  avoid  the  usage  of  paths ,
85+   and   using   them   on   modules  would  therefore  most  likely  be  counterproductive . 
7386
7487## Using  diagnostic  items 
88+ 
7589In  rustc , diagnostic  items  are  looked  up  via  [`Symbol `]s  from  inside  the 
7690[`rustc_span :: symbol :: sym `] module .  These  can  then  be  mapped  to  [`DefId `]s 
7791using  [`TyCtxt :: get_diagnostic_item ()`] or  checked  if  they  match  a  [`DefId `]
7892using  [`TyCtxt :: is_diagnostic_item ()`].  When  mapping  from  a  diagnostic  item  to 
7993a  [`DefId `], the  method  will  return  a  `Option <DefId >`.  This  can  be  `None ` if 
8094either  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 . 
95+ instance  when  compiling  with  `#[no_std]`. 
96+ All   the   following   examples   are   based   on   [`DefId `]s  and  their  usage . 
8397
8498### Example :  Checking  for  a  type 
99+ 
85100```rust 
86101use  rustc_span :: symbol :: sym;
87102
@@ -96,6 +111,7 @@ fn example_1(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
96111``` 
97112
98113### Example: Checking for a trait implementation  
114+ 
99115``` rust 
100116///  This example checks if a given [`DefId`] from a method is part of a trait
101117///  implementation defined by a diagnostic item.
@@ -112,20 +128,23 @@ fn is_diag_trait_item(
112128``` 
113129
114130### Associated Types  
131+ 
115132Associated types of diagnostic items can be accessed indirectly by first
116133getting the [ ` DefId ` ]  of the trait and then calling
117134[ ` TyCtxt::associated_items() ` ] . This returns an [ ` AssocItems ` ]  object which can
118135be used for further checks. Checkout
119136[ ` clippy_utils::ty::get_iterator_item_ty() ` ]  for an example usage of this.
120137
121138### Usage in Clippy  
139+ 
122140Clippy tries to use diagnostic items where possible and has developed some
123141wrapper and utility functions. Please also refer to its documentation when
124142using diagnostic items in Clippy. (See [ * Common tools for writing
125143lints* ] [ clippy-Common-tools-for-writing-lints ] .)
126144
127145## Related issues  
128- This lists some related issues. These are probably only interesting to people
146+ 
147+ These are probably only interesting to people
129148who really want to take a deep dive into the topic :)
130149
131150*  [ rust #60966 ] : The Rust PR that introduced diagnostic items
0 commit comments