77//! * Traits that represent operators; e.g., `Add`, `Sub`, `Index`.
88//! * Functions called by the compiler itself.
99
10+ use crate :: check_attr:: target_from_impl_item;
1011use crate :: weak_lang_items;
1112
1213use rustc_middle:: middle:: cstore:: ExternCrate ;
1314use rustc_middle:: ty:: TyCtxt ;
1415
16+ use rustc_ast:: ast:: Attribute ;
1517use rustc_errors:: struct_span_err;
1618use rustc_hir as hir;
1719use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
1820use rustc_hir:: itemlikevisit:: ItemLikeVisitor ;
1921use rustc_hir:: lang_items:: { extract, ITEM_REFS } ;
20- use rustc_hir:: { LangItem , LanguageItems , Target } ;
22+ use rustc_hir:: { HirId , LangItem , LanguageItems , Target } ;
2123
2224use rustc_middle:: ty:: query:: Providers ;
2325
@@ -28,12 +30,37 @@ struct LanguageItemCollector<'tcx> {
2830
2931impl ItemLikeVisitor < ' v > for LanguageItemCollector < ' tcx > {
3032 fn visit_item ( & mut self , item : & hir:: Item < ' _ > ) {
31- if let Some ( ( value, span) ) = extract ( & item. attrs ) {
32- let actual_target = Target :: from_item ( item) ;
33+ self . check_for_lang ( Target :: from_item ( item) , item. hir_id , item. attrs )
34+ }
35+
36+ fn visit_trait_item ( & mut self , trait_item : & hir:: TraitItem < ' _ > ) {
37+ self . check_for_lang (
38+ Target :: from_trait_item ( trait_item) ,
39+ trait_item. hir_id ,
40+ trait_item. attrs ,
41+ )
42+ }
43+
44+ fn visit_impl_item ( & mut self , impl_item : & hir:: ImplItem < ' _ > ) {
45+ self . check_for_lang (
46+ target_from_impl_item ( self . tcx , impl_item) ,
47+ impl_item. hir_id ,
48+ impl_item. attrs ,
49+ )
50+ }
51+ }
52+
53+ impl LanguageItemCollector < ' tcx > {
54+ fn new ( tcx : TyCtxt < ' tcx > ) -> LanguageItemCollector < ' tcx > {
55+ LanguageItemCollector { tcx, items : LanguageItems :: new ( ) }
56+ }
57+
58+ fn check_for_lang ( & mut self , actual_target : Target , hir_id : HirId , attrs : & [ Attribute ] ) {
59+ if let Some ( ( value, span) ) = extract ( & attrs) {
3360 match ITEM_REFS . get ( & * value. as_str ( ) ) . cloned ( ) {
3461 // Known lang item with attribute on correct target.
3562 Some ( ( item_index, expected_target) ) if actual_target == expected_target => {
36- let def_id = self . tcx . hir ( ) . local_def_id ( item . hir_id ) ;
63+ let def_id = self . tcx . hir ( ) . local_def_id ( hir_id) ;
3764 self . collect_item ( item_index, def_id. to_def_id ( ) ) ;
3865 }
3966 // Known lang item with attribute on incorrect target.
@@ -71,20 +98,6 @@ impl ItemLikeVisitor<'v> for LanguageItemCollector<'tcx> {
7198 }
7299 }
73100
74- fn visit_trait_item ( & mut self , _trait_item : & hir:: TraitItem < ' _ > ) {
75- // At present, lang items are always items, not trait items.
76- }
77-
78- fn visit_impl_item ( & mut self , _impl_item : & hir:: ImplItem < ' _ > ) {
79- // At present, lang items are always items, not impl items.
80- }
81- }
82-
83- impl LanguageItemCollector < ' tcx > {
84- fn new ( tcx : TyCtxt < ' tcx > ) -> LanguageItemCollector < ' tcx > {
85- LanguageItemCollector { tcx, items : LanguageItems :: new ( ) }
86- }
87-
88101 fn collect_item ( & mut self , item_index : usize , item_def_id : DefId ) {
89102 // Check for duplicates.
90103 if let Some ( original_def_id) = self . items . items [ item_index] {
0 commit comments