Collect lang items from AST
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user