Collect lang items from AST

This commit is contained in:
Michael Goulet
2023-11-23 04:45:42 +00:00
parent 4d1bd0db7f
commit ad00641b74
12 changed files with 325 additions and 178 deletions

View File

@@ -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) {