summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_passes/src/weak_lang_items.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_passes/src/weak_lang_items.rs')
-rw-r--r--compiler/rustc_passes/src/weak_lang_items.rs30
1 files changed, 19 insertions, 11 deletions
diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs
index 9a6fb88c2..b226c65e9 100644
--- a/compiler/rustc_passes/src/weak_lang_items.rs
+++ b/compiler/rustc_passes/src/weak_lang_items.rs
@@ -1,5 +1,7 @@
//! Validity checking for weak lang items
+use rustc_ast as ast;
+use rustc_ast::visit;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::lang_items::{self, LangItem};
use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
@@ -11,7 +13,7 @@ use crate::errors::{MissingLangItem, MissingPanicHandler, UnknownExternLangItem}
/// Checks the crate for usage of weak lang items, returning a vector of all the
/// language items required by this crate, but not defined yet.
-pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) {
+pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems, krate: &ast::Crate) {
// These are never called by user code, they're generated by the compiler.
// They will never implicitly be added to the `missing` array unless we do
// so here.
@@ -22,24 +24,30 @@ pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) {
items.missing.push(LangItem::EhCatchTypeinfo);
}
- let crate_items = tcx.hir_crate_items(());
- for id in crate_items.foreign_items() {
- let attrs = tcx.hir().attrs(id.hir_id());
- if let Some((lang_item, _)) = lang_items::extract(attrs) {
+ visit::Visitor::visit_crate(&mut WeakLangItemVisitor { tcx, items }, krate);
+
+ verify(tcx, items);
+}
+
+struct WeakLangItemVisitor<'a, 'tcx> {
+ tcx: TyCtxt<'tcx>,
+ items: &'a mut lang_items::LanguageItems,
+}
+
+impl<'ast> visit::Visitor<'ast> for WeakLangItemVisitor<'_, '_> {
+ fn visit_foreign_item(&mut self, i: &'ast ast::ForeignItem) {
+ if let Some((lang_item, _)) = lang_items::extract(&i.attrs) {
if let Some(item) = LangItem::from_name(lang_item)
&& item.is_weak()
{
- if items.get(item).is_none() {
- items.missing.push(item);
+ if self.items.get(item).is_none() {
+ self.items.missing.push(item);
}
} else {
- let span = tcx.def_span(id.owner_id);
- tcx.sess.emit_err(UnknownExternLangItem { span, lang_item });
+ self.tcx.sess.emit_err(UnknownExternLangItem { span: i.span, lang_item });
}
}
}
-
- verify(tcx, items);
}
fn verify(tcx: TyCtxt<'_>, items: &lang_items::LanguageItems) {