7
7
//! * Traits that represent operators; e.g., `Add`, `Sub`, `Index`.
8
8
//! * Functions called by the compiler itself.
9
9
10
+ use crate :: check_attr:: target_from_impl_item;
10
11
use crate :: weak_lang_items;
11
12
12
13
use rustc_middle:: middle:: cstore:: ExternCrate ;
13
14
use rustc_middle:: ty:: TyCtxt ;
14
15
16
+ use rustc_ast:: ast:: Attribute ;
15
17
use rustc_errors:: struct_span_err;
16
18
use rustc_hir as hir;
17
19
use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
18
20
use rustc_hir:: itemlikevisit:: ItemLikeVisitor ;
19
21
use rustc_hir:: lang_items:: { extract, ITEM_REFS } ;
20
- use rustc_hir:: { LangItem , LanguageItems , Target } ;
22
+ use rustc_hir:: { HirId , LangItem , LanguageItems , Target } ;
21
23
22
24
use rustc_middle:: ty:: query:: Providers ;
23
25
@@ -28,12 +30,37 @@ struct LanguageItemCollector<'tcx> {
28
30
29
31
impl ItemLikeVisitor < ' v > for LanguageItemCollector < ' tcx > {
30
32
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) {
33
60
match ITEM_REFS . get ( & * value. as_str ( ) ) . cloned ( ) {
34
61
// Known lang item with attribute on correct target.
35
62
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) ;
37
64
self . collect_item ( item_index, def_id. to_def_id ( ) ) ;
38
65
}
39
66
// Known lang item with attribute on incorrect target.
@@ -71,20 +98,6 @@ impl ItemLikeVisitor<'v> for LanguageItemCollector<'tcx> {
71
98
}
72
99
}
73
100
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
-
88
101
fn collect_item ( & mut self , item_index : usize , item_def_id : DefId ) {
89
102
// Check for duplicates.
90
103
if let Some ( original_def_id) = self . items . items [ item_index] {
0 commit comments