11//! Validity checking for weak lang items
22
3+ use rustc_ast as ast;
4+ use rustc_ast:: visit;
35use rustc_data_structures:: fx:: FxHashSet ;
46use rustc_hir:: lang_items:: { self , LangItem } ;
57use rustc_hir:: weak_lang_items:: WEAK_LANG_ITEMS ;
@@ -11,7 +13,7 @@ use crate::errors::{MissingLangItem, MissingPanicHandler, UnknownExternLangItem}
1113
1214/// Checks the crate for usage of weak lang items, returning a vector of all the
1315/// 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 ) {
1517 // These are never called by user code, they're generated by the compiler.
1618 // They will never implicitly be added to the `missing` array unless we do
1719 // so here.
@@ -22,24 +24,30 @@ pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) {
2224 items. missing . push ( LangItem :: EhCatchTypeinfo ) ;
2325 }
2426
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 ) {
2940 if let Some ( item) = LangItem :: from_name ( lang_item)
3041 && item. is_weak ( )
3142 {
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) ;
3445 }
3546 } 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 } ) ;
3848 }
3949 }
4050 }
41-
42- verify ( tcx, items) ;
4351}
4452
4553fn verify ( tcx : TyCtxt < ' _ > , items : & lang_items:: LanguageItems ) {
0 commit comments