11
11
12
12
use rustc_ast as ast;
13
13
use rustc_hir:: diagnostic_items:: DiagnosticItems ;
14
+ use rustc_hir:: OwnerId ;
14
15
use rustc_middle:: ty:: query:: Providers ;
15
16
use rustc_middle:: ty:: TyCtxt ;
16
- use rustc_span:: def_id:: { CrateNum , DefId , LocalDefId , LOCAL_CRATE } ;
17
- use rustc_span:: symbol:: { kw :: Empty , sym, Symbol } ;
17
+ use rustc_span:: def_id:: { CrateNum , DefId , LOCAL_CRATE } ;
18
+ use rustc_span:: symbol:: { sym, Symbol } ;
18
19
19
- use crate :: errors:: { DuplicateDiagnosticItem , DuplicateDiagnosticItemInCrate } ;
20
+ use crate :: errors:: DuplicateDiagnosticItemInCrate ;
20
21
21
- fn observe_item ( tcx : TyCtxt < ' _ > , diagnostic_items : & mut DiagnosticItems , def_id : LocalDefId ) {
22
- let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ;
23
- let attrs = tcx. hir ( ) . attrs ( hir_id) ;
22
+ fn observe_item < ' tcx > ( tcx : TyCtxt < ' tcx > , diagnostic_items : & mut DiagnosticItems , owner : OwnerId ) {
23
+ let attrs = tcx. hir ( ) . attrs ( owner. into ( ) ) ;
24
24
if let Some ( name) = extract ( attrs) {
25
25
// insert into our table
26
- collect_item ( tcx, diagnostic_items, name, def_id . to_def_id ( ) ) ;
26
+ collect_item ( tcx, diagnostic_items, name, owner . to_def_id ( ) ) ;
27
27
}
28
28
}
29
29
30
30
fn collect_item ( tcx : TyCtxt < ' _ > , items : & mut DiagnosticItems , name : Symbol , item_def_id : DefId ) {
31
31
items. id_to_name . insert ( item_def_id, name) ;
32
32
if let Some ( original_def_id) = items. name_to_id . insert ( name, item_def_id) {
33
33
if original_def_id != item_def_id {
34
- let orig_span = tcx. hir ( ) . span_if_local ( original_def_id) ;
35
- let orig_crate_name =
36
- orig_span. is_none ( ) . then ( || tcx. crate_name ( original_def_id. krate ) ) ;
37
- match tcx. hir ( ) . span_if_local ( item_def_id) {
38
- Some ( span) => tcx. sess . emit_err ( DuplicateDiagnosticItem { span, name } ) ,
39
- None => tcx. sess . emit_err ( DuplicateDiagnosticItemInCrate {
40
- span : orig_span,
41
- orig_crate_name : orig_crate_name. unwrap_or ( Empty ) ,
42
- have_orig_crate_name : orig_crate_name. map ( |_| ( ) ) ,
43
- crate_name : tcx. crate_name ( item_def_id. krate ) ,
44
- name,
45
- } ) ,
46
- } ;
34
+ report_duplicate_item ( tcx, name, original_def_id, item_def_id) ;
47
35
}
48
36
}
49
37
}
50
38
39
+ fn report_duplicate_item (
40
+ tcx : TyCtxt < ' _ > ,
41
+ name : Symbol ,
42
+ original_def_id : DefId ,
43
+ item_def_id : DefId ,
44
+ ) {
45
+ let orig_span = tcx. hir ( ) . span_if_local ( original_def_id) ;
46
+ let duplicate_span = tcx. hir ( ) . span_if_local ( item_def_id) ;
47
+ tcx. sess . emit_err ( DuplicateDiagnosticItemInCrate {
48
+ duplicate_span,
49
+ orig_span,
50
+ crate_name : tcx. crate_name ( item_def_id. krate ) ,
51
+ orig_crate_name : tcx. crate_name ( original_def_id. krate ) ,
52
+ different_crates : ( item_def_id. krate != original_def_id. krate ) . then_some ( ( ) ) ,
53
+ name,
54
+ } ) ;
55
+ }
56
+
51
57
/// Extract the first `rustc_diagnostic_item = "$name"` out of a list of attributes.
52
58
fn extract ( attrs : & [ ast:: Attribute ] ) -> Option < Symbol > {
53
59
attrs. iter ( ) . find_map ( |attr| {
@@ -64,21 +70,8 @@ fn diagnostic_items(tcx: TyCtxt<'_>, cnum: CrateNum) -> DiagnosticItems {
64
70
65
71
// Collect diagnostic items in this crate.
66
72
let crate_items = tcx. hir_crate_items ( ( ) ) ;
67
-
68
- for id in crate_items. items ( ) {
69
- observe_item ( tcx, & mut diagnostic_items, id. owner_id . def_id ) ;
70
- }
71
-
72
- for id in crate_items. trait_items ( ) {
73
- observe_item ( tcx, & mut diagnostic_items, id. owner_id . def_id ) ;
74
- }
75
-
76
- for id in crate_items. impl_items ( ) {
77
- observe_item ( tcx, & mut diagnostic_items, id. owner_id . def_id ) ;
78
- }
79
-
80
- for id in crate_items. foreign_items ( ) {
81
- observe_item ( tcx, & mut diagnostic_items, id. owner_id . def_id ) ;
73
+ for id in crate_items. owners ( ) {
74
+ observe_item ( tcx, & mut diagnostic_items, id) ;
82
75
}
83
76
84
77
diagnostic_items
0 commit comments