Skip to content

Commit 1fb257b

Browse files
committed
Collect attributes during HIR lowering.
1 parent d50ca3c commit 1fb257b

File tree

9 files changed

+126
-87
lines changed

9 files changed

+126
-87
lines changed

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
260260
// Merge attributes into the inner expression.
261261
let mut attrs: Vec<_> = e.attrs.iter().map(|a| self.lower_attr(a)).collect();
262262
attrs.extend::<Vec<_>>(ex.attrs.into());
263+
self.attrs[ex.hir_id] = &*self.arena.alloc_from_iter(attrs.iter().cloned());
263264
ex.attrs = attrs.into();
264265
return ex;
265266
}
@@ -272,12 +273,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
272273
ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span),
273274
};
274275

275-
hir::Expr {
276-
hir_id: self.lower_node_id(e.id),
277-
kind,
278-
span: e.span,
279-
attrs: e.attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>().into(),
280-
}
276+
let hir_id = self.lower_node_id(e.id);
277+
let attrs = e.attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>();
278+
self.attrs.push_sparse(hir_id, &*self.arena.alloc_from_iter(attrs.iter().cloned()));
279+
hir::Expr { hir_id, kind, span: e.span, attrs: attrs.into() }
281280
})
282281
}
283282

@@ -618,9 +617,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
618617
hir::Guard::If(self.lower_expr(cond))
619618
}
620619
});
620+
let hir_id = self.next_id();
621621
hir::Arm {
622-
hir_id: self.next_id(),
623-
attrs: self.lower_attrs(&arm.attrs),
622+
hir_id,
623+
attrs: self.lower_attrs(hir_id, &arm.attrs),
624624
pat,
625625
guard,
626626
body: self.lower_expr(&arm.body),
@@ -2159,7 +2159,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
21592159
kind: hir::ExprKind<'hir>,
21602160
attrs: AttrVec,
21612161
) -> hir::Expr<'hir> {
2162-
hir::Expr { hir_id: self.next_id(), kind, span, attrs }
2162+
let hir_id = self.next_id();
2163+
self.attrs.push_sparse(hir_id, &*self.arena.alloc_from_iter(attrs.iter().cloned()));
2164+
hir::Expr { hir_id, kind, span, attrs }
21632165
}
21642166

21652167
fn field(&mut self, ident: Ident, expr: &'hir hir::Expr<'hir>, span: Span) -> hir::Field<'hir> {

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 55 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -217,42 +217,40 @@ impl<'hir> LoweringContext<'_, 'hir> {
217217
pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item<'hir>> {
218218
let mut ident = i.ident;
219219
let mut vis = self.lower_visibility(&i.vis, None);
220-
let attrs = self.lower_attrs(&i.attrs);
221220

222221
if let ItemKind::MacroDef(MacroDef { ref body, macro_rules }) = i.kind {
223222
if !macro_rules || self.sess.contains_name(&i.attrs, sym::macro_export) {
224-
let def_id = self.lower_node_id(i.id).expect_owner();
223+
let hir_id = self.lower_node_id(i.id);
224+
let attrs = self.lower_attrs(hir_id, &i.attrs);
225225
let body = P(self.lower_mac_args(body));
226226
self.exported_macros.push(hir::MacroDef {
227227
ident,
228228
vis,
229229
attrs,
230-
def_id,
230+
def_id: hir_id.expect_owner(),
231231
span: i.span,
232232
ast: MacroDef { body, macro_rules },
233233
});
234234
} else {
235-
self.non_exported_macro_attrs.extend(attrs.iter().cloned());
235+
for a in i.attrs.iter() {
236+
let a = self.lower_attr(a);
237+
self.non_exported_macro_attrs.push(a);
238+
}
236239
}
237240
return None;
238241
}
239242

240-
let kind = self.lower_item_kind(i.span, i.id, &mut ident, attrs, &mut vis, &i.kind);
241-
242-
Some(hir::Item {
243-
def_id: self.lower_node_id(i.id).expect_owner(),
244-
ident,
245-
attrs,
246-
kind,
247-
vis,
248-
span: i.span,
249-
})
243+
let hir_id = self.lower_node_id(i.id);
244+
let attrs = self.lower_attrs(hir_id, &i.attrs);
245+
let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, &mut vis, &i.kind);
246+
Some(hir::Item { def_id: hir_id.expect_owner(), ident, attrs, kind, vis, span: i.span })
250247
}
251248

252249
fn lower_item_kind(
253250
&mut self,
254251
span: Span,
255252
id: NodeId,
253+
hir_id: hir::HirId,
256254
ident: &mut Ident,
257255
attrs: &'hir [Attribute],
258256
vis: &mut hir::Visibility<'hir>,
@@ -365,14 +363,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
365363
self.lower_generics(generics, ImplTraitContext::disallowed()),
366364
),
367365
ItemKind::Struct(ref struct_def, ref generics) => {
368-
let struct_def = self.lower_variant_data(struct_def);
366+
let struct_def = self.lower_variant_data(hir_id, struct_def);
369367
hir::ItemKind::Struct(
370368
struct_def,
371369
self.lower_generics(generics, ImplTraitContext::disallowed()),
372370
)
373371
}
374372
ItemKind::Union(ref vdata, ref generics) => {
375-
let vdata = self.lower_variant_data(vdata);
373+
let vdata = self.lower_variant_data(hir_id, vdata);
376374
hir::ItemKind::Union(
377375
vdata,
378376
self.lower_generics(generics, ImplTraitContext::disallowed()),
@@ -554,6 +552,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
554552
let path = this.lower_path_extra(res, &path, ParamMode::Explicit, None);
555553
let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
556554
let vis = this.rebuild_vis(&vis);
555+
this.attrs.push_sparse(new_id, attrs);
557556

558557
this.insert_item(hir::Item {
559558
def_id: new_id.expect_owner(),
@@ -626,6 +625,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
626625

627626
let kind =
628627
this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs);
628+
this.attrs.push_sparse(new_hir_id, attrs);
629629

630630
this.insert_item(hir::Item {
631631
def_id: new_hir_id.expect_owner(),
@@ -699,11 +699,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
699699
}
700700

701701
fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem<'hir> {
702-
let def_id = self.resolver.local_def_id(i.id);
702+
let hir_id = self.lower_node_id(i.id);
703+
let def_id = hir_id.expect_owner();
703704
hir::ForeignItem {
704705
def_id,
705706
ident: i.ident,
706-
attrs: self.lower_attrs(&i.attrs),
707+
attrs: self.lower_attrs(hir_id, &i.attrs),
707708
kind: match i.kind {
708709
ForeignItemKind::Fn(box FnKind(_, ref sig, ref generics, _)) => {
709710
let fdec = &sig.decl;
@@ -748,29 +749,43 @@ impl<'hir> LoweringContext<'_, 'hir> {
748749
}
749750

750751
fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
752+
let id = self.lower_node_id(v.id);
751753
hir::Variant {
752-
attrs: self.lower_attrs(&v.attrs),
753-
data: self.lower_variant_data(&v.data),
754+
id,
755+
attrs: self.lower_attrs(id, &v.attrs),
756+
data: self.lower_variant_data(id, &v.data),
754757
disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
755-
id: self.lower_node_id(v.id),
756758
ident: v.ident,
757759
span: v.span,
758760
}
759761
}
760762

761-
fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData<'hir> {
763+
fn lower_variant_data(
764+
&mut self,
765+
parent_id: hir::HirId,
766+
vdata: &VariantData,
767+
) -> hir::VariantData<'hir> {
762768
match *vdata {
763769
VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct(
764770
self.arena
765771
.alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_struct_field(f))),
766772
recovered,
767773
),
768-
VariantData::Tuple(ref fields, id) => hir::VariantData::Tuple(
769-
self.arena
770-
.alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_struct_field(f))),
771-
self.lower_node_id(id),
772-
),
773-
VariantData::Unit(id) => hir::VariantData::Unit(self.lower_node_id(id)),
774+
VariantData::Tuple(ref fields, id) => {
775+
let ctor_id = self.lower_node_id(id);
776+
self.attrs.push_sparse(ctor_id, self.attrs[parent_id]);
777+
hir::VariantData::Tuple(
778+
self.arena.alloc_from_iter(
779+
fields.iter().enumerate().map(|f| self.lower_struct_field(f)),
780+
),
781+
ctor_id,
782+
)
783+
}
784+
VariantData::Unit(id) => {
785+
let ctor_id = self.lower_node_id(id);
786+
self.attrs.push_sparse(ctor_id, self.attrs[parent_id]);
787+
hir::VariantData::Unit(ctor_id)
788+
}
774789
}
775790
}
776791

@@ -787,22 +802,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
787802
} else {
788803
self.lower_ty(&f.ty, ImplTraitContext::disallowed())
789804
};
805+
let hir_id = self.lower_node_id(f.id);
790806
hir::StructField {
791807
span: f.span,
792-
hir_id: self.lower_node_id(f.id),
808+
hir_id,
793809
ident: match f.ident {
794810
Some(ident) => ident,
795811
// FIXME(jseyfried): positional field hygiene.
796812
None => Ident::new(sym::integer(index), f.span),
797813
},
798814
vis: self.lower_visibility(&f.vis, None),
799815
ty,
800-
attrs: self.lower_attrs(&f.attrs),
816+
attrs: self.lower_attrs(hir_id, &f.attrs),
801817
}
802818
}
803819

804820
fn lower_trait_item(&mut self, i: &AssocItem) -> hir::TraitItem<'hir> {
805-
let trait_item_def_id = self.resolver.local_def_id(i.id);
821+
let hir_id = self.lower_node_id(i.id);
822+
let trait_item_def_id = hir_id.expect_owner();
806823

807824
let (generics, kind) = match i.kind {
808825
AssocItemKind::Const(_, ref ty, ref default) => {
@@ -838,7 +855,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
838855
hir::TraitItem {
839856
def_id: trait_item_def_id,
840857
ident: i.ident,
841-
attrs: self.lower_attrs(&i.attrs),
858+
attrs: self.lower_attrs(hir_id, &i.attrs),
842859
generics,
843860
kind,
844861
span: i.span,
@@ -920,10 +937,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
920937
// Since `default impl` is not yet implemented, this is always true in impls.
921938
let has_value = true;
922939
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
940+
let hir_id = self.lower_node_id(i.id);
923941
hir::ImplItem {
924-
def_id: self.lower_node_id(i.id).expect_owner(),
942+
def_id: hir_id.expect_owner(),
925943
ident: i.ident,
926-
attrs: self.lower_attrs(&i.attrs),
944+
attrs: self.lower_attrs(hir_id, &i.attrs),
927945
generics,
928946
vis: self.lower_visibility(&i.vis, None),
929947
defaultness,
@@ -1024,9 +1042,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
10241042
}
10251043

10261044
fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
1045+
let hir_id = self.lower_node_id(param.id);
10271046
hir::Param {
1028-
attrs: self.lower_attrs(&param.attrs),
1029-
hir_id: self.lower_node_id(param.id),
1047+
hir_id,
1048+
attrs: self.lower_attrs(hir_id, &param.attrs),
10301049
pat: self.lower_pat(&param.pat),
10311050
ty_span: param.ty.span,
10321051
span: param.span,

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ struct LoweringContext<'a, 'hir: 'a> {
114114

115115
generator_kind: Option<hir::GeneratorKind>,
116116

117+
attrs: hir::HirIdVec<&'hir [Attribute]>,
118+
117119
/// When inside an `async` context, this is the `HirId` of the
118120
/// `task_context` local bound to the resume argument of the generator.
119121
task_context: Option<hir::HirId>,
@@ -309,6 +311,7 @@ pub fn lower_crate<'a, 'hir>(
309311
bodies: BTreeMap::new(),
310312
trait_impls: BTreeMap::new(),
311313
modules: BTreeMap::new(),
314+
attrs: hir::HirIdVec::default(),
312315
exported_macros: Vec::new(),
313316
non_exported_macro_attrs: Vec::new(),
314317
catch_scopes: Vec::new(),
@@ -565,7 +568,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
565568
visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c);
566569

567570
let module = self.lower_mod(&c.items, c.span);
568-
let attrs = self.lower_attrs(&c.attrs);
571+
let attrs = self.lower_attrs(hir::CRATE_HIR_ID, &c.attrs);
569572
let body_ids = body_ids(&self.bodies);
570573
let proc_macros =
571574
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> {
592595

593596
self.resolver.definitions().init_def_id_to_hir_id_mapping(def_id_to_hir_id);
594597

598+
// Not all HIR owners have declared attrs. Complete with empty IndexVecs.
599+
self.attrs.push_owner(Idx::new(self.resolver.definitions().def_index_count() - 1));
600+
595601
hir::Crate {
596602
item: hir::CrateItem { module, attrs, span: c.span },
597603
exported_macros: self.arena.alloc_from_iter(self.exported_macros),
@@ -606,6 +612,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
606612
modules: self.modules,
607613
proc_macros,
608614
trait_map,
615+
attrs: self.attrs,
609616
}
610617
}
611618

@@ -967,8 +974,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
967974
ret
968975
}
969976

970-
fn lower_attrs(&mut self, attrs: &[Attribute]) -> &'hir [Attribute] {
971-
self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)))
977+
fn lower_attrs(&mut self, id: hir::HirId, attrs: &[Attribute]) -> &'hir [Attribute] {
978+
let ret = self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)));
979+
self.attrs.push_sparse(id, ret);
980+
ret
972981
}
973982

974983
fn lower_attr(&mut self, attr: &Attribute) -> Attribute {
@@ -1790,14 +1799,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17901799
)
17911800
});
17921801
let init = l.init.as_ref().map(|e| self.lower_expr(e));
1802+
let hir_id = self.lower_node_id(l.id);
1803+
let attrs = l.attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>();
1804+
self.attrs.push_sparse(hir_id, &*self.arena.alloc_from_iter(attrs.iter().cloned()));
17931805
(
17941806
hir::Local {
1795-
hir_id: self.lower_node_id(l.id),
1807+
hir_id,
17961808
ty,
17971809
pat: self.lower_pat(&l.pat),
17981810
init,
17991811
span: l.span,
1800-
attrs: l.attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>().into(),
1812+
attrs: attrs.into(),
18011813
source: hir::LocalSource::Normal,
18021814
},
18031815
ids,
@@ -2300,12 +2312,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23002312
}
23012313
};
23022314

2315+
let hir_id = self.lower_node_id(param.id);
23032316
hir::GenericParam {
2304-
hir_id: self.lower_node_id(param.id),
2317+
hir_id,
23052318
name,
23062319
span: param.ident.span,
23072320
pure_wrt_drop: self.sess.contains_name(&param.attrs, sym::may_dangle),
2308-
attrs: self.lower_attrs(&param.attrs),
2321+
attrs: self.lower_attrs(hir_id, &param.attrs),
23092322
bounds: self.arena.alloc_from_iter(bounds),
23102323
kind,
23112324
}
@@ -2519,7 +2532,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
25192532
pat: &'hir hir::Pat<'hir>,
25202533
source: hir::LocalSource,
25212534
) -> hir::Stmt<'hir> {
2522-
let local = hir::Local { attrs, hir_id: self.next_id(), init, pat, source, span, ty: None };
2535+
let hir_id = self.next_id();
2536+
self.attrs.push_sparse(hir_id, &*self.arena.alloc_from_iter(attrs.iter().cloned()));
2537+
let local = hir::Local { attrs, hir_id, init, pat, source, span, ty: None };
25232538
self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))
25242539
}
25252540

compiler/rustc_hir/src/hir.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
use crate::def::{CtorKind, DefKind, Namespace, Res};
33
use crate::def_id::DefId;
44
crate use crate::hir_id::HirId;
5-
use crate::{itemlikevisit, LangItem};
5+
use crate::{itemlikevisit, HirIdVec, LangItem};
66

77
use rustc_ast::util::parser::ExprPrecedence;
88
use rustc_ast::{self as ast, CrateSugar, LlvmAsmDialect};
@@ -675,6 +675,9 @@ pub struct Crate<'hir> {
675675
pub proc_macros: Vec<HirId>,
676676

677677
pub trait_map: BTreeMap<HirId, Vec<TraitCandidate>>,
678+
679+
/// Collected attributes from HIR nodes.
680+
pub attrs: HirIdVec<&'hir [Attribute]>,
678681
}
679682

680683
impl Crate<'hir> {

0 commit comments

Comments
 (0)