1
1
//! Validity checking for weak lang items
2
2
3
+ use rustc_ast as ast;
4
+ use rustc_ast:: visit;
3
5
use rustc_data_structures:: fx:: FxHashSet ;
4
6
use rustc_hir:: lang_items:: { self , LangItem } ;
5
7
use rustc_hir:: weak_lang_items:: WEAK_LANG_ITEMS ;
@@ -11,7 +13,7 @@ use crate::errors::{MissingLangItem, MissingPanicHandler, UnknownExternLangItem}
11
13
12
14
/// Checks the crate for usage of weak lang items, returning a vector of all the
13
15
/// language items required by this crate, but not defined yet.
14
- pub fn check_crate ( tcx : TyCtxt < ' _ > , items : & mut lang_items:: LanguageItems ) {
16
+ pub fn check_crate ( tcx : TyCtxt < ' _ > , items : & mut lang_items:: LanguageItems , krate : & ast :: Crate ) {
15
17
// These are never called by user code, they're generated by the compiler.
16
18
// They will never implicitly be added to the `missing` array unless we do
17
19
// so here.
@@ -22,24 +24,30 @@ pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) {
22
24
items. missing . push ( LangItem :: EhCatchTypeinfo ) ;
23
25
}
24
26
25
- let crate_items = tcx. hir_crate_items ( ( ) ) ;
26
- for id in crate_items. foreign_items ( ) {
27
- let attrs = tcx. hir ( ) . attrs ( id. hir_id ( ) ) ;
28
- if let Some ( ( lang_item, _) ) = lang_items:: extract ( attrs) {
27
+ visit:: Visitor :: visit_crate ( & mut WeakLangItemVisitor { tcx, items } , krate) ;
28
+
29
+ verify ( tcx, items) ;
30
+ }
31
+
32
+ struct WeakLangItemVisitor < ' a , ' tcx > {
33
+ tcx : TyCtxt < ' tcx > ,
34
+ items : & ' a mut lang_items:: LanguageItems ,
35
+ }
36
+
37
+ impl < ' ast > visit:: Visitor < ' ast > for WeakLangItemVisitor < ' _ , ' _ > {
38
+ fn visit_foreign_item ( & mut self , i : & ' ast ast:: ForeignItem ) {
39
+ if let Some ( ( lang_item, _) ) = lang_items:: extract ( & i. attrs ) {
29
40
if let Some ( item) = LangItem :: from_name ( lang_item)
30
41
&& item. is_weak ( )
31
42
{
32
- if items. get ( item) . is_none ( ) {
33
- items. missing . push ( item) ;
43
+ if self . items . get ( item) . is_none ( ) {
44
+ self . items . missing . push ( item) ;
34
45
}
35
46
} else {
36
- let span = tcx. def_span ( id. owner_id ) ;
37
- tcx. sess . emit_err ( UnknownExternLangItem { span, lang_item } ) ;
47
+ self . tcx . sess . emit_err ( UnknownExternLangItem { span : i. span , lang_item } ) ;
38
48
}
39
49
}
40
50
}
41
-
42
- verify ( tcx, items) ;
43
51
}
44
52
45
53
fn verify ( tcx : TyCtxt < ' _ > , items : & lang_items:: LanguageItems ) {
0 commit comments