use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span;
use rustc_target::spec::abi;
-
use smallvec::{smallvec, SmallVec};
-use std::collections::BTreeSet;
use tracing::debug;
+use std::mem;
+
pub(super) struct ItemLowerer<'a, 'lowering, 'hir> {
pub(super) lctx: &'a mut LoweringContext<'lowering, 'hir>,
}
}
impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
- fn visit_mod(&mut self, m: &'a Mod, _s: Span, _attrs: &[Attribute], n: NodeId) {
- let hir_id = self.lctx.lower_node_id(n);
-
- self.lctx.modules.insert(
- hir_id,
- hir::ModuleItems {
- items: BTreeSet::new(),
- trait_items: BTreeSet::new(),
- impl_items: BTreeSet::new(),
- foreign_items: BTreeSet::new(),
- },
- );
-
- let old = self.lctx.current_module;
- self.lctx.current_module = hir_id;
- visit::walk_mod(self, m);
- self.lctx.current_module = old;
- }
-
fn visit_item(&mut self, item: &'a Item) {
let mut item_hir_id = None;
self.lctx.with_hir_id_owner(item.id, |lctx| {
lctx.without_in_scope_lifetime_defs(|lctx| {
if let Some(hir_item) = lctx.lower_item(item) {
- item_hir_id = Some(hir_item.hir_id);
- lctx.insert_item(hir_item);
+ let id = lctx.insert_item(hir_item);
+ item_hir_id = Some(id);
}
})
});
if let Some(hir_id) = item_hir_id {
self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
let this = &mut ItemLowerer { lctx: this };
- if let ItemKind::Impl(box ImplKind { ref of_trait, .. }) = item.kind {
- this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item));
- } else {
- visit::walk_item(this, item);
+ match item.kind {
+ ItemKind::Mod(..) => {
+ let def_id = this.lctx.lower_node_id(item.id).expect_owner();
+ let old_current_module =
+ mem::replace(&mut this.lctx.current_module, def_id);
+ visit::walk_item(this, item);
+ this.lctx.current_module = old_current_module;
+ }
+ ItemKind::Impl(box ImplKind { ref of_trait, .. }) => {
+ this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item));
+ }
+ _ => visit::walk_item(this, item),
}
});
}
self.lctx.with_hir_id_owner(item.id, |lctx| match ctxt {
AssocCtxt::Trait => {
let hir_item = lctx.lower_trait_item(item);
- let id = hir::TraitItemId { hir_id: hir_item.hir_id };
+ let id = hir_item.trait_item_id();
lctx.trait_items.insert(id, hir_item);
- lctx.modules.get_mut(&lctx.current_module).unwrap().trait_items.insert(id);
+ lctx.modules.entry(lctx.current_module).or_default().trait_items.insert(id);
}
AssocCtxt::Impl => {
let hir_item = lctx.lower_impl_item(item);
- let id = hir::ImplItemId { hir_id: hir_item.hir_id };
+ let id = hir_item.impl_item_id();
lctx.impl_items.insert(id, hir_item);
- lctx.modules.get_mut(&lctx.current_module).unwrap().impl_items.insert(id);
+ lctx.modules.entry(lctx.current_module).or_default().impl_items.insert(id);
}
});
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 };
+ let id = hir_item.foreign_item_id();
lctx.foreign_items.insert(id, hir_item);
- lctx.modules.get_mut(&lctx.current_module).unwrap().foreign_items.insert(id);
+ lctx.modules.entry(lctx.current_module).or_default().foreign_items.insert(id);
});
visit::walk_foreign_item(self, item);
// only used when lowering a child item of a trait or impl.
fn with_parent_item_lifetime_defs<T>(
&mut self,
- parent_hir_id: hir::HirId,
+ parent_hir_id: hir::ItemId,
f: impl FnOnce(&mut LoweringContext<'_, '_>) -> T,
) -> T {
let old_len = self.in_scope_lifetimes.len();
let parent_generics = match self.items.get(&parent_hir_id).unwrap().kind {
hir::ItemKind::Impl(hir::Impl { ref generics, .. })
- | hir::ItemKind::Trait(_, _, ref generics, ..) => &generics.params[..],
+ | hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params,
_ => &[],
};
let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind {
&mut self,
f: impl FnOnce(&mut LoweringContext<'_, '_>) -> T,
) -> T {
- let old_in_scope_lifetimes = std::mem::replace(&mut self.in_scope_lifetimes, vec![]);
+ let old_in_scope_lifetimes = mem::replace(&mut self.in_scope_lifetimes, vec![]);
// this vector is only used when walking over impl headers,
// input types, and the like, and should not be non-empty in
res
}
- pub(super) fn lower_mod(&mut self, m: &Mod) -> hir::Mod<'hir> {
+ pub(super) fn lower_mod(&mut self, items: &[P<Item>], inner: Span) -> hir::Mod<'hir> {
hir::Mod {
- inner: m.inner,
- item_ids: self
- .arena
- .alloc_from_iter(m.items.iter().flat_map(|x| self.lower_item_id(x))),
+ inner,
+ item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_id(x))),
}
}
node_ids
.into_iter()
- .map(|node_id| hir::ItemId { id: self.allocate_hir_id_counter(node_id) })
+ .map(|node_id| hir::ItemId {
+ def_id: self.allocate_hir_id_counter(node_id).expect_owner(),
+ })
.collect()
}
pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item<'hir>> {
let mut ident = i.ident;
let mut vis = self.lower_visibility(&i.vis, None);
- let attrs = self.lower_attrs(&i.attrs);
if let ItemKind::MacroDef(MacroDef { ref body, macro_rules }) = i.kind {
if !macro_rules || self.sess.contains_name(&i.attrs, sym::macro_export) {
let hir_id = self.lower_node_id(i.id);
+ self.lower_attrs(hir_id, &i.attrs);
let body = P(self.lower_mac_args(body));
self.exported_macros.push(hir::MacroDef {
ident,
vis,
- attrs,
- hir_id,
+ def_id: hir_id.expect_owner(),
span: i.span,
ast: MacroDef { body, macro_rules },
});
} else {
- self.non_exported_macro_attrs.extend(attrs.iter().cloned());
+ for a in i.attrs.iter() {
+ let a = self.lower_attr(a);
+ self.non_exported_macro_attrs.push(a);
+ }
}
return None;
}
- let kind = self.lower_item_kind(i.span, i.id, &mut ident, attrs, &mut vis, &i.kind);
-
- Some(hir::Item { hir_id: self.lower_node_id(i.id), ident, attrs, kind, vis, span: i.span })
+ let hir_id = self.lower_node_id(i.id);
+ let attrs = self.lower_attrs(hir_id, &i.attrs);
+ let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, &mut vis, &i.kind);
+ Some(hir::Item { def_id: hir_id.expect_owner(), ident, kind, vis, span: i.span })
}
fn lower_item_kind(
&mut self,
span: Span,
id: NodeId,
+ hir_id: hir::HirId,
ident: &mut Ident,
- attrs: &'hir [Attribute],
+ attrs: Option<&'hir [Attribute]>,
vis: &mut hir::Visibility<'hir>,
i: &ItemKind,
) -> hir::ItemKind<'hir> {
hir::ItemKind::Fn(sig, generics, body_id)
})
}
- ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
+ ItemKind::Mod(_, ref mod_kind) => match mod_kind {
+ ModKind::Loaded(items, _, inner_span) => {
+ hir::ItemKind::Mod(self.lower_mod(items, *inner_span))
+ }
+ ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
+ },
ItemKind::ForeignMod(ref fm) => {
if fm.abi.is_none() {
- self.maybe_lint_missing_abi(span, id, abi::Abi::C);
+ self.maybe_lint_missing_abi(span, id, abi::Abi::C { unwind: false });
}
hir::ItemKind::ForeignMod {
- abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
+ abi: fm.abi.map_or(abi::Abi::C { unwind: false }, |abi| self.lower_abi(abi)),
items: self
.arena
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
ty,
ImplTraitContext::OtherOpaqueTy {
capturable_lifetimes: &mut FxHashSet::default(),
- origin: hir::OpaqueTyOrigin::Misc,
+ origin: hir::OpaqueTyOrigin::TyAlias,
},
);
let generics = self.lower_generics(gen, ImplTraitContext::disallowed());
self.lower_generics(generics, ImplTraitContext::disallowed()),
),
ItemKind::Struct(ref struct_def, ref generics) => {
- let struct_def = self.lower_variant_data(struct_def);
+ let struct_def = self.lower_variant_data(hir_id, struct_def);
hir::ItemKind::Struct(
struct_def,
self.lower_generics(generics, ImplTraitContext::disallowed()),
)
}
ItemKind::Union(ref vdata, ref generics) => {
- let vdata = self.lower_variant_data(vdata);
+ let vdata = self.lower_variant_data(hir_id, vdata);
hir::ItemKind::Union(
vdata,
self.lower_generics(generics, ImplTraitContext::disallowed()),
self_ty: ref ty,
items: ref impl_items,
}) => {
- let def_id = self.resolver.local_def_id(id);
-
// Lower the "impl header" first. This ordering is important
// for in-band lifetimes! Consider `'a` here:
//
// method, it will not be considered an in-band
// lifetime to be added, but rather a reference to a
// parent lifetime.
- let lowered_trait_impl_id = self.lower_node_id(id);
+ let lowered_trait_def_id = self.lower_node_id(id).expect_owner();
let (generics, (trait_ref, lowered_ty)) = self.add_in_band_defs(
ast_generics,
- def_id,
+ lowered_trait_def_id,
AnonymousLifetimeMode::CreateParameter,
|this, _| {
let trait_ref = trait_ref.as_ref().map(|trait_ref| {
this.trait_impls
.entry(def_id)
.or_default()
- .push(lowered_trait_impl_id);
+ .push(lowered_trait_def_id);
}
}
id: NodeId,
vis: &mut hir::Visibility<'hir>,
ident: &mut Ident,
- attrs: &'hir [Attribute],
+ attrs: Option<&'hir [Attribute]>,
) -> hir::ItemKind<'hir> {
debug!("lower_use_tree(tree={:?})", tree);
debug!("lower_use_tree: vis = {:?}", vis);
let path = this.lower_path_extra(res, &path, ParamMode::Explicit, None);
let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
let vis = this.rebuild_vis(&vis);
+ if let Some(attrs) = attrs {
+ this.attrs.insert(new_id, attrs);
+ }
this.insert_item(hir::Item {
- hir_id: new_id,
+ def_id: new_id.expect_owner(),
ident,
- attrs,
kind,
vis,
span,
let kind =
this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs);
+ if let Some(attrs) = attrs {
+ this.attrs.insert(new_hir_id, attrs);
+ }
this.insert_item(hir::Item {
- hir_id: new_hir_id,
+ def_id: new_hir_id.expect_owner(),
ident,
- attrs,
kind,
vis,
span: use_tree.span,
}
fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem<'hir> {
- let def_id = self.resolver.local_def_id(i.id);
+ let hir_id = self.lower_node_id(i.id);
+ let def_id = hir_id.expect_owner();
+ self.lower_attrs(hir_id, &i.attrs);
hir::ForeignItem {
- hir_id: self.lower_node_id(i.id),
+ def_id,
ident: i.ident,
- attrs: self.lower_attrs(&i.attrs),
kind: match i.kind {
ForeignItemKind::Fn(box FnKind(_, ref sig, ref generics, _)) => {
let fdec = &sig.decl;
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) },
+ id: hir::ForeignItemId { def_id: self.lower_node_id(i.id).expect_owner() },
ident: i.ident,
span: i.span,
vis: self.lower_visibility(&i.vis, Some(i.id)),
}
fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
+ let id = self.lower_node_id(v.id);
+ self.lower_attrs(id, &v.attrs);
hir::Variant {
- attrs: self.lower_attrs(&v.attrs),
- data: self.lower_variant_data(&v.data),
+ id,
+ data: self.lower_variant_data(id, &v.data),
disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
- id: self.lower_node_id(v.id),
ident: v.ident,
span: v.span,
}
}
- fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData<'hir> {
+ fn lower_variant_data(
+ &mut self,
+ parent_id: hir::HirId,
+ vdata: &VariantData,
+ ) -> hir::VariantData<'hir> {
match *vdata {
VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct(
self.arena
- .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_struct_field(f))),
+ .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f))),
recovered,
),
- VariantData::Tuple(ref fields, id) => hir::VariantData::Tuple(
- self.arena
- .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_struct_field(f))),
- self.lower_node_id(id),
- ),
- VariantData::Unit(id) => hir::VariantData::Unit(self.lower_node_id(id)),
+ VariantData::Tuple(ref fields, id) => {
+ let ctor_id = self.lower_node_id(id);
+ self.alias_attrs(ctor_id, parent_id);
+ hir::VariantData::Tuple(
+ self.arena.alloc_from_iter(
+ fields.iter().enumerate().map(|f| self.lower_field_def(f)),
+ ),
+ ctor_id,
+ )
+ }
+ VariantData::Unit(id) => {
+ let ctor_id = self.lower_node_id(id);
+ self.alias_attrs(ctor_id, parent_id);
+ hir::VariantData::Unit(ctor_id)
+ }
}
}
- fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::StructField<'hir> {
+ fn lower_field_def(&mut self, (index, f): (usize, &FieldDef)) -> hir::FieldDef<'hir> {
let ty = if let TyKind::Path(ref qself, ref path) = f.ty.kind {
let t = self.lower_path_ty(
&f.ty,
} else {
self.lower_ty(&f.ty, ImplTraitContext::disallowed())
};
- hir::StructField {
+ let hir_id = self.lower_node_id(f.id);
+ self.lower_attrs(hir_id, &f.attrs);
+ hir::FieldDef {
span: f.span,
- hir_id: self.lower_node_id(f.id),
+ hir_id,
ident: match f.ident {
Some(ident) => ident,
// FIXME(jseyfried): positional field hygiene.
},
vis: self.lower_visibility(&f.vis, None),
ty,
- attrs: self.lower_attrs(&f.attrs),
}
}
fn lower_trait_item(&mut self, i: &AssocItem) -> hir::TraitItem<'hir> {
- let trait_item_def_id = self.resolver.local_def_id(i.id);
+ let hir_id = self.lower_node_id(i.id);
+ let trait_item_def_id = hir_id.expect_owner();
let (generics, kind) = match i.kind {
AssocItemKind::Const(_, ref ty, ref default) => {
AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"),
};
- hir::TraitItem {
- hir_id: self.lower_node_id(i.id),
- ident: i.ident,
- attrs: self.lower_attrs(&i.attrs),
- generics,
- kind,
- span: i.span,
- }
+ self.lower_attrs(hir_id, &i.attrs);
+ hir::TraitItem { def_id: trait_item_def_id, ident: i.ident, generics, kind, span: i.span }
}
fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
}
AssocItemKind::MacCall(..) => unimplemented!(),
};
- let id = hir::TraitItemId { hir_id: self.lower_node_id(i.id) };
+ let id = hir::TraitItemId { def_id: self.lower_node_id(i.id).expect_owner() };
let defaultness = hir::Defaultness::Default { has_value: has_default };
hir::TraitItemRef { id, ident: i.ident, span: i.span, defaultness, kind }
}
ty,
ImplTraitContext::OtherOpaqueTy {
capturable_lifetimes: &mut FxHashSet::default(),
- origin: hir::OpaqueTyOrigin::Misc,
+ origin: hir::OpaqueTyOrigin::TyAlias,
},
);
hir::ImplItemKind::TyAlias(ty)
// Since `default impl` is not yet implemented, this is always true in impls.
let has_value = true;
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
+ let hir_id = self.lower_node_id(i.id);
+ self.lower_attrs(hir_id, &i.attrs);
hir::ImplItem {
- hir_id: self.lower_node_id(i.id),
+ def_id: hir_id.expect_owner(),
ident: i.ident,
- attrs: self.lower_attrs(&i.attrs),
generics,
vis: self.lower_visibility(&i.vis, None),
defaultness,
let has_value = true;
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
hir::ImplItemRef {
- id: hir::ImplItemId { hir_id: self.lower_node_id(i.id) },
+ id: hir::ImplItemId { def_id: self.lower_node_id(i.id).expect_owner() },
ident: i.ident,
span: i.span,
vis: self.lower_visibility(&i.vis, Some(i.id)),
}
fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
+ let hir_id = self.lower_node_id(param.id);
+ self.lower_attrs(hir_id, ¶m.attrs);
hir::Param {
- attrs: self.lower_attrs(¶m.attrs),
- hir_id: self.lower_node_id(param.id),
+ hir_id,
pat: self.lower_pat(¶m.pat),
ty_span: param.ty.span,
span: param.span,
//
// If this is the simple case, this parameter will end up being the same as the
// original parameter, but with a different pattern id.
- let mut stmt_attrs = AttrVec::new();
- stmt_attrs.extend(parameter.attrs.iter().cloned());
+ let stmt_attrs = this.attrs.get(¶meter.hir_id).copied();
let (new_parameter_pat, new_parameter_id) = this.pat_ident(desugared_span, ident);
let new_parameter = hir::Param {
- attrs: parameter.attrs,
hir_id: parameter.hir_id,
pat: new_parameter_pat,
ty_span: parameter.ty_span,
);
let move_expr = this.expr_ident(desugared_span, ident, new_parameter_id);
let move_stmt = this.stmt_let_pat(
- AttrVec::new(),
+ None,
desugared_span,
Some(move_expr),
move_pat,
match ext {
Extern::None => abi::Abi::Rust,
Extern::Implicit => {
- self.maybe_lint_missing_abi(span, id, abi::Abi::C);
- abi::Abi::C
+ self.maybe_lint_missing_abi(span, id, abi::Abi::C { unwind: false });
+ abi::Abi::C { unwind: false }
}
Extern::Explicit(abi) => self.lower_abi(abi),
}