1
Fork 0

Collect attributes during HIR lowering.

This commit is contained in:
Camille GILLOT 2020-11-24 18:12:42 +01:00
parent d50ca3cbee
commit 1fb257b3b4
9 changed files with 126 additions and 87 deletions

View file

@ -260,6 +260,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// Merge attributes into the inner expression.
let mut attrs: Vec<_> = e.attrs.iter().map(|a| self.lower_attr(a)).collect();
attrs.extend::<Vec<_>>(ex.attrs.into());
self.attrs[ex.hir_id] = &*self.arena.alloc_from_iter(attrs.iter().cloned());
ex.attrs = attrs.into();
return ex;
}
@ -272,12 +273,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span),
};
hir::Expr {
hir_id: self.lower_node_id(e.id),
kind,
span: e.span,
attrs: e.attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>().into(),
}
let hir_id = self.lower_node_id(e.id);
let attrs = e.attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>();
self.attrs.push_sparse(hir_id, &*self.arena.alloc_from_iter(attrs.iter().cloned()));
hir::Expr { hir_id, kind, span: e.span, attrs: attrs.into() }
})
}
@ -618,9 +617,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::Guard::If(self.lower_expr(cond))
}
});
let hir_id = self.next_id();
hir::Arm {
hir_id: self.next_id(),
attrs: self.lower_attrs(&arm.attrs),
hir_id,
attrs: self.lower_attrs(hir_id, &arm.attrs),
pat,
guard,
body: self.lower_expr(&arm.body),
@ -2159,7 +2159,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
kind: hir::ExprKind<'hir>,
attrs: AttrVec,
) -> hir::Expr<'hir> {
hir::Expr { hir_id: self.next_id(), kind, span, attrs }
let hir_id = self.next_id();
self.attrs.push_sparse(hir_id, &*self.arena.alloc_from_iter(attrs.iter().cloned()));
hir::Expr { hir_id, kind, span, attrs }
}
fn field(&mut self, ident: Ident, expr: &'hir hir::Expr<'hir>, span: Span) -> hir::Field<'hir> {

View file

@ -217,42 +217,40 @@ impl<'hir> LoweringContext<'_, 'hir> {
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 def_id = self.lower_node_id(i.id).expect_owner();
let hir_id = self.lower_node_id(i.id);
let attrs = self.lower_attrs(hir_id, &i.attrs);
let body = P(self.lower_mac_args(body));
self.exported_macros.push(hir::MacroDef {
ident,
vis,
attrs,
def_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 {
def_id: self.lower_node_id(i.id).expect_owner(),
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, attrs, 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],
vis: &mut hir::Visibility<'hir>,
@ -365,14 +363,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
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()),
@ -554,6 +552,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
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);
this.attrs.push_sparse(new_id, attrs);
this.insert_item(hir::Item {
def_id: new_id.expect_owner(),
@ -626,6 +625,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let kind =
this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs);
this.attrs.push_sparse(new_hir_id, attrs);
this.insert_item(hir::Item {
def_id: new_hir_id.expect_owner(),
@ -699,11 +699,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
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();
hir::ForeignItem {
def_id,
ident: i.ident,
attrs: self.lower_attrs(&i.attrs),
attrs: self.lower_attrs(hir_id, &i.attrs),
kind: match i.kind {
ForeignItemKind::Fn(box FnKind(_, ref sig, ref generics, _)) => {
let fdec = &sig.decl;
@ -748,29 +749,43 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
let id = self.lower_node_id(v.id);
hir::Variant {
attrs: self.lower_attrs(&v.attrs),
data: self.lower_variant_data(&v.data),
id,
attrs: self.lower_attrs(id, &v.attrs),
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))),
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.attrs.push_sparse(ctor_id, self.attrs[parent_id]);
hir::VariantData::Tuple(
self.arena.alloc_from_iter(
fields.iter().enumerate().map(|f| self.lower_struct_field(f)),
),
ctor_id,
)
}
VariantData::Unit(id) => {
let ctor_id = self.lower_node_id(id);
self.attrs.push_sparse(ctor_id, self.attrs[parent_id]);
hir::VariantData::Unit(ctor_id)
}
}
}
@ -787,9 +802,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
} else {
self.lower_ty(&f.ty, ImplTraitContext::disallowed())
};
let hir_id = self.lower_node_id(f.id);
hir::StructField {
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.
@ -797,12 +813,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
},
vis: self.lower_visibility(&f.vis, None),
ty,
attrs: self.lower_attrs(&f.attrs),
attrs: self.lower_attrs(hir_id, &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) => {
@ -838,7 +855,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::TraitItem {
def_id: trait_item_def_id,
ident: i.ident,
attrs: self.lower_attrs(&i.attrs),
attrs: self.lower_attrs(hir_id, &i.attrs),
generics,
kind,
span: i.span,
@ -920,10 +937,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
// 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);
hir::ImplItem {
def_id: self.lower_node_id(i.id).expect_owner(),
def_id: hir_id.expect_owner(),
ident: i.ident,
attrs: self.lower_attrs(&i.attrs),
attrs: self.lower_attrs(hir_id, &i.attrs),
generics,
vis: self.lower_visibility(&i.vis, None),
defaultness,
@ -1024,9 +1042,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
let hir_id = self.lower_node_id(param.id);
hir::Param {
attrs: self.lower_attrs(&param.attrs),
hir_id: self.lower_node_id(param.id),
hir_id,
attrs: self.lower_attrs(hir_id, &param.attrs),
pat: self.lower_pat(&param.pat),
ty_span: param.ty.span,
span: param.span,

View file

@ -114,6 +114,8 @@ struct LoweringContext<'a, 'hir: 'a> {
generator_kind: Option<hir::GeneratorKind>,
attrs: hir::HirIdVec<&'hir [Attribute]>,
/// When inside an `async` context, this is the `HirId` of the
/// `task_context` local bound to the resume argument of the generator.
task_context: Option<hir::HirId>,
@ -309,6 +311,7 @@ pub fn lower_crate<'a, 'hir>(
bodies: BTreeMap::new(),
trait_impls: BTreeMap::new(),
modules: BTreeMap::new(),
attrs: hir::HirIdVec::default(),
exported_macros: Vec::new(),
non_exported_macro_attrs: Vec::new(),
catch_scopes: Vec::new(),
@ -565,7 +568,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c);
let module = self.lower_mod(&c.items, c.span);
let attrs = self.lower_attrs(&c.attrs);
let attrs = self.lower_attrs(hir::CRATE_HIR_ID, &c.attrs);
let body_ids = body_ids(&self.bodies);
let proc_macros =
c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id].unwrap()).collect();
@ -592,6 +595,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.resolver.definitions().init_def_id_to_hir_id_mapping(def_id_to_hir_id);
// Not all HIR owners have declared attrs. Complete with empty IndexVecs.
self.attrs.push_owner(Idx::new(self.resolver.definitions().def_index_count() - 1));
hir::Crate {
item: hir::CrateItem { module, attrs, span: c.span },
exported_macros: self.arena.alloc_from_iter(self.exported_macros),
@ -606,6 +612,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
modules: self.modules,
proc_macros,
trait_map,
attrs: self.attrs,
}
}
@ -967,8 +974,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ret
}
fn lower_attrs(&mut self, attrs: &[Attribute]) -> &'hir [Attribute] {
self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)))
fn lower_attrs(&mut self, id: hir::HirId, attrs: &[Attribute]) -> &'hir [Attribute] {
let ret = self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)));
self.attrs.push_sparse(id, ret);
ret
}
fn lower_attr(&mut self, attr: &Attribute) -> Attribute {
@ -1790,14 +1799,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
)
});
let init = l.init.as_ref().map(|e| self.lower_expr(e));
let hir_id = self.lower_node_id(l.id);
let attrs = l.attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>();
self.attrs.push_sparse(hir_id, &*self.arena.alloc_from_iter(attrs.iter().cloned()));
(
hir::Local {
hir_id: self.lower_node_id(l.id),
hir_id,
ty,
pat: self.lower_pat(&l.pat),
init,
span: l.span,
attrs: l.attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>().into(),
attrs: attrs.into(),
source: hir::LocalSource::Normal,
},
ids,
@ -2300,12 +2312,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
};
let hir_id = self.lower_node_id(param.id);
hir::GenericParam {
hir_id: self.lower_node_id(param.id),
hir_id,
name,
span: param.ident.span,
pure_wrt_drop: self.sess.contains_name(&param.attrs, sym::may_dangle),
attrs: self.lower_attrs(&param.attrs),
attrs: self.lower_attrs(hir_id, &param.attrs),
bounds: self.arena.alloc_from_iter(bounds),
kind,
}
@ -2519,7 +2532,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
pat: &'hir hir::Pat<'hir>,
source: hir::LocalSource,
) -> hir::Stmt<'hir> {
let local = hir::Local { attrs, hir_id: self.next_id(), init, pat, source, span, ty: None };
let hir_id = self.next_id();
self.attrs.push_sparse(hir_id, &*self.arena.alloc_from_iter(attrs.iter().cloned()));
let local = hir::Local { attrs, hir_id, init, pat, source, span, ty: None };
self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))
}