add mapping from DefKind to Target and remove more ItemLikeVisitor impls
Signed-off-by: Miguel Guarniz <mi9uel9@gmail.com>
This commit is contained in:
parent
df10715463
commit
d2840d237c
@ -7,6 +7,7 @@
|
||||
use crate::hir;
|
||||
use crate::{Item, ItemKind, TraitItem, TraitItemKind};
|
||||
|
||||
use crate::def::DefKind;
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
@ -130,6 +131,29 @@ pub fn from_item(item: &Item<'_>) -> Target {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_def_kind(def_kind: DefKind) -> Target {
|
||||
match def_kind {
|
||||
DefKind::ExternCrate => Target::ExternCrate,
|
||||
DefKind::Use => Target::Use,
|
||||
DefKind::Static(..) => Target::Static,
|
||||
DefKind::Const => Target::Const,
|
||||
DefKind::Fn => Target::Fn,
|
||||
DefKind::Macro(..) => Target::MacroDef,
|
||||
DefKind::Mod => Target::Mod,
|
||||
DefKind::ForeignMod => Target::ForeignMod,
|
||||
DefKind::GlobalAsm => Target::GlobalAsm,
|
||||
DefKind::TyAlias => Target::TyAlias,
|
||||
DefKind::OpaqueTy => Target::OpaqueTy,
|
||||
DefKind::Enum => Target::Enum,
|
||||
DefKind::Struct => Target::Struct,
|
||||
DefKind::Union => Target::Union,
|
||||
DefKind::Trait => Target::Trait,
|
||||
DefKind::TraitAlias => Target::TraitAlias,
|
||||
DefKind::Impl => Target::Impl,
|
||||
_ => panic!("impossible case reached"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_trait_item(trait_item: &TraitItem<'_>) -> Target {
|
||||
match trait_item.kind {
|
||||
TraitItemKind::Const(..) => Target::AssocConst,
|
||||
|
@ -12,8 +12,8 @@
|
||||
|
||||
use rustc_errors::{pluralize, struct_span_err};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::itemlikevisit::ItemLikeVisitor;
|
||||
use rustc_hir::lang_items::{extract, GenericRequirement, ITEM_REFS};
|
||||
use rustc_hir::{HirId, LangItem, LanguageItems, Target};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
@ -27,28 +27,6 @@ struct LanguageItemCollector<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
}
|
||||
|
||||
impl<'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'tcx> {
|
||||
fn visit_item(&mut self, item: &hir::Item<'_>) {
|
||||
self.check_for_lang(Target::from_item(item), item.hir_id());
|
||||
|
||||
if let hir::ItemKind::Enum(def, ..) = &item.kind {
|
||||
for variant in def.variants {
|
||||
self.check_for_lang(Target::Variant, variant.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, trait_item: &hir::TraitItem<'_>) {
|
||||
self.check_for_lang(Target::from_trait_item(trait_item), trait_item.hir_id())
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) {
|
||||
self.check_for_lang(target_from_impl_item(self.tcx, impl_item), impl_item.hir_id())
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, _: &hir::ForeignItem<'_>) {}
|
||||
}
|
||||
|
||||
impl<'tcx> LanguageItemCollector<'tcx> {
|
||||
fn new(tcx: TyCtxt<'tcx>) -> LanguageItemCollector<'tcx> {
|
||||
LanguageItemCollector { tcx, items: LanguageItems::new() }
|
||||
@ -262,18 +240,28 @@ fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems {
|
||||
let crate_items = tcx.hir_crate_items(());
|
||||
|
||||
for id in crate_items.items() {
|
||||
let item = tcx.hir().item(id);
|
||||
collector.visit_item(item);
|
||||
collector.check_for_lang(Target::from_def_kind(tcx.hir().def_kind(id.def_id)), id.hir_id());
|
||||
|
||||
if matches!(tcx.hir().def_kind(id.def_id), DefKind::Enum) {
|
||||
let item = tcx.hir().item(id);
|
||||
if let hir::ItemKind::Enum(def, ..) = &item.kind {
|
||||
for variant in def.variants {
|
||||
collector.check_for_lang(Target::Variant, variant.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: avoid calling trait_item() when possible
|
||||
for id in crate_items.trait_items() {
|
||||
let item = tcx.hir().trait_item(id);
|
||||
collector.visit_trait_item(item);
|
||||
collector.check_for_lang(Target::from_trait_item(item), item.hir_id())
|
||||
}
|
||||
|
||||
// FIXME: avoid calling impl_item() when possible
|
||||
for id in crate_items.impl_items() {
|
||||
let item = tcx.hir().impl_item(id);
|
||||
collector.visit_impl_item(item);
|
||||
collector.check_for_lang(target_from_impl_item(tcx, item), item.hir_id())
|
||||
}
|
||||
|
||||
// Extract out the found lang items.
|
||||
|
@ -2,20 +2,11 @@
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::struct_span_err;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::lang_items::{self, LangItem};
|
||||
use rustc_hir::weak_lang_items::WEAK_ITEMS_REFS;
|
||||
use rustc_middle::middle::lang_items::required;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::config::CrateType;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::Span;
|
||||
|
||||
struct Context<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
items: &'a mut lang_items::LanguageItems,
|
||||
}
|
||||
|
||||
/// 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.
|
||||
@ -30,10 +21,28 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>, items: &mut lang_items::LanguageItem
|
||||
items.missing.push(LangItem::EhCatchTypeinfo);
|
||||
}
|
||||
|
||||
{
|
||||
let mut cx = Context { tcx, items };
|
||||
tcx.hir().visit_all_item_likes(&mut cx.as_deep_visitor());
|
||||
let crate_items = tcx.hir_crate_items(());
|
||||
for id in crate_items.foreign_items() {
|
||||
let attrs = tcx.hir().attrs(id.hir_id());
|
||||
let span = tcx.hir().span(id.hir_id());
|
||||
if let Some((lang_item, _)) = lang_items::extract(attrs) {
|
||||
if let Some(&item) = WEAK_ITEMS_REFS.get(&lang_item) {
|
||||
if items.require(item).is_err() {
|
||||
items.missing.push(item);
|
||||
}
|
||||
} else {
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
span,
|
||||
E0264,
|
||||
"unknown external lang item: `{}`",
|
||||
lang_item
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
verify(tcx, items);
|
||||
}
|
||||
|
||||
@ -80,26 +89,3 @@ fn verify<'tcx>(tcx: TyCtxt<'tcx>, items: &lang_items::LanguageItems) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Context<'a, 'tcx> {
|
||||
fn register(&mut self, name: Symbol, span: Span) {
|
||||
if let Some(&item) = WEAK_ITEMS_REFS.get(&name) {
|
||||
if self.items.require(item).is_err() {
|
||||
self.items.missing.push(item);
|
||||
}
|
||||
} else {
|
||||
struct_span_err!(self.tcx.sess, span, E0264, "unknown external lang item: `{}`", name)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
|
||||
fn visit_foreign_item(&mut self, i: &hir::ForeignItem<'_>) {
|
||||
let attrs = self.tcx.hir().attrs(i.hir_id());
|
||||
if let Some((lang_item, _)) = lang_items::extract(attrs) {
|
||||
self.register(lang_item, i.span);
|
||||
}
|
||||
intravisit::walk_foreign_item(self, i)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user