提交 c9228570 编写于 作者: B bors

Auto merge of #79318 - cjgillot:fitem, r=lcnr

Store HIR ForeignItem in a side table

In a similar fashion to Item, ImplItem and TraitItem.
......@@ -43,6 +43,7 @@ fn visit_mod(&mut self, m: &'a Mod, _s: Span, _attrs: &[Attribute], n: NodeId) {
items: BTreeSet::new(),
trait_items: BTreeSet::new(),
impl_items: BTreeSet::new(),
foreign_items: BTreeSet::new(),
},
);
......@@ -105,6 +106,18 @@ fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
visit::walk_assoc_item(self, item, ctxt);
}
fn visit_foreign_item(&mut self, item: &'a ForeignItem) {
self.lctx.allocate_hir_id_counter(item.id);
self.lctx.with_hir_id_owner(item.id, |lctx| {
let hir_item = lctx.lower_foreign_item(item);
let id = hir::ForeignItemId { hir_id: hir_item.hir_id };
lctx.foreign_items.insert(id, hir_item);
lctx.modules.get_mut(&lctx.current_module).unwrap().foreign_items.insert(id);
});
visit::walk_foreign_item(self, item);
}
}
impl<'hir> LoweringContext<'_, 'hir> {
......@@ -304,7 +317,12 @@ fn lower_item_kind(
})
}
ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)),
ItemKind::ForeignMod(ref fm) => hir::ItemKind::ForeignMod {
abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
items: self
.arena
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
},
ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
ItemKind::TyAlias(_, ref gen, _, Some(ref ty)) => {
// We lower
......@@ -704,10 +722,12 @@ fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem<'hir> {
}
}
fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod<'hir> {
hir::ForeignMod {
abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
items: self.arena.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item(x))),
fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef<'hir> {
hir::ForeignItemRef {
id: hir::ForeignItemId { hir_id: self.lower_node_id(i.id) },
ident: i.ident,
span: i.span,
vis: self.lower_visibility(&i.vis, Some(i.id)),
}
}
......
......@@ -101,6 +101,7 @@ struct LoweringContext<'a, 'hir: 'a> {
trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem<'hir>>,
impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem<'hir>>,
foreign_items: BTreeMap<hir::ForeignItemId, hir::ForeignItem<'hir>>,
bodies: BTreeMap<hir::BodyId, hir::Body<'hir>>,
exported_macros: Vec<hir::MacroDef<'hir>>,
non_exported_macro_attrs: Vec<ast::Attribute>,
......@@ -298,6 +299,7 @@ pub fn lower_crate<'a, 'hir>(
items: BTreeMap::new(),
trait_items: BTreeMap::new(),
impl_items: BTreeMap::new(),
foreign_items: BTreeMap::new(),
bodies: BTreeMap::new(),
trait_impls: BTreeMap::new(),
modules: BTreeMap::new(),
......@@ -485,6 +487,11 @@ fn visit_assoc_item(&mut self, item: &'tcx AssocItem, ctxt: AssocCtxt) {
visit::walk_assoc_item(self, item, ctxt);
}
fn visit_foreign_item(&mut self, item: &'tcx ForeignItem) {
self.lctx.allocate_hir_id_counter(item.id);
visit::walk_foreign_item(self, item);
}
fn visit_ty(&mut self, t: &'tcx Ty) {
match t.kind {
// Mirrors the case in visit::walk_ty
......@@ -548,6 +555,7 @@ fn visit_ty(&mut self, t: &'tcx Ty) {
items: self.items,
trait_items: self.trait_items,
impl_items: self.impl_items,
foreign_items: self.foreign_items,
bodies: self.bodies,
body_ids,
trait_impls: self.trait_impls,
......
......@@ -29,6 +29,7 @@
[] field_pat: rustc_hir::FieldPat<$tcx>,
[] fn_decl: rustc_hir::FnDecl<$tcx>,
[] foreign_item: rustc_hir::ForeignItem<$tcx>,
[few] foreign_item_ref: rustc_hir::ForeignItemRef<$tcx>,
[] impl_item_ref: rustc_hir::ImplItemRef<$tcx>,
[few] inline_asm: rustc_hir::InlineAsm<$tcx>,
[few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>,
......
......@@ -579,6 +579,7 @@ pub struct ModuleItems {
pub items: BTreeSet<HirId>,
pub trait_items: BTreeSet<TraitItemId>,
pub impl_items: BTreeSet<ImplItemId>,
pub foreign_items: BTreeSet<ForeignItemId>,
}
/// A type representing only the top-level module.
......@@ -612,6 +613,7 @@ pub struct Crate<'hir> {
pub trait_items: BTreeMap<TraitItemId, TraitItem<'hir>>,
pub impl_items: BTreeMap<ImplItemId, ImplItem<'hir>>,
pub foreign_items: BTreeMap<ForeignItemId, ForeignItem<'hir>>,
pub bodies: BTreeMap<BodyId, Body<'hir>>,
pub trait_impls: BTreeMap<DefId, Vec<HirId>>,
......@@ -644,6 +646,10 @@ pub fn impl_item(&self, id: ImplItemId) -> &ImplItem<'hir> {
&self.impl_items[&id]
}
pub fn foreign_item(&self, id: ForeignItemId) -> &ForeignItem<'hir> {
&self.foreign_items[&id]
}
pub fn body(&self, id: BodyId) -> &Body<'hir> {
&self.bodies[&id]
}
......@@ -673,6 +679,10 @@ pub fn visit_all_item_likes<'hir, V>(&'hir self, visitor: &mut V)
for impl_item in self.impl_items.values() {
visitor.visit_impl_item(impl_item);
}
for foreign_item in self.foreign_items.values() {
visitor.visit_foreign_item(foreign_item);
}
}
/// A parallel version of `visit_all_item_likes`.
......@@ -695,6 +705,11 @@ pub fn par_visit_all_item_likes<'hir, V>(&'hir self, visitor: &V)
par_for_each_in(&self.impl_items, |(_, impl_item)| {
visitor.visit_impl_item(impl_item);
});
},
{
par_for_each_in(&self.foreign_items, |(_, foreign_item)| {
visitor.visit_foreign_item(foreign_item);
});
}
);
}
......@@ -1840,7 +1855,7 @@ pub struct FnSig<'hir> {
}
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the node-id of the item
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
pub struct TraitItemId {
......@@ -1884,7 +1899,7 @@ pub enum TraitItemKind<'hir> {
}
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the node-id of the item
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
pub struct ImplItemId {
......@@ -2269,12 +2284,6 @@ pub struct Mod<'hir> {
pub item_ids: &'hir [ItemId],
}
#[derive(Debug, HashStable_Generic)]
pub struct ForeignMod<'hir> {
pub abi: Abi,
pub items: &'hir [ForeignItem<'hir>],
}
#[derive(Encodable, Debug, HashStable_Generic)]
pub struct GlobalAsm {
pub asm: Symbol,
......@@ -2432,7 +2441,7 @@ pub fn ctor_hir_id(&self) -> Option<HirId> {
}
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the node-id of the item
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, Encodable, Debug)]
pub struct ItemId {
......@@ -2521,7 +2530,7 @@ pub enum ItemKind<'hir> {
/// A module.
Mod(Mod<'hir>),
/// An external module, e.g. `extern { .. }`.
ForeignMod(ForeignMod<'hir>),
ForeignMod { abi: Abi, items: &'hir [ForeignItemRef<'hir>] },
/// Module-level inline assembly (from `global_asm!`).
GlobalAsm(&'hir GlobalAsm),
/// A type alias, e.g., `type Foo = Bar<u8>`.
......@@ -2614,6 +2623,29 @@ pub enum AssocItemKind {
Type,
}
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
pub struct ForeignItemId {
pub hir_id: HirId,
}
/// A reference from a foreign block to one of its items. This
/// contains the item's ID, naturally, but also the item's name and
/// some other high-level details (like whether it is an associated
/// type or method, and whether it is public). This allows other
/// passes to find the impl they want without loading the ID (which
/// means fewer edges in the incremental compilation graph).
#[derive(Debug, HashStable_Generic)]
pub struct ForeignItemRef<'hir> {
pub id: ForeignItemId,
#[stable_hasher(project(name))]
pub ident: Ident,
pub span: Span,
pub vis: Visibility<'hir>,
}
#[derive(Debug, HashStable_Generic)]
pub struct ForeignItem<'hir> {
#[stable_hasher(project(name))]
......
......@@ -64,6 +64,10 @@ fn visit_trait_item(&mut self, trait_item: &'hir TraitItem<'hir>) {
fn visit_impl_item(&mut self, impl_item: &'hir ImplItem<'hir>) {
self.visitor.visit_impl_item(impl_item);
}
fn visit_foreign_item(&mut self, foreign_item: &'hir ForeignItem<'hir>) {
self.visitor.visit_foreign_item(foreign_item);
}
}
pub trait IntoVisitor<'hir> {
......@@ -88,6 +92,10 @@ fn visit_trait_item(&self, trait_item: &'hir TraitItem<'hir>) {
fn visit_impl_item(&self, impl_item: &'hir ImplItem<'hir>) {
self.0.into_visitor().visit_impl_item(impl_item);
}
fn visit_foreign_item(&self, foreign_item: &'hir ForeignItem<'hir>) {
self.0.into_visitor().visit_foreign_item(foreign_item);
}
}
#[derive(Copy, Clone)]
......@@ -128,6 +136,7 @@ pub trait Map<'hir> {
fn item(&self, id: HirId) -> &'hir Item<'hir>;
fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>;
fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir>;
fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir>;
}
/// An erased version of `Map<'hir>`, using dynamic dispatch.
......@@ -150,6 +159,9 @@ fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir> {
fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir> {
self.0.impl_item(id)
}
fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir> {
self.0.foreign_item(id)
}
}
/// Specifies what nested things a visitor wants to visit. The most
......@@ -277,6 +289,14 @@ fn visit_nested_impl_item(&mut self, id: ImplItemId) {
walk_list!(self, visit_impl_item, opt_item);
}
/// Like `visit_nested_item()`, but for foreign items. See
/// `visit_nested_item()` for advice on when to override this
/// method.
fn visit_nested_foreign_item(&mut self, id: ForeignItemId) {
let opt_item = self.nested_visit_map().inter().map(|map| map.foreign_item(id));
walk_list!(self, visit_foreign_item, opt_item);
}
/// Invoked to visit the body of a function, method or closure. Like
/// visit_nested_item, does nothing by default unless you override
/// `nested_visit_map` to return other than `None`, in which case it will walk
......@@ -378,6 +398,9 @@ fn visit_trait_item_ref(&mut self, ii: &'v TraitItemRef) {
fn visit_impl_item(&mut self, ii: &'v ImplItem<'v>) {
walk_impl_item(self, ii)
}
fn visit_foreign_item_ref(&mut self, ii: &'v ForeignItemRef<'v>) {
walk_foreign_item_ref(self, ii)
}
fn visit_impl_item_ref(&mut self, ii: &'v ImplItemRef<'v>) {
walk_impl_item_ref(self, ii)
}
......@@ -566,9 +589,9 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
// `visit_mod()` takes care of visiting the `Item`'s `HirId`.
visitor.visit_mod(module, item.span, item.hir_id)
}
ItemKind::ForeignMod(ref foreign_module) => {
ItemKind::ForeignMod { abi: _, items } => {
visitor.visit_id(item.hir_id);
walk_list!(visitor, visit_foreign_item, foreign_module.items);
walk_list!(visitor, visit_foreign_item_ref, items);
}
ItemKind::GlobalAsm(_) => {
visitor.visit_id(item.hir_id);
......@@ -1012,6 +1035,17 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
}
}
pub fn walk_foreign_item_ref<'v, V: Visitor<'v>>(
visitor: &mut V,
foreign_item_ref: &'v ForeignItemRef<'v>,
) {
// N.B., deliberately force a compilation error if/when new fields are added.
let ForeignItemRef { id, ident, span: _, ref vis } = *foreign_item_ref;
visitor.visit_nested_foreign_item(id);
visitor.visit_ident(ident);
visitor.visit_vis(vis);
}
pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'v ImplItemRef<'v>) {
// N.B., deliberately force a compilation error if/when new fields are added.
let ImplItemRef { id, ident, ref kind, span: _, ref vis, ref defaultness } = *impl_item_ref;
......
use super::{ImplItem, Item, TraitItem};
use super::{ForeignItem, ImplItem, Item, TraitItem};
/// The "item-like visitor" defines only the top-level methods
/// that can be invoked by `Crate::visit_all_item_likes()`. Whether
......@@ -47,6 +47,7 @@ pub trait ItemLikeVisitor<'hir> {
fn visit_item(&mut self, item: &'hir Item<'hir>);
fn visit_trait_item(&mut self, trait_item: &'hir TraitItem<'hir>);
fn visit_impl_item(&mut self, impl_item: &'hir ImplItem<'hir>);
fn visit_foreign_item(&mut self, foreign_item: &'hir ForeignItem<'hir>);
}
/// A parallel variant of `ItemLikeVisitor`.
......@@ -54,4 +55,5 @@ pub trait ParItemLikeVisitor<'hir> {
fn visit_item(&self, item: &'hir Item<'hir>);
fn visit_trait_item(&self, trait_item: &'hir TraitItem<'hir>);
fn visit_impl_item(&self, impl_item: &'hir ImplItem<'hir>);
fn visit_foreign_item(&self, foreign_item: &'hir ForeignItem<'hir>);
}
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
use crate::hir::{
BodyId, Expr, ImplItem, ImplItemId, Item, ItemId, Mod, TraitItem, TraitItemId, Ty,
VisibilityKind,
BodyId, Expr, ForeignItemId, ImplItem, ImplItemId, Item, ItemId, Mod, TraitItem, TraitItemId,
Ty, VisibilityKind,
};
use crate::hir_id::{HirId, ItemLocalId};
use rustc_span::def_id::{DefPathHash, LocalDefId};
......@@ -52,6 +52,15 @@ fn to_stable_hash_key(&self, hcx: &HirCtx) -> (DefPathHash, ItemLocalId) {
}
}
impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ForeignItemId {
type KeyType = (DefPathHash, ItemLocalId);
#[inline]
fn to_stable_hash_key(&self, hcx: &HirCtx) -> (DefPathHash, ItemLocalId) {
self.hir_id.to_stable_hash_key(hcx)
}
}
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for HirId {
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
hcx.hash_hir_id(*self, hasher)
......@@ -77,6 +86,12 @@ fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
}
}
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ForeignItemId {
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
hcx.hash_reference_to_item(self.hir_id, hasher)
}
}
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ImplItemId {
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
hcx.hash_reference_to_item(self.hir_id, hasher)
......
......@@ -91,7 +91,7 @@ pub fn from_item(item: &Item<'_>) -> Target {
ItemKind::Const(..) => Target::Const,
ItemKind::Fn(..) => Target::Fn,
ItemKind::Mod(..) => Target::Mod,
ItemKind::ForeignMod(..) => Target::ForeignMod,
ItemKind::ForeignMod { .. } => Target::ForeignMod,
ItemKind::GlobalAsm(..) => Target::GlobalAsm,
ItemKind::TyAlias(..) => Target::TyAlias,
ItemKind::OpaqueTy(..) => Target::OpaqueTy,
......
......@@ -36,6 +36,7 @@ pub enum Nested {
Item(hir::ItemId),
TraitItem(hir::TraitItemId),
ImplItem(hir::ImplItemId),
ForeignItem(hir::ForeignItemId),
Body(hir::BodyId),
BodyParamPat(hir::BodyId, usize),
}
......@@ -56,6 +57,7 @@ fn nested(&self, state: &mut State<'_>, nested: Nested) {
Nested::Item(id) => state.print_item(self.item(id.id)),
Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
Nested::ForeignItem(id) => state.print_foreign_item(self.foreign_item(id)),
Nested::Body(id) => state.print_expr(&self.body(id).value),
Nested::BodyParamPat(id, i) => state.print_pat(&self.body(id).params[i].pat),
}
......@@ -70,6 +72,7 @@ fn nested(&self, state: &mut State<'_>, nested: Nested) {
Nested::Item(id) => state.print_item(self.item(id.id)),
Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
Nested::ForeignItem(id) => state.print_foreign_item(self.foreign_item(id)),
Nested::Body(id) => state.print_expr(&self.body(id).value),
Nested::BodyParamPat(id, i) => state.print_pat(&self.body(id).params[i].pat),
}
......@@ -349,13 +352,6 @@ pub fn print_mod(&mut self, _mod: &hir::Mod<'_>, attrs: &[ast::Attribute]) {
}
}
pub fn print_foreign_mod(&mut self, nmod: &hir::ForeignMod<'_>, attrs: &[ast::Attribute]) {
self.print_inner_attributes(attrs);
for item in nmod.items {
self.print_foreign_item(item);
}
}
pub fn print_opt_lifetime(&mut self, lifetime: &hir::Lifetime) {
if !lifetime.is_elided() {
self.print_lifetime(lifetime);
......@@ -644,11 +640,14 @@ pub fn print_item(&mut self, item: &hir::Item<'_>) {
self.print_mod(_mod, &item.attrs);
self.bclose(item.span);
}
hir::ItemKind::ForeignMod(ref nmod) => {
hir::ItemKind::ForeignMod { abi, items } => {
self.head("extern");
self.word_nbsp(nmod.abi.to_string());
self.word_nbsp(abi.to_string());
self.bopen();
self.print_foreign_mod(nmod, &item.attrs);
self.print_inner_attributes(item.attrs);
for item in items {
self.ann.nested(self, Nested::ForeignItem(item.id));
}
self.bclose(item.span);
}
hir::ItemKind::GlobalAsm(ref ga) => {
......
......@@ -280,7 +280,7 @@ fn auto_labels(&mut self, item_id: hir::HirId, attr: &Attribute) -> (&'static st
HirItem::Mod(..) => ("ItemMod", LABELS_HIR_ONLY),
// // An external module
HirItem::ForeignMod(..) => ("ItemForeignMod", LABELS_HIR_ONLY),
HirItem::ForeignMod { .. } => ("ItemForeignMod", LABELS_HIR_ONLY),
// Module-level inline assembly (from global_asm!)
HirItem::GlobalAsm(..) => ("ItemGlobalAsm", LABELS_HIR_ONLY),
......@@ -460,6 +460,10 @@ fn visit_trait_item(&mut self, item: &hir::TraitItem<'_>) {
fn visit_impl_item(&mut self, item: &hir::ImplItem<'_>) {
self.check_item(item.hir_id, item.span);
}
fn visit_foreign_item(&mut self, item: &hir::ForeignItem<'_>) {
self.check_item(item.hir_id, item.span);
}
}
/// Given a `#[rustc_dirty]` or `#[rustc_clean]` attribute, scan
......
......@@ -33,6 +33,8 @@ fn visit_item(&mut self, item: &hir::Item<'_>) {
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
}
pub(crate) fn provide(providers: &mut Providers) {
......
......@@ -16,13 +16,13 @@ struct Collector<'tcx> {
impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
let fm = match it.kind {
hir::ItemKind::ForeignMod(ref fm) => fm,
let items = match it.kind {
hir::ItemKind::ForeignMod { items, .. } => items,
_ => return,
};
let foreign_items =
fm.items.iter().map(|it| self.tcx.hir().local_def_id(it.hir_id).to_def_id()).collect();
items.iter().map(|it| self.tcx.hir().local_def_id(it.id.hir_id).to_def_id()).collect();
self.modules.push(ForeignModule {
foreign_items,
def_id: self.tcx.hir().local_def_id(it.hir_id).to_def_id(),
......@@ -31,4 +31,5 @@ fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem<'tcx>) {}
fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem<'tcx>) {}
fn visit_foreign_item(&mut self, _it: &'tcx hir::ForeignItem<'tcx>) {}
}
......@@ -26,11 +26,11 @@ struct Collector<'tcx> {
impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> {
fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
let fm = match it.kind {
hir::ItemKind::ForeignMod(ref fm) => fm,
let abi = match it.kind {
hir::ItemKind::ForeignMod { abi, .. } => abi,
_ => return,
};
if fm.abi == Abi::Rust || fm.abi == Abi::RustIntrinsic || fm.abi == Abi::PlatformIntrinsic {
if abi == Abi::Rust || abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic {
return;
}
......@@ -45,6 +45,7 @@ fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem<'tcx>) {}
fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem<'tcx>) {}
fn visit_foreign_item(&mut self, _it: &'tcx hir::ForeignItem<'tcx>) {}
}
impl<'tcx> Collector<'tcx> {
......
......@@ -33,12 +33,12 @@ struct Collector<'tcx> {
impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
let fm = match it.kind {
hir::ItemKind::ForeignMod(ref fm) => fm,
let abi = match it.kind {
hir::ItemKind::ForeignMod { abi, .. } => abi,
_ => return,
};
if fm.abi == Abi::Rust || fm.abi == Abi::RustIntrinsic || fm.abi == Abi::PlatformIntrinsic {
if abi == Abi::Rust || abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic {
return;
}
......@@ -127,6 +127,7 @@ fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem<'tcx>) {}
fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem<'tcx>) {}
fn visit_foreign_item(&mut self, _it: &'tcx hir::ForeignItem<'tcx>) {}
}
impl Collector<'tcx> {
......
......@@ -1225,7 +1225,7 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) {
hir::ItemKind::Mod(ref m) => {
return self.encode_info_for_mod(item.hir_id, m, &item.attrs);
}
hir::ItemKind::ForeignMod(_) => EntryKind::ForeignMod,
hir::ItemKind::ForeignMod { .. } => EntryKind::ForeignMod,
hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm,
hir::ItemKind::TyAlias(..) => EntryKind::Type,
hir::ItemKind::OpaqueTy(..) => {
......@@ -1320,11 +1320,11 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) {
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expansion_that_defined(def_id));
// FIXME(eddyb) there should be a nicer way to do this.
match item.kind {
hir::ItemKind::ForeignMod(ref fm) => record!(self.tables.children[def_id] <-
fm.items
hir::ItemKind::ForeignMod { items, .. } => record!(self.tables.children[def_id] <-
items
.iter()
.map(|foreign_item| tcx.hir().local_def_id(
foreign_item.hir_id).local_def_index)
foreign_item.id.hir_id).local_def_index)
),
hir::ItemKind::Enum(..) => record!(self.tables.children[def_id] <-
self.tcx.adt_def(def_id).variants.iter().map(|v| {
......@@ -1836,7 +1836,7 @@ fn encode_addl_info_for_item(&mut self, item: &hir::Item<'_>) {
| hir::ItemKind::Const(..)
| hir::ItemKind::Fn(..)
| hir::ItemKind::Mod(..)
| hir::ItemKind::ForeignMod(..)
| hir::ItemKind::ForeignMod { .. }
| hir::ItemKind::GlobalAsm(..)
| hir::ItemKind::ExternCrate(..)
| hir::ItemKind::Use(..)
......@@ -1913,6 +1913,8 @@ fn visit_trait_item(&mut self, _trait_item: &'v hir::TraitItem<'v>) {}
fn visit_impl_item(&mut self, _impl_item: &'v hir::ImplItem<'v>) {
// handled in `visit_item` above
}
fn visit_foreign_item(&mut self, _foreign_item: &'v hir::ForeignItem<'v>) {}
}
/// Used to prefetch queries which will be needed later by metadata encoding.
......@@ -1977,6 +1979,11 @@ fn visit_impl_item(&self, impl_item: &'v hir::ImplItem<'v>) {
hir::ImplItemKind::TyAlias(..) => (),
}
}
fn visit_foreign_item(&self, _foreign_item: &'v hir::ForeignItem<'v>) {
// This should be kept in sync with `encode_info_for_foreign_item`.
// Foreign items contain no MIR.
}
}
// NOTE(eddyb) The following comment was preserved for posterity, even
......
......@@ -112,6 +112,7 @@ pub(super) fn root(
items: _,
trait_items: _,
impl_items: _,
foreign_items: _,
bodies: _,
trait_impls: _,
body_ids: _,
......@@ -319,6 +320,10 @@ fn visit_nested_impl_item(&mut self, item_id: ImplItemId) {
self.visit_impl_item(self.krate.impl_item(item_id));
}
fn visit_nested_foreign_item(&mut self, foreign_id: ForeignItemId) {
self.visit_foreign_item(self.krate.foreign_item(foreign_id));
}
fn visit_nested_body(&mut self, id: BodyId) {
self.visit_body(self.krate.body(id));
}
......@@ -351,11 +356,17 @@ fn visit_item(&mut self, i: &'hir Item<'hir>) {
});
}
fn visit_foreign_item(&mut self, foreign_item: &'hir ForeignItem<'hir>) {
self.insert(foreign_item.span, foreign_item.hir_id, Node::ForeignItem(foreign_item));
fn visit_foreign_item(&mut self, fi: &'hir ForeignItem<'hir>) {
debug_assert_eq!(
fi.hir_id.owner,
self.definitions.opt_hir_id_to_local_def_id(fi.hir_id).unwrap()
);
self.with_dep_node_owner(fi.hir_id.owner, fi, |this, hash| {
this.insert_with_hash(fi.span, fi.hir_id, Node::ForeignItem(fi), hash);
self.with_parent(foreign_item.hir_id, |this| {
intravisit::walk_foreign_item(this, foreign_item);
this.with_parent(fi.hir_id, |this| {
intravisit::walk_foreign_item(this, fi);
});
});
}
......
......@@ -205,7 +205,7 @@ pub fn def_kind(&self, local_def_id: LocalDefId) -> DefKind {
ItemKind::TraitAlias(..) => DefKind::TraitAlias,
ItemKind::ExternCrate(_) => DefKind::ExternCrate,
ItemKind::Use(..) => DefKind::Use,
ItemKind::ForeignMod(..) => DefKind::ForeignMod,
ItemKind::ForeignMod { .. } => DefKind::ForeignMod,
ItemKind::GlobalAsm(..) => DefKind::GlobalAsm,
ItemKind::Impl { .. } => DefKind::Impl,
},
......@@ -309,6 +309,13 @@ pub fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir> {
}
}
pub fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir> {
match self.find(id.hir_id).unwrap() {
Node::ForeignItem(item) => item,
_ => bug!(),
}
}
pub fn body(&self, id: BodyId) -> &'hir Body<'hir> {
self.tcx.hir_owner_nodes(id.hir_id.owner).unwrap().bodies.get(&id.hir_id.local_id).unwrap()
}
......@@ -470,6 +477,10 @@ pub fn visit_item_likes_in_module<V>(&self, module: LocalDefId, visitor: &mut V)
for id in &module.impl_items {
visitor.visit_impl_item(self.expect_impl_item(id.hir_id));
}
for id in &module.foreign_items {
visitor.visit_foreign_item(self.expect_foreign_item(id.hir_id));
}
}
/// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found.
......@@ -718,10 +729,11 @@ pub fn get_foreign_abi(&self, hir_id: HirId) -> Abi {
let parent = self.get_parent_item(hir_id);
if let Some(entry) = self.find_entry(parent) {
if let Entry {
node: Node::Item(Item { kind: ItemKind::ForeignMod(ref nm), .. }), ..
node: Node::Item(Item { kind: ItemKind::ForeignMod { abi, .. }, .. }),
..
} = entry
{
return nm.abi;
return *abi;
}
}
bug!("expected foreign mod or inlined parent, found {}", self.node_to_string(parent))
......@@ -937,6 +949,10 @@ fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir> {
fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir> {
self.impl_item(id)
}
fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir> {
self.foreign_item(id)
}
}
trait Named {
......@@ -1030,7 +1046,7 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId) -> String {
ItemKind::Const(..) => "const",
ItemKind::Fn(..) => "fn",
ItemKind::Mod(..) => "mod",
ItemKind::ForeignMod(..) => "foreign mod",
ItemKind::ForeignMod { .. } => "foreign mod",
ItemKind::GlobalAsm(..) => "global asm",
ItemKind::TyAlias(..) => "ty",
ItemKind::OpaqueTy(..) => "opaque type",
......
......@@ -993,7 +993,7 @@ fn visit_item(&mut self, item: &'v hir::Item<'v>) {
match item.kind {
hir::ItemKind::ExternCrate(..)
| hir::ItemKind::Use(..)
| hir::ItemKind::ForeignMod(..)
| hir::ItemKind::ForeignMod { .. }
| hir::ItemKind::TyAlias(..)
| hir::ItemKind::Trait(..)
| hir::ItemKind::TraitAlias(..)
......@@ -1066,6 +1066,8 @@ fn visit_impl_item(&mut self, ii: &'v hir::ImplItem<'v>) {
self.push_if_root(def_id);
}
}
fn visit_foreign_item(&mut self, _foreign_item: &'v hir::ForeignItem<'v>) {}
}
impl RootCollector<'_, 'v> {
......
......@@ -190,7 +190,7 @@ fn visit_node(&mut self, node: Node<'tcx>) {
intravisit::walk_item(self, &item);
}
hir::ItemKind::ForeignMod(..) => {}
hir::ItemKind::ForeignMod { .. } => {}
_ => {
intravisit::walk_item(self, &item);
}
......@@ -447,6 +447,8 @@ fn visit_trait_item(&mut self, _item: &hir::TraitItem<'_>) {
fn visit_impl_item(&mut self, _item: &hir::ImplItem<'_>) {
// ignore: we are handling this in `visit_item` above
}
fn visit_foreign_item(&mut self, _item: &'v hir::ForeignItem<'v>) {}
}
fn create_and_seed_worklist<'tcx>(
......
......@@ -37,6 +37,10 @@ fn visit_trait_item(&mut self, trait_item: &hir::TraitItem<'_>) {
fn visit_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) {
self.observe_item(&impl_item.attrs, impl_item.hir_id);
}
fn visit_foreign_item(&mut self, foreign_item: &hir::ForeignItem<'_>) {
self.observe_item(foreign_item.attrs, foreign_item.hir_id);
}
}
impl<'tcx> DiagnosticItemCollector<'tcx> {
......@@ -100,18 +104,6 @@ fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> FxHashMap<Symbol, DefId> {
// Collect diagnostic items in this crate.
tcx.hir().krate().visit_all_item_likes(&mut collector);
// FIXME(visit_all_item_likes): Foreign items are not visited
// here, so we have to manually look at them for now.
for (_, foreign_module) in tcx.foreign_modules(LOCAL_CRATE).iter() {
for &foreign_item in foreign_module.foreign_items.iter() {
match tcx.hir().get(tcx.hir().local_def_id_to_hir_id(foreign_item.expect_local())) {
hir::Node::ForeignItem(item) => {
collector.observe_item(item.attrs, item.hir_id);
}
item => bug!("unexpected foreign item {:?}", item),
}
}
}
for m in tcx.hir().krate().exported_macros {
collector.observe_item(m.attrs, m.hir_id);
......
......@@ -2,7 +2,7 @@
use rustc_errors::struct_span_err;
use rustc_hir::def_id::{CrateNum, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_hir::{HirId, ImplItem, Item, ItemKind, TraitItem};
use rustc_hir::{ForeignItem, HirId, ImplItem, Item, ItemKind, TraitItem};
use rustc_middle::hir::map::Map;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
......@@ -45,6 +45,10 @@ fn visit_trait_item(&mut self, _trait_item: &'tcx TraitItem<'tcx>) {
fn visit_impl_item(&mut self, _impl_item: &'tcx ImplItem<'tcx>) {
// Entry fn is never a trait item.
}
fn visit_foreign_item(&mut self, _: &'tcx ForeignItem<'tcx>) {
// Entry fn is never a foreign item.
}
}
fn entry_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<(LocalDefId, EntryFnType)> {
......
......@@ -68,6 +68,11 @@ fn visit_impl_item(&mut self, i: &'hir hir::ImplItem<'hir>) {
let mut inner_visitor = self.new_inner_visitor(self.hir_map);
inner_visitor.check(i.hir_id, |this| intravisit::walk_impl_item(this, i));
}
fn visit_foreign_item(&mut self, i: &'hir hir::ForeignItem<'hir>) {
let mut inner_visitor = self.new_inner_visitor(self.hir_map);
inner_visitor.check(i.hir_id, |this| intravisit::walk_foreign_item(this, i));
}
}
impl<'a, 'hir> HirIdValidator<'a, 'hir> {
......
......@@ -54,6 +54,8 @@ fn visit_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) {
impl_item.attrs,
)
}
fn visit_foreign_item(&mut self, _: &hir::ForeignItem<'_>) {}
}
impl LanguageItemCollector<'tcx> {
......
......@@ -40,6 +40,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
fn visit_foreign_item(&mut self, _: &'tcx hir::ForeignItem<'tcx>) {}
}
impl LayoutTest<'tcx> {
......
......@@ -262,7 +262,7 @@ fn propagate_node(&mut self, node: &Node<'tcx>, search_item: LocalDefId) {
| hir::ItemKind::TyAlias(..)
| hir::ItemKind::Static(..)
| hir::ItemKind::Mod(..)
| hir::ItemKind::ForeignMod(..)
| hir::ItemKind::ForeignMod { .. }
| hir::ItemKind::Impl { .. }
| hir::ItemKind::Trait(..)
| hir::ItemKind::TraitAlias(..)
......@@ -378,6 +378,10 @@ fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {
// processed in visit_item above
}
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {
// We never export foreign functions as they have no body to export.
}
}
fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> FxHashSet<LocalDefId> {
......
......@@ -326,7 +326,7 @@ fn visit_item(&mut self, i: &'tcx Item<'tcx>) {
// they don't have their own stability. They still can be annotated as unstable
// and propagate this unstability to children, but this annotation is completely
// optional. They inherit stability from their parents when unannotated.
hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod(..) => {
hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod { .. } => {
self.in_trait_impl = false;
kind = AnnotationKind::Container;
}
......@@ -499,7 +499,7 @@ fn visit_item(&mut self, i: &'tcx Item<'tcx>) {
// optional. They inherit stability from their parents when unannotated.
if !matches!(
i.kind,
hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod(..)
hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod { .. }
) {
self.check_missing_stability(i.hir_id, i.span);
}
......
......@@ -25,6 +25,8 @@ fn visit_item(&mut self, item: &hir::Item<'_>) {
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
}
/// Finds the function marked with `#[plugin_registrar]`, if any.
......
......@@ -592,7 +592,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
Option::<AccessLevel>::of_impl(item.hir_id, self.tcx, &self.access_levels)
}
// Foreign modules inherit level from parents.
hir::ItemKind::ForeignMod(..) => self.prev_level,
hir::ItemKind::ForeignMod { .. } => self.prev_level,
// Other `pub` items inherit levels from parents.
hir::ItemKind::Const(..)
| hir::ItemKind::Enum(..)
......@@ -654,10 +654,10 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
}
}
}
hir::ItemKind::ForeignMod(ref foreign_mod) => {
for foreign_item in foreign_mod.items {
hir::ItemKind::ForeignMod { items, .. } => {
for foreign_item in items {
if foreign_item.vis.node.is_pub() {
self.update(foreign_item.hir_id, item_level);
self.update(foreign_item.id.hir_id, item_level);
}
}
}
......@@ -770,11 +770,11 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
}
}
// Visit everything, but foreign items have their own levels.
hir::ItemKind::ForeignMod(ref foreign_mod) => {
for foreign_item in foreign_mod.items {
let foreign_item_level = self.get(foreign_item.hir_id);
hir::ItemKind::ForeignMod { items, .. } => {
for foreign_item in items {
let foreign_item_level = self.get(foreign_item.id.hir_id);
if foreign_item_level.is_some() {
self.reach(foreign_item.hir_id, foreign_item_level)
self.reach(foreign_item.id.hir_id, foreign_item_level)
.generics()
.predicates()
.ty();
......@@ -1430,7 +1430,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
// An `extern {}` doesn't introduce a new privacy
// namespace (the contents have their own privacies).
hir::ItemKind::ForeignMod(_) => {}
hir::ItemKind::ForeignMod { .. } => {}
hir::ItemKind::Trait(.., ref bounds, _) => {
if !self.trait_is_public(item.hir_id) {
......@@ -1948,10 +1948,10 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
}
}
// Subitems of foreign modules have their own publicity.
hir::ItemKind::ForeignMod(ref foreign_mod) => {
for foreign_item in foreign_mod.items {
let vis = tcx.visibility(tcx.hir().local_def_id(foreign_item.hir_id));
self.check(foreign_item.hir_id, vis).generics().predicates().ty();
hir::ItemKind::ForeignMod { items, .. } => {
for foreign_item in items {
let vis = tcx.visibility(tcx.hir().local_def_id(foreign_item.id.hir_id));
self.check(foreign_item.id.hir_id, vis).generics().predicates().ty();
}
}
// Subitems of structs and unions have their own publicity.
......
......@@ -388,7 +388,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
hir::ItemKind::ExternCrate(_)
| hir::ItemKind::Use(..)
| hir::ItemKind::Mod(..)
| hir::ItemKind::ForeignMod(..)
| hir::ItemKind::ForeignMod { .. }
| hir::ItemKind::GlobalAsm(..) => {
// These sorts of items have no lifetime parameters at all.
intravisit::walk_item(self, item);
......
......@@ -550,7 +550,7 @@ fn make(&self, offset: usize, _parent_id: Option<hir::HirId>, scx: &SaveContext<
// FIXME where clause
}
hir::ItemKind::ForeignMod(_) => Err("extern mod"),
hir::ItemKind::ForeignMod { .. } => Err("extern mod"),
hir::ItemKind::GlobalAsm(_) => Err("global asm"),
hir::ItemKind::ExternCrate(_) => Err("extern crate"),
hir::ItemKind::OpaqueTy(..) => Err("opaque type"),
......
......@@ -71,4 +71,8 @@ fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
self.process_attrs(impl_item.hir_id);
}
fn visit_foreign_item(&mut self, foreign_item: &'tcx hir::ForeignItem<'tcx>) {
self.process_attrs(foreign_item.hir_id);
}
}
......@@ -746,20 +746,22 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
let generics = tcx.generics_of(def_id);
check_type_params_are_used(tcx, &generics, pty_ty);
}
hir::ItemKind::ForeignMod(ref m) => {
check_abi(tcx, it.span, m.abi);
hir::ItemKind::ForeignMod { abi, items } => {
check_abi(tcx, it.span, abi);
if m.abi == Abi::RustIntrinsic {
for item in m.items {
if abi == Abi::RustIntrinsic {
for item in items {
let item = tcx.hir().foreign_item(item.id);
intrinsic::check_intrinsic_type(tcx, item);
}
} else if m.abi == Abi::PlatformIntrinsic {
for item in m.items {
} else if abi == Abi::PlatformIntrinsic {
for item in items {
let item = tcx.hir().foreign_item(item.id);
intrinsic::check_platform_intrinsic_type(tcx, item);
}
} else {
for item in m.items {
let def_id = tcx.hir().local_def_id(item.hir_id);
for item in items {
let def_id = tcx.hir().local_def_id(item.id.hir_id);
let generics = tcx.generics_of(def_id);
let own_counts = generics.own_counts();
if generics.params.len() - own_counts.lifetimes != 0 {
......@@ -791,9 +793,10 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
.emit();
}
let item = tcx.hir().foreign_item(item.id);
match item.kind {
hir::ForeignItemKind::Fn(ref fn_decl, _, _) => {
require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
require_c_abi_if_c_variadic(tcx, fn_decl, abi, item.span);
}
hir::ForeignItemKind::Static(..) => {
check_static_inhabited(tcx, def_id, item.span);
......
......@@ -1308,6 +1308,8 @@ fn visit_item(&mut self, i: &'v hir::Item<'v>) {
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
}
tcx.hir().krate().visit_all_item_likes(&mut Visitor { map: &tcx.hir(), traits: &mut traits });
......
......@@ -1134,6 +1134,7 @@ fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
}
fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
fn visit_foreign_item(&mut self, _: &'tcx hir::ForeignItem<'tcx>) {}
}
fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
......
......@@ -156,8 +156,9 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
hir::ItemKind::Const(ref ty, ..) => {
check_item_type(tcx, item.hir_id, ty.span, false);
}
hir::ItemKind::ForeignMod(ref module) => {
for it in module.items.iter() {
hir::ItemKind::ForeignMod { items, .. } => {
for it in items.iter() {
let it = tcx.hir().foreign_item(it.id);
match it.kind {
hir::ForeignItemKind::Fn(ref decl, ..) => {
check_item_fn(tcx, it.hir_id, it.ident, it.span, decl)
......@@ -1345,6 +1346,10 @@ fn visit_trait_item(&self, trait_item: &'tcx hir::TraitItem<'tcx>) {
fn visit_impl_item(&self, impl_item: &'tcx hir::ImplItem<'tcx>) {
Visitor::visit_impl_item(&mut self.clone(), impl_item);
}
fn visit_foreign_item(&self, foreign_item: &'tcx hir::ForeignItem<'tcx>) {
Visitor::visit_foreign_item(&mut self.clone(), foreign_item)
}
}
impl Visitor<'tcx> for CheckTypeWellFormedVisitor<'tcx> {
......
......@@ -35,6 +35,8 @@ fn visit_item(&mut self, item: &hir::Item<'_>) {
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
}
struct CheckVisitor<'tcx> {
......@@ -225,4 +227,6 @@ fn visit_item(&mut self, item: &hir::Item<'_>) {
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
}
......@@ -334,6 +334,8 @@ fn visit_item(&mut self, item: &hir::Item<'_>) {
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
}
impl InherentCollect<'tcx> {
......
......@@ -149,4 +149,6 @@ fn visit_item(&mut self, item: &'v hir::Item<'v>) {
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'v>) {}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'v>) {}
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'v>) {}
}
......@@ -244,4 +244,6 @@ fn visit_item(&mut self, item: &hir::Item<'_>) {
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
}
......@@ -94,4 +94,6 @@ fn visit_item(&mut self, item: &'v hir::Item<'v>) {
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
}
......@@ -646,8 +646,9 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::HirId) {
| hir::ItemKind::Use(..)
| hir::ItemKind::Mod(_)
| hir::ItemKind::GlobalAsm(_) => {}
hir::ItemKind::ForeignMod(ref foreign_mod) => {
for item in foreign_mod.items {
hir::ItemKind::ForeignMod { items, .. } => {
for item in items {
let item = tcx.hir().foreign_item(item.id);
let def_id = tcx.hir().local_def_id(item.hir_id);
tcx.ensure().generics_of(def_id);
tcx.ensure().type_of(def_id);
......
......@@ -259,7 +259,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
ItemKind::Trait(..)
| ItemKind::TraitAlias(..)
| ItemKind::Mod(..)
| ItemKind::ForeignMod(..)
| ItemKind::ForeignMod { .. }
| ItemKind::GlobalAsm(..)
| ItemKind::ExternCrate(..)
| ItemKind::Use(..) => {
......
......@@ -93,6 +93,8 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
fn visit_trait_item(&mut self, _trait_item: &'tcx hir::TraitItem<'tcx>) {}
fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem<'tcx>) {}
fn visit_foreign_item(&mut self, _foreign_item: &'tcx hir::ForeignItem<'tcx>) {}
}
fn enforce_impl_params_are_constrained(
......
......@@ -109,6 +109,8 @@ fn visit_item(&mut self, item: &hir::Item<'_>) {
fn visit_trait_item(&mut self, _trait_item: &'tcx hir::TraitItem<'tcx>) {}
fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem<'tcx>) {}
fn visit_foreign_item(&mut self, _foreign_item: &'tcx hir::ForeignItem<'tcx>) {}
}
fn insert_required_predicates_to_be_wf<'tcx>(
......
......@@ -26,4 +26,5 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
fn visit_foreign_item(&mut self, _: &'tcx hir::ForeignItem<'tcx>) {}
}
......@@ -92,14 +92,6 @@ fn visit_item(&mut self, item: &hir::Item<'_>) {
self.visit_node_helper(item.hir_id);
}
hir::ItemKind::ForeignMod(ref foreign_mod) => {
for foreign_item in foreign_mod.items {
if let hir::ForeignItemKind::Fn(..) = foreign_item.kind {
self.visit_node_helper(foreign_item.hir_id);
}
}
}
_ => {}
}
}
......@@ -115,6 +107,12 @@ fn visit_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) {
self.visit_node_helper(impl_item.hir_id);
}
}
fn visit_foreign_item(&mut self, foreign_item: &hir::ForeignItem<'_>) {
if let hir::ForeignItemKind::Fn(..) = foreign_item.kind {
self.visit_node_helper(foreign_item.hir_id);
}
}
}
impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
......
......@@ -153,14 +153,6 @@ fn visit_item(&mut self, item: &hir::Item<'_>) {
self.add_inferreds_for_item(item.hir_id);
}
hir::ItemKind::ForeignMod(ref foreign_mod) => {
for foreign_item in foreign_mod.items {
if let hir::ForeignItemKind::Fn(..) = foreign_item.kind {
self.add_inferreds_for_item(foreign_item.hir_id);
}
}
}
_ => {}
}
}
......@@ -176,4 +168,10 @@ fn visit_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) {
self.add_inferreds_for_item(impl_item.hir_id);
}
}
fn visit_foreign_item(&mut self, foreign_item: &hir::ForeignItem<'_>) {
if let hir::ForeignItemKind::Fn(..) = foreign_item.kind {
self.add_inferreds_for_item(foreign_item.hir_id);
}
}
}
......@@ -26,4 +26,5 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
fn visit_foreign_item(&mut self, _: &'tcx hir::ForeignItem<'tcx>) {}
}
......@@ -240,8 +240,9 @@ fn visit_item(
}
match item.kind {
hir::ItemKind::ForeignMod(ref fm) => {
for item in fm.items {
hir::ItemKind::ForeignMod { items, .. } => {
for item in items {
let item = self.cx.tcx.hir().foreign_item(item.id);
self.visit_foreign_item(item, None, om);
}
}
......
......@@ -13,114 +13,99 @@
#![feature(rustc_attrs)]
#![feature(unboxed_closures)]
#![feature(link_args)]
#![crate_type="rlib"]
#![crate_type = "rlib"]
// Change function name --------------------------------------------------------
#[cfg(cfail1)]
extern {
extern "C" {
pub fn change_function_name1(c: i64) -> i32;
}
#[cfg(not(cfail1))]
#[rustc_dirty(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
extern {
#[rustc_dirty(cfg = "cfail2", except = "hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
extern "C" {
pub fn change_function_name2(c: i64) -> i32;
}
// Change parameter name -------------------------------------------------------
#[cfg(cfail1)]
extern {
extern "C" {
pub fn change_parameter_name(c: i64) -> i32;
}
#[cfg(not(cfail1))]
#[rustc_dirty(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
extern {
#[rustc_dirty(cfg = "cfail2", except = "hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
extern "C" {
pub fn change_parameter_name(d: i64) -> i32;
}
// Change parameter type -------------------------------------------------------
#[cfg(cfail1)]
extern {
extern "C" {
pub fn change_parameter_type(c: i64) -> i32;
}
#[cfg(not(cfail1))]
#[rustc_dirty(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
extern {
#[rustc_dirty(cfg = "cfail2", except = "hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
extern "C" {
pub fn change_parameter_type(c: i32) -> i32;
}
// Change return type ----------------------------------------------------------
#[cfg(cfail1)]
extern {
extern "C" {
pub fn change_return_type(c: i32) -> i32;
}
#[cfg(not(cfail1))]
#[rustc_dirty(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
extern {
#[rustc_dirty(cfg = "cfail2", except = "hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
extern "C" {
pub fn change_return_type(c: i32) -> i8;
}
// Add parameter ---------------------------------------------------------------
#[cfg(cfail1)]
extern {
extern "C" {
pub fn add_parameter(c: i32) -> i32;
}
#[cfg(not(cfail1))]
#[rustc_dirty(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
extern {
#[rustc_dirty(cfg = "cfail2", except = "hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
extern "C" {
pub fn add_parameter(c: i32, d: i32) -> i32;
}
// Add return type -------------------------------------------------------------
#[cfg(cfail1)]
extern {
extern "C" {
pub fn add_return_type(c: i32);
}
#[cfg(not(cfail1))]
#[rustc_dirty(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
extern {
#[rustc_dirty(cfg = "cfail2", except = "hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
extern "C" {
pub fn add_return_type(c: i32) -> i32;
}
// Make function variadic ------------------------------------------------------
#[cfg(cfail1)]
extern {
extern "C" {
pub fn make_function_variadic(c: i32);
}
#[cfg(not(cfail1))]
#[rustc_dirty(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
extern {
#[rustc_dirty(cfg = "cfail2", except = "hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
extern "C" {
pub fn make_function_variadic(c: i32, ...);
}
// Change calling convention ---------------------------------------------------
#[cfg(cfail1)]
extern "C" {
......@@ -128,74 +113,66 @@
}
#[cfg(not(cfail1))]
#[rustc_dirty(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
#[rustc_dirty(cfg = "cfail2", except = "hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
extern "rust-call" {
pub fn change_calling_convention(c: i32);
}
// Make function public --------------------------------------------------------
#[cfg(cfail1)]
extern {
extern "C" {
fn make_function_public(c: i32);
}
#[cfg(not(cfail1))]
#[rustc_dirty(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
extern {
#[rustc_dirty(cfg = "cfail2", except = "hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
extern "C" {
pub fn make_function_public(c: i32);
}
// Add function ----------------------------------------------------------------
#[cfg(cfail1)]
extern {
extern "C" {
pub fn add_function1(c: i32);
}
#[cfg(not(cfail1))]
#[rustc_dirty(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
extern {
#[rustc_dirty(cfg = "cfail2", except = "hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
extern "C" {
pub fn add_function1(c: i32);
pub fn add_function2();
}
// Change link-args ------------------------------------------------------------
#[cfg(cfail1)]
#[link_args = "-foo -bar"]
extern {
extern "C" {
pub fn change_link_args(c: i32);
}
#[cfg(not(cfail1))]
#[rustc_dirty(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
#[rustc_dirty(cfg = "cfail2", except = "hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
#[link_args = "-foo -bar -baz"]
extern {
extern "C" {
pub fn change_link_args(c: i32);
}
// Change link-name ------------------------------------------------------------
#[cfg(cfail1)]
#[link(name = "foo")]
extern {
extern "C" {
pub fn change_link_name(c: i32);
}
#[cfg(not(cfail1))]
#[rustc_dirty(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
#[rustc_dirty(cfg = "cfail2", except = "hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
#[link(name = "bar")]
extern {
extern "C" {
pub fn change_link_name(c: i32);
}
......@@ -209,15 +186,13 @@ mod indirectly_change_parameter_type {
#[cfg(not(cfail1))]
use super::c_i64 as c_int;
#[rustc_dirty(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
extern {
#[rustc_dirty(cfg = "cfail2", except = "hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
extern "C" {
pub fn indirectly_change_parameter_type(c: c_int);
}
}
// Indirectly change return type --------------------------------------------
mod indirectly_change_return_type {
#[cfg(cfail1)]
......@@ -225,9 +200,9 @@ mod indirectly_change_return_type {
#[cfg(not(cfail1))]
use super::c_i64 as c_int;
#[rustc_dirty(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
extern {
#[rustc_dirty(cfg = "cfail2", except = "hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
extern "C" {
pub fn indirectly_change_return_type() -> c_int;
}
}
error: attribute should be applied to a function definition
--> $DIR/naked-invalid-attr.rs:9:5
|
LL | #[naked]
| ^^^^^^^^
LL | fn f();
| ------- not a function definition
error: attribute should be applied to a function definition
--> $DIR/naked-invalid-attr.rs:13:1
|
......@@ -32,6 +24,14 @@ LL | #[naked]
LL | extern "C" fn invoke(&self);
| ---------------------------- not a function definition
error: attribute should be applied to a function definition
--> $DIR/naked-invalid-attr.rs:9:5
|
LL | #[naked]
| ^^^^^^^^
LL | fn f();
| ------- not a function definition
error: attribute should be applied to a function definition
--> $DIR/naked-invalid-attr.rs:6:1
|
......
error[E0518]: attribute should be applied to function or closure
--> $DIR/inline-trait-and-foreign-items.rs:30:5
|
LL | #[inline]
| ^^^^^^^^^
LL | static X: u32;
| -------------- not a function or closure
error[E0518]: attribute should be applied to function or closure
--> $DIR/inline-trait-and-foreign-items.rs:33:5
|
LL | #[inline]
| ^^^^^^^^^
LL | type T;
| ------- not a function or closure
warning: `#[inline]` is ignored on constants
--> $DIR/inline-trait-and-foreign-items.rs:7:5
|
......@@ -61,6 +45,22 @@ LL | #[inline]
LL | type U = impl Trait;
| -------------------- not a function or closure
error[E0518]: attribute should be applied to function or closure
--> $DIR/inline-trait-and-foreign-items.rs:30:5
|
LL | #[inline]
| ^^^^^^^^^
LL | static X: u32;
| -------------- not a function or closure
error[E0518]: attribute should be applied to function or closure
--> $DIR/inline-trait-and-foreign-items.rs:33:5
|
LL | #[inline]
| ^^^^^^^^^
LL | type T;
| ------- not a function or closure
error: could not find defining uses
--> $DIR/inline-trait-and-foreign-items.rs:26:14
|
......
error: `#[inline]` is ignored on function prototypes
--> $DIR/warn-unused-inline-on-fn-prototypes.rs:9:5
--> $DIR/warn-unused-inline-on-fn-prototypes.rs:4:5
|
LL | #[inline]
| ^^^^^^^^^
......@@ -11,7 +11,7 @@ LL | #![deny(unused_attributes)]
| ^^^^^^^^^^^^^^^^^
error: `#[inline]` is ignored on function prototypes
--> $DIR/warn-unused-inline-on-fn-prototypes.rs:4:5
--> $DIR/warn-unused-inline-on-fn-prototypes.rs:9:5
|
LL | #[inline]
| ^^^^^^^^^
......
......@@ -147,7 +147,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
hir::ItemKind::Union(..) => "a union",
hir::ItemKind::OpaqueTy(..) => "an existential type",
hir::ItemKind::ExternCrate(..)
| hir::ItemKind::ForeignMod(..)
| hir::ItemKind::ForeignMod { .. }
| hir::ItemKind::GlobalAsm(..)
| hir::ItemKind::Impl { .. }
| hir::ItemKind::Use(..) => return,
......
......@@ -125,7 +125,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
| hir::ItemKind::Union(..)
| hir::ItemKind::OpaqueTy(..)
| hir::ItemKind::ExternCrate(..)
| hir::ItemKind::ForeignMod(..)
| hir::ItemKind::ForeignMod { .. }
| hir::ItemKind::Impl { .. }
| hir::ItemKind::Use(..) => {},
};
......
......@@ -395,7 +395,7 @@ fn print_item(cx: &LateContext<'_>, item: &hir::Item<'_>) {
println!("function of type {:#?}", item_ty);
},
hir::ItemKind::Mod(..) => println!("module"),
hir::ItemKind::ForeignMod(ref fm) => println!("foreign module with abi: {}", fm.abi),
hir::ItemKind::ForeignMod { abi, .. } => println!("foreign module with abi: {}", abi),
hir::ItemKind::GlobalAsm(ref asm) => println!("global asm: {:?}", asm),
hir::ItemKind::TyAlias(..) => {
println!("type alias for {:?}", cx.tcx.type_of(did));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册