1111
1212use rustc_ast as ast;
1313use rustc_hir:: diagnostic_items:: DiagnosticItems ;
14+ use rustc_hir:: OwnerId ;
1415use rustc_middle:: ty:: query:: Providers ;
1516use rustc_middle:: ty:: TyCtxt ;
16- use rustc_span:: def_id:: { CrateNum , DefId , LocalDefId , LOCAL_CRATE } ;
17+ use rustc_span:: def_id:: { CrateNum , DefId , LOCAL_CRATE } ;
1718use rustc_span:: symbol:: { kw:: Empty , sym, Symbol } ;
1819
1920use crate :: errors:: { DuplicateDiagnosticItem , DuplicateDiagnosticItemInCrate } ;
2021
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 ( ) ) ;
2424 if let Some ( name) = extract ( attrs) {
2525 // 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 ( ) ) ;
2727 }
2828}
2929
3030fn collect_item ( tcx : TyCtxt < ' _ > , items : & mut DiagnosticItems , name : Symbol , item_def_id : DefId ) {
3131 items. id_to_name . insert ( item_def_id, name) ;
3232 if let Some ( original_def_id) = items. name_to_id . insert ( name, item_def_id) {
3333 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) ;
4735 }
4836 }
4937}
5038
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, orig_crate_name, have_orig_crate_name) = match original_def_id. as_local ( ) {
46+ Some ( local_original) => ( Some ( tcx. def_span ( local_original) ) , Empty , None ) ,
47+ None => ( None , tcx. crate_name ( original_def_id. krate ) , Some ( ( ) ) ) ,
48+ } ;
49+ match tcx. hir ( ) . span_if_local ( item_def_id) {
50+ Some ( span) => tcx. sess . emit_err ( DuplicateDiagnosticItem { span, name } ) ,
51+ None => tcx. sess . emit_err ( DuplicateDiagnosticItemInCrate {
52+ span : orig_span,
53+ orig_crate_name,
54+ have_orig_crate_name,
55+ crate_name : tcx. crate_name ( item_def_id. krate ) ,
56+ name,
57+ } ) ,
58+ } ;
59+ }
60+
5161/// Extract the first `rustc_diagnostic_item = "$name"` out of a list of attributes.
5262fn extract ( attrs : & [ ast:: Attribute ] ) -> Option < Symbol > {
5363 attrs. iter ( ) . find_map ( |attr| {
@@ -64,21 +74,8 @@ fn diagnostic_items(tcx: TyCtxt<'_>, cnum: CrateNum) -> DiagnosticItems {
6474
6575 // Collect diagnostic items in this crate.
6676 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 ) ;
77+ for id in crate_items. owners ( ) {
78+ observe_item ( tcx, & mut diagnostic_items, id) ;
8279 }
8380
8481 diagnostic_items
0 commit comments