Collect attributes during HIR lowering.
This commit is contained in:
parent
d50ca3cbee
commit
1fb257b3b4
9 changed files with 126 additions and 87 deletions
|
@ -260,6 +260,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
// Merge attributes into the inner expression.
|
// Merge attributes into the inner expression.
|
||||||
let mut attrs: Vec<_> = e.attrs.iter().map(|a| self.lower_attr(a)).collect();
|
let mut attrs: Vec<_> = e.attrs.iter().map(|a| self.lower_attr(a)).collect();
|
||||||
attrs.extend::<Vec<_>>(ex.attrs.into());
|
attrs.extend::<Vec<_>>(ex.attrs.into());
|
||||||
|
self.attrs[ex.hir_id] = &*self.arena.alloc_from_iter(attrs.iter().cloned());
|
||||||
ex.attrs = attrs.into();
|
ex.attrs = attrs.into();
|
||||||
return ex;
|
return ex;
|
||||||
}
|
}
|
||||||
|
@ -272,12 +273,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span),
|
ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span),
|
||||||
};
|
};
|
||||||
|
|
||||||
hir::Expr {
|
let hir_id = self.lower_node_id(e.id);
|
||||||
hir_id: self.lower_node_id(e.id),
|
let attrs = e.attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>();
|
||||||
kind,
|
self.attrs.push_sparse(hir_id, &*self.arena.alloc_from_iter(attrs.iter().cloned()));
|
||||||
span: e.span,
|
hir::Expr { hir_id, kind, span: e.span, attrs: attrs.into() }
|
||||||
attrs: e.attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>().into(),
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,9 +617,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
hir::Guard::If(self.lower_expr(cond))
|
hir::Guard::If(self.lower_expr(cond))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
let hir_id = self.next_id();
|
||||||
hir::Arm {
|
hir::Arm {
|
||||||
hir_id: self.next_id(),
|
hir_id,
|
||||||
attrs: self.lower_attrs(&arm.attrs),
|
attrs: self.lower_attrs(hir_id, &arm.attrs),
|
||||||
pat,
|
pat,
|
||||||
guard,
|
guard,
|
||||||
body: self.lower_expr(&arm.body),
|
body: self.lower_expr(&arm.body),
|
||||||
|
@ -2159,7 +2159,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
kind: hir::ExprKind<'hir>,
|
kind: hir::ExprKind<'hir>,
|
||||||
attrs: AttrVec,
|
attrs: AttrVec,
|
||||||
) -> hir::Expr<'hir> {
|
) -> 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> {
|
fn field(&mut self, ident: Ident, expr: &'hir hir::Expr<'hir>, span: Span) -> hir::Field<'hir> {
|
||||||
|
|
|
@ -217,42 +217,40 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item<'hir>> {
|
pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item<'hir>> {
|
||||||
let mut ident = i.ident;
|
let mut ident = i.ident;
|
||||||
let mut vis = self.lower_visibility(&i.vis, None);
|
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 let ItemKind::MacroDef(MacroDef { ref body, macro_rules }) = i.kind {
|
||||||
if !macro_rules || self.sess.contains_name(&i.attrs, sym::macro_export) {
|
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));
|
let body = P(self.lower_mac_args(body));
|
||||||
self.exported_macros.push(hir::MacroDef {
|
self.exported_macros.push(hir::MacroDef {
|
||||||
ident,
|
ident,
|
||||||
vis,
|
vis,
|
||||||
attrs,
|
attrs,
|
||||||
def_id,
|
def_id: hir_id.expect_owner(),
|
||||||
span: i.span,
|
span: i.span,
|
||||||
ast: MacroDef { body, macro_rules },
|
ast: MacroDef { body, macro_rules },
|
||||||
});
|
});
|
||||||
} else {
|
} 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;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let kind = self.lower_item_kind(i.span, i.id, &mut ident, attrs, &mut vis, &i.kind);
|
let hir_id = self.lower_node_id(i.id);
|
||||||
|
let attrs = self.lower_attrs(hir_id, &i.attrs);
|
||||||
Some(hir::Item {
|
let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, &mut vis, &i.kind);
|
||||||
def_id: self.lower_node_id(i.id).expect_owner(),
|
Some(hir::Item { def_id: hir_id.expect_owner(), ident, attrs, kind, vis, span: i.span })
|
||||||
ident,
|
|
||||||
attrs,
|
|
||||||
kind,
|
|
||||||
vis,
|
|
||||||
span: i.span,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_item_kind(
|
fn lower_item_kind(
|
||||||
&mut self,
|
&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
|
hir_id: hir::HirId,
|
||||||
ident: &mut Ident,
|
ident: &mut Ident,
|
||||||
attrs: &'hir [Attribute],
|
attrs: &'hir [Attribute],
|
||||||
vis: &mut hir::Visibility<'hir>,
|
vis: &mut hir::Visibility<'hir>,
|
||||||
|
@ -365,14 +363,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
self.lower_generics(generics, ImplTraitContext::disallowed()),
|
self.lower_generics(generics, ImplTraitContext::disallowed()),
|
||||||
),
|
),
|
||||||
ItemKind::Struct(ref struct_def, ref generics) => {
|
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(
|
hir::ItemKind::Struct(
|
||||||
struct_def,
|
struct_def,
|
||||||
self.lower_generics(generics, ImplTraitContext::disallowed()),
|
self.lower_generics(generics, ImplTraitContext::disallowed()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ItemKind::Union(ref vdata, ref generics) => {
|
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(
|
hir::ItemKind::Union(
|
||||||
vdata,
|
vdata,
|
||||||
self.lower_generics(generics, ImplTraitContext::disallowed()),
|
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 path = this.lower_path_extra(res, &path, ParamMode::Explicit, None);
|
||||||
let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
|
let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
|
||||||
let vis = this.rebuild_vis(&vis);
|
let vis = this.rebuild_vis(&vis);
|
||||||
|
this.attrs.push_sparse(new_id, attrs);
|
||||||
|
|
||||||
this.insert_item(hir::Item {
|
this.insert_item(hir::Item {
|
||||||
def_id: new_id.expect_owner(),
|
def_id: new_id.expect_owner(),
|
||||||
|
@ -626,6 +625,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
|
|
||||||
let kind =
|
let kind =
|
||||||
this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs);
|
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 {
|
this.insert_item(hir::Item {
|
||||||
def_id: new_hir_id.expect_owner(),
|
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> {
|
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 {
|
hir::ForeignItem {
|
||||||
def_id,
|
def_id,
|
||||||
ident: i.ident,
|
ident: i.ident,
|
||||||
attrs: self.lower_attrs(&i.attrs),
|
attrs: self.lower_attrs(hir_id, &i.attrs),
|
||||||
kind: match i.kind {
|
kind: match i.kind {
|
||||||
ForeignItemKind::Fn(box FnKind(_, ref sig, ref generics, _)) => {
|
ForeignItemKind::Fn(box FnKind(_, ref sig, ref generics, _)) => {
|
||||||
let fdec = &sig.decl;
|
let fdec = &sig.decl;
|
||||||
|
@ -748,29 +749,43 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
|
fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
|
||||||
|
let id = self.lower_node_id(v.id);
|
||||||
hir::Variant {
|
hir::Variant {
|
||||||
attrs: self.lower_attrs(&v.attrs),
|
id,
|
||||||
data: self.lower_variant_data(&v.data),
|
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)),
|
disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
|
||||||
id: self.lower_node_id(v.id),
|
|
||||||
ident: v.ident,
|
ident: v.ident,
|
||||||
span: v.span,
|
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 {
|
match *vdata {
|
||||||
VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct(
|
VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct(
|
||||||
self.arena
|
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_struct_field(f))),
|
||||||
recovered,
|
recovered,
|
||||||
),
|
),
|
||||||
VariantData::Tuple(ref fields, id) => hir::VariantData::Tuple(
|
VariantData::Tuple(ref fields, id) => {
|
||||||
self.arena
|
let ctor_id = self.lower_node_id(id);
|
||||||
.alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_struct_field(f))),
|
self.attrs.push_sparse(ctor_id, self.attrs[parent_id]);
|
||||||
self.lower_node_id(id),
|
hir::VariantData::Tuple(
|
||||||
),
|
self.arena.alloc_from_iter(
|
||||||
VariantData::Unit(id) => hir::VariantData::Unit(self.lower_node_id(id)),
|
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 {
|
} else {
|
||||||
self.lower_ty(&f.ty, ImplTraitContext::disallowed())
|
self.lower_ty(&f.ty, ImplTraitContext::disallowed())
|
||||||
};
|
};
|
||||||
|
let hir_id = self.lower_node_id(f.id);
|
||||||
hir::StructField {
|
hir::StructField {
|
||||||
span: f.span,
|
span: f.span,
|
||||||
hir_id: self.lower_node_id(f.id),
|
hir_id,
|
||||||
ident: match f.ident {
|
ident: match f.ident {
|
||||||
Some(ident) => ident,
|
Some(ident) => ident,
|
||||||
// FIXME(jseyfried): positional field hygiene.
|
// FIXME(jseyfried): positional field hygiene.
|
||||||
|
@ -797,12 +813,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
},
|
},
|
||||||
vis: self.lower_visibility(&f.vis, None),
|
vis: self.lower_visibility(&f.vis, None),
|
||||||
ty,
|
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> {
|
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 {
|
let (generics, kind) = match i.kind {
|
||||||
AssocItemKind::Const(_, ref ty, ref default) => {
|
AssocItemKind::Const(_, ref ty, ref default) => {
|
||||||
|
@ -838,7 +855,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
hir::TraitItem {
|
hir::TraitItem {
|
||||||
def_id: trait_item_def_id,
|
def_id: trait_item_def_id,
|
||||||
ident: i.ident,
|
ident: i.ident,
|
||||||
attrs: self.lower_attrs(&i.attrs),
|
attrs: self.lower_attrs(hir_id, &i.attrs),
|
||||||
generics,
|
generics,
|
||||||
kind,
|
kind,
|
||||||
span: i.span,
|
span: i.span,
|
||||||
|
@ -920,10 +937,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
// Since `default impl` is not yet implemented, this is always true in impls.
|
// Since `default impl` is not yet implemented, this is always true in impls.
|
||||||
let has_value = true;
|
let has_value = true;
|
||||||
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
|
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
|
||||||
|
let hir_id = self.lower_node_id(i.id);
|
||||||
hir::ImplItem {
|
hir::ImplItem {
|
||||||
def_id: self.lower_node_id(i.id).expect_owner(),
|
def_id: hir_id.expect_owner(),
|
||||||
ident: i.ident,
|
ident: i.ident,
|
||||||
attrs: self.lower_attrs(&i.attrs),
|
attrs: self.lower_attrs(hir_id, &i.attrs),
|
||||||
generics,
|
generics,
|
||||||
vis: self.lower_visibility(&i.vis, None),
|
vis: self.lower_visibility(&i.vis, None),
|
||||||
defaultness,
|
defaultness,
|
||||||
|
@ -1024,9 +1042,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
|
fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
|
||||||
|
let hir_id = self.lower_node_id(param.id);
|
||||||
hir::Param {
|
hir::Param {
|
||||||
attrs: self.lower_attrs(¶m.attrs),
|
hir_id,
|
||||||
hir_id: self.lower_node_id(param.id),
|
attrs: self.lower_attrs(hir_id, ¶m.attrs),
|
||||||
pat: self.lower_pat(¶m.pat),
|
pat: self.lower_pat(¶m.pat),
|
||||||
ty_span: param.ty.span,
|
ty_span: param.ty.span,
|
||||||
span: param.span,
|
span: param.span,
|
||||||
|
|
|
@ -114,6 +114,8 @@ struct LoweringContext<'a, 'hir: 'a> {
|
||||||
|
|
||||||
generator_kind: Option<hir::GeneratorKind>,
|
generator_kind: Option<hir::GeneratorKind>,
|
||||||
|
|
||||||
|
attrs: hir::HirIdVec<&'hir [Attribute]>,
|
||||||
|
|
||||||
/// When inside an `async` context, this is the `HirId` of the
|
/// When inside an `async` context, this is the `HirId` of the
|
||||||
/// `task_context` local bound to the resume argument of the generator.
|
/// `task_context` local bound to the resume argument of the generator.
|
||||||
task_context: Option<hir::HirId>,
|
task_context: Option<hir::HirId>,
|
||||||
|
@ -309,6 +311,7 @@ pub fn lower_crate<'a, 'hir>(
|
||||||
bodies: BTreeMap::new(),
|
bodies: BTreeMap::new(),
|
||||||
trait_impls: BTreeMap::new(),
|
trait_impls: BTreeMap::new(),
|
||||||
modules: BTreeMap::new(),
|
modules: BTreeMap::new(),
|
||||||
|
attrs: hir::HirIdVec::default(),
|
||||||
exported_macros: Vec::new(),
|
exported_macros: Vec::new(),
|
||||||
non_exported_macro_attrs: Vec::new(),
|
non_exported_macro_attrs: Vec::new(),
|
||||||
catch_scopes: 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);
|
visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c);
|
||||||
|
|
||||||
let module = self.lower_mod(&c.items, c.span);
|
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 body_ids = body_ids(&self.bodies);
|
||||||
let proc_macros =
|
let proc_macros =
|
||||||
c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id].unwrap()).collect();
|
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);
|
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 {
|
hir::Crate {
|
||||||
item: hir::CrateItem { module, attrs, span: c.span },
|
item: hir::CrateItem { module, attrs, span: c.span },
|
||||||
exported_macros: self.arena.alloc_from_iter(self.exported_macros),
|
exported_macros: self.arena.alloc_from_iter(self.exported_macros),
|
||||||
|
@ -606,6 +612,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
modules: self.modules,
|
modules: self.modules,
|
||||||
proc_macros,
|
proc_macros,
|
||||||
trait_map,
|
trait_map,
|
||||||
|
attrs: self.attrs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -967,8 +974,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_attrs(&mut self, attrs: &[Attribute]) -> &'hir [Attribute] {
|
fn lower_attrs(&mut self, id: hir::HirId, attrs: &[Attribute]) -> &'hir [Attribute] {
|
||||||
self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)))
|
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 {
|
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 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::Local {
|
||||||
hir_id: self.lower_node_id(l.id),
|
hir_id,
|
||||||
ty,
|
ty,
|
||||||
pat: self.lower_pat(&l.pat),
|
pat: self.lower_pat(&l.pat),
|
||||||
init,
|
init,
|
||||||
span: l.span,
|
span: l.span,
|
||||||
attrs: l.attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>().into(),
|
attrs: attrs.into(),
|
||||||
source: hir::LocalSource::Normal,
|
source: hir::LocalSource::Normal,
|
||||||
},
|
},
|
||||||
ids,
|
ids,
|
||||||
|
@ -2300,12 +2312,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let hir_id = self.lower_node_id(param.id);
|
||||||
hir::GenericParam {
|
hir::GenericParam {
|
||||||
hir_id: self.lower_node_id(param.id),
|
hir_id,
|
||||||
name,
|
name,
|
||||||
span: param.ident.span,
|
span: param.ident.span,
|
||||||
pure_wrt_drop: self.sess.contains_name(¶m.attrs, sym::may_dangle),
|
pure_wrt_drop: self.sess.contains_name(¶m.attrs, sym::may_dangle),
|
||||||
attrs: self.lower_attrs(¶m.attrs),
|
attrs: self.lower_attrs(hir_id, ¶m.attrs),
|
||||||
bounds: self.arena.alloc_from_iter(bounds),
|
bounds: self.arena.alloc_from_iter(bounds),
|
||||||
kind,
|
kind,
|
||||||
}
|
}
|
||||||
|
@ -2519,7 +2532,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
pat: &'hir hir::Pat<'hir>,
|
pat: &'hir hir::Pat<'hir>,
|
||||||
source: hir::LocalSource,
|
source: hir::LocalSource,
|
||||||
) -> hir::Stmt<'hir> {
|
) -> 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)))
|
self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use crate::def::{CtorKind, DefKind, Namespace, Res};
|
use crate::def::{CtorKind, DefKind, Namespace, Res};
|
||||||
use crate::def_id::DefId;
|
use crate::def_id::DefId;
|
||||||
crate use crate::hir_id::HirId;
|
crate use crate::hir_id::HirId;
|
||||||
use crate::{itemlikevisit, LangItem};
|
use crate::{itemlikevisit, HirIdVec, LangItem};
|
||||||
|
|
||||||
use rustc_ast::util::parser::ExprPrecedence;
|
use rustc_ast::util::parser::ExprPrecedence;
|
||||||
use rustc_ast::{self as ast, CrateSugar, LlvmAsmDialect};
|
use rustc_ast::{self as ast, CrateSugar, LlvmAsmDialect};
|
||||||
|
@ -675,6 +675,9 @@ pub struct Crate<'hir> {
|
||||||
pub proc_macros: Vec<HirId>,
|
pub proc_macros: Vec<HirId>,
|
||||||
|
|
||||||
pub trait_map: BTreeMap<HirId, Vec<TraitCandidate>>,
|
pub trait_map: BTreeMap<HirId, Vec<TraitCandidate>>,
|
||||||
|
|
||||||
|
/// Collected attributes from HIR nodes.
|
||||||
|
pub attrs: HirIdVec<&'hir [Attribute]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Crate<'hir> {
|
impl Crate<'hir> {
|
||||||
|
|
|
@ -82,6 +82,20 @@ impl<T> HirIdVec<T> {
|
||||||
debug_assert_eq!(_ret_id, id.local_id);
|
debug_assert_eq!(_ret_id, id.local_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn push_sparse(&mut self, id: HirId, value: T)
|
||||||
|
where
|
||||||
|
T: Default,
|
||||||
|
{
|
||||||
|
self.map.ensure_contains_elem(id.owner, IndexVec::new);
|
||||||
|
let submap = &mut self.map[id.owner];
|
||||||
|
let i = id.local_id.index();
|
||||||
|
let len = submap.len();
|
||||||
|
if i >= len {
|
||||||
|
submap.extend(std::iter::repeat_with(T::default).take(i - len + 1));
|
||||||
|
}
|
||||||
|
submap[id.local_id] = value;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get(&self, id: HirId) -> Option<&T> {
|
pub fn get(&self, id: HirId) -> Option<&T> {
|
||||||
self.map.get(id.owner)?.get(id.local_id)
|
self.map.get(id.owner)?.get(id.local_id)
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,6 +116,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||||
modules: _,
|
modules: _,
|
||||||
proc_macros: _,
|
proc_macros: _,
|
||||||
trait_map: _,
|
trait_map: _,
|
||||||
|
attrs: _,
|
||||||
} = *krate;
|
} = *krate;
|
||||||
|
|
||||||
hash_body(&mut hcx, root_mod_def_path_hash, item, &mut hir_body_nodes)
|
hash_body(&mut hcx, root_mod_def_path_hash, item, &mut hir_body_nodes)
|
||||||
|
@ -131,7 +132,11 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||||
hcx,
|
hcx,
|
||||||
hir_body_nodes,
|
hir_body_nodes,
|
||||||
map: (0..definitions.def_index_count())
|
map: (0..definitions.def_index_count())
|
||||||
.map(|_| HirOwnerData { signature: None, with_bodies: None })
|
.map(|id| HirOwnerData {
|
||||||
|
attrs: krate.attrs.get_owner(Idx::new(id)),
|
||||||
|
signature: None,
|
||||||
|
with_bodies: None,
|
||||||
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
};
|
};
|
||||||
collector.insert_entry(
|
collector.insert_entry(
|
||||||
|
|
|
@ -88,6 +88,7 @@ fn is_body_owner<'hir>(node: Node<'hir>, hir_id: HirId) -> bool {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct HirOwnerData<'hir> {
|
pub(super) struct HirOwnerData<'hir> {
|
||||||
|
pub(super) attrs: &'hir IndexVec<ItemLocalId, &'hir [ast::Attribute]>,
|
||||||
pub(super) signature: Option<&'hir Owner<'hir>>,
|
pub(super) signature: Option<&'hir Owner<'hir>>,
|
||||||
pub(super) with_bodies: Option<&'hir mut OwnerNodes<'hir>>,
|
pub(super) with_bodies: Option<&'hir mut OwnerNodes<'hir>>,
|
||||||
}
|
}
|
||||||
|
@ -457,10 +458,7 @@ impl<'hir> Map<'hir> {
|
||||||
/// invoking `krate.attrs` because it registers a tighter
|
/// invoking `krate.attrs` because it registers a tighter
|
||||||
/// dep-graph access.
|
/// dep-graph access.
|
||||||
pub fn krate_attrs(&self) -> &'hir [ast::Attribute] {
|
pub fn krate_attrs(&self) -> &'hir [ast::Attribute] {
|
||||||
match self.get_entry(CRATE_HIR_ID).node {
|
self.attrs(CRATE_HIR_ID)
|
||||||
Node::Crate(item) => item.attrs,
|
|
||||||
_ => bug!(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_module(&self, module: LocalDefId) -> (&'hir Mod<'hir>, Span, HirId) {
|
pub fn get_module(&self, module: LocalDefId) -> (&'hir Mod<'hir>, Span, HirId) {
|
||||||
|
@ -853,34 +851,7 @@ impl<'hir> Map<'hir> {
|
||||||
/// Given a node ID, gets a list of attributes associated with the AST
|
/// Given a node ID, gets a list of attributes associated with the AST
|
||||||
/// corresponding to the node-ID.
|
/// corresponding to the node-ID.
|
||||||
pub fn attrs(&self, id: HirId) -> &'hir [ast::Attribute] {
|
pub fn attrs(&self, id: HirId) -> &'hir [ast::Attribute] {
|
||||||
self.find_entry(id).map_or(&[], |entry| match entry.node {
|
self.tcx.hir_attrs(id.owner).get(id.local_id).copied().unwrap_or(&[])
|
||||||
Node::Param(a) => a.attrs,
|
|
||||||
Node::Local(l) => &l.attrs[..],
|
|
||||||
Node::Item(i) => i.attrs,
|
|
||||||
Node::ForeignItem(fi) => fi.attrs,
|
|
||||||
Node::TraitItem(ref ti) => ti.attrs,
|
|
||||||
Node::ImplItem(ref ii) => ii.attrs,
|
|
||||||
Node::Variant(ref v) => v.attrs,
|
|
||||||
Node::Field(ref f) => f.attrs,
|
|
||||||
Node::Expr(ref e) => &*e.attrs,
|
|
||||||
Node::Stmt(ref s) => s.kind.attrs(|id| self.item(id)),
|
|
||||||
Node::Arm(ref a) => &*a.attrs,
|
|
||||||
Node::GenericParam(param) => param.attrs,
|
|
||||||
// Unit/tuple structs/variants take the attributes straight from
|
|
||||||
// the struct/variant definition.
|
|
||||||
Node::Ctor(..) => self.attrs(self.get_parent_item(id)),
|
|
||||||
Node::Crate(item) => item.attrs,
|
|
||||||
Node::MacroDef(def) => def.attrs,
|
|
||||||
Node::AnonConst(..)
|
|
||||||
| Node::PathSegment(..)
|
|
||||||
| Node::Ty(..)
|
|
||||||
| Node::Pat(..)
|
|
||||||
| Node::Binding(..)
|
|
||||||
| Node::TraitRef(..)
|
|
||||||
| Node::Block(..)
|
|
||||||
| Node::Lifetime(..)
|
|
||||||
| Node::Visibility(..) => &[],
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the span of the definition of the specified HIR node.
|
/// Gets the span of the definition of the specified HIR node.
|
||||||
|
|
|
@ -76,6 +76,7 @@ pub fn provide(providers: &mut Providers) {
|
||||||
providers.hir_module_items = |tcx, id| &tcx.untracked_crate.modules[&id];
|
providers.hir_module_items = |tcx, id| &tcx.untracked_crate.modules[&id];
|
||||||
providers.hir_owner = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].signature;
|
providers.hir_owner = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].signature;
|
||||||
providers.hir_owner_nodes = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].with_bodies.as_deref();
|
providers.hir_owner_nodes = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].with_bodies.as_deref();
|
||||||
|
providers.hir_attrs = |tcx, id| &tcx.index_hir(LOCAL_CRATE).map[id].attrs;
|
||||||
providers.def_span = |tcx, def_id| tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP);
|
providers.def_span = |tcx, def_id| tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP);
|
||||||
providers.fn_arg_names = |tcx, id| {
|
providers.fn_arg_names = |tcx, id| {
|
||||||
let hir = tcx.hir();
|
let hir = tcx.hir();
|
||||||
|
|
|
@ -61,6 +61,15 @@ rustc_queries! {
|
||||||
desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) }
|
desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gives access to the HIR attributes inside the HIR owner `key`.
|
||||||
|
///
|
||||||
|
/// This can be conveniently accessed by methods on `tcx.hir()`.
|
||||||
|
/// Avoid calling this query directly.
|
||||||
|
query hir_attrs(key: LocalDefId) -> &'tcx IndexVec<ItemLocalId, &'tcx [ast::Attribute]> {
|
||||||
|
eval_always
|
||||||
|
desc { |tcx| "HIR owner attributes in `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Computes the `DefId` of the corresponding const parameter in case the `key` is a
|
/// Computes the `DefId` of the corresponding const parameter in case the `key` is a
|
||||||
/// const argument and returns `None` otherwise.
|
/// const argument and returns `None` otherwise.
|
||||||
///
|
///
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue