Skip to content

Commit 38d9d09

Browse files
committed
Use BTreeMap to store attributes.
1 parent 90a562c commit 38d9d09

File tree

10 files changed

+117
-47
lines changed

10 files changed

+117
-47
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+15-9
Original file line numberDiff line numberDiff line change
@@ -258,12 +258,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
258258
ex.span = e.span;
259259
}
260260
// Merge attributes into the inner expression.
261-
self.attrs[ex.hir_id] = &*self.arena.alloc_from_iter(
262-
e.attrs
263-
.iter()
264-
.map(|a| self.lower_attr(a))
265-
.chain(self.attrs[ex.hir_id].iter().cloned()),
266-
);
261+
if !e.attrs.is_empty() {
262+
let old_attrs = self.attrs.get(&ex.hir_id).map(|la| *la).unwrap_or(&[]);
263+
self.attrs.insert(
264+
ex.hir_id,
265+
&*self.arena.alloc_from_iter(
266+
e.attrs
267+
.iter()
268+
.map(|a| self.lower_attr(a))
269+
.chain(old_attrs.iter().cloned()),
270+
),
271+
);
272+
}
267273
return ex;
268274
}
269275

@@ -1016,7 +1022,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10161022

10171023
// Introduce a `let` for destructuring: `let (lhs1, lhs2) = t`.
10181024
let destructure_let = self.stmt_let_pat(
1019-
&[],
1025+
None,
10201026
whole_span,
10211027
Some(rhs),
10221028
pat,
@@ -1775,7 +1781,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
17751781

17761782
// `let mut __next`
17771783
let next_let = self.stmt_let_pat(
1778-
&[],
1784+
None,
17791785
desugared_span,
17801786
None,
17811787
next_pat,
@@ -1785,7 +1791,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
17851791
// `let <pat> = __next`
17861792
let pat = self.lower_pat(pat);
17871793
let pat_let = self.stmt_let_pat(
1788-
&[],
1794+
None,
17891795
desugared_span,
17901796
Some(next_expr),
17911797
pat,

compiler/rustc_ast_lowering/src/item.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
251251
id: NodeId,
252252
hir_id: hir::HirId,
253253
ident: &mut Ident,
254-
attrs: &'hir [Attribute],
254+
attrs: Option<&'hir [Attribute]>,
255255
vis: &mut hir::Visibility<'hir>,
256256
i: &ItemKind,
257257
) -> hir::ItemKind<'hir> {
@@ -502,7 +502,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
502502
id: NodeId,
503503
vis: &mut hir::Visibility<'hir>,
504504
ident: &mut Ident,
505-
attrs: &'hir [Attribute],
505+
attrs: Option<&'hir [Attribute]>,
506506
) -> hir::ItemKind<'hir> {
507507
debug!("lower_use_tree(tree={:?})", tree);
508508
debug!("lower_use_tree: vis = {:?}", vis);
@@ -551,7 +551,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
551551
let path = this.lower_path_extra(res, &path, ParamMode::Explicit, None);
552552
let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
553553
let vis = this.rebuild_vis(&vis);
554-
this.attrs.push_sparse(new_id, attrs);
554+
if let Some(attrs) = attrs {
555+
this.attrs.insert(new_id, attrs);
556+
}
555557

556558
this.insert_item(hir::Item {
557559
def_id: new_id.expect_owner(),
@@ -623,7 +625,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
623625

624626
let kind =
625627
this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs);
626-
this.attrs.push_sparse(new_hir_id, attrs);
628+
if let Some(attrs) = attrs {
629+
this.attrs.insert(new_hir_id, attrs);
630+
}
627631

628632
this.insert_item(hir::Item {
629633
def_id: new_hir_id.expect_owner(),
@@ -770,7 +774,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
770774
),
771775
VariantData::Tuple(ref fields, id) => {
772776
let ctor_id = self.lower_node_id(id);
773-
self.attrs.push_sparse(ctor_id, self.attrs[parent_id]);
777+
self.alias_attrs(ctor_id, parent_id);
774778
hir::VariantData::Tuple(
775779
self.arena.alloc_from_iter(
776780
fields.iter().enumerate().map(|f| self.lower_struct_field(f)),
@@ -780,7 +784,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
780784
}
781785
VariantData::Unit(id) => {
782786
let ctor_id = self.lower_node_id(id);
783-
self.attrs.push_sparse(ctor_id, self.attrs[parent_id]);
787+
self.alias_attrs(ctor_id, parent_id);
784788
hir::VariantData::Unit(ctor_id)
785789
}
786790
}
@@ -1168,7 +1172,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
11681172
//
11691173
// If this is the simple case, this parameter will end up being the same as the
11701174
// original parameter, but with a different pattern id.
1171-
let stmt_attrs = this.attrs[parameter.hir_id];
1175+
let stmt_attrs = this.attrs.get(&parameter.hir_id).copied();
11721176
let (new_parameter_pat, new_parameter_id) = this.pat_ident(desugared_span, ident);
11731177
let new_parameter = hir::Param {
11741178
hir_id: parameter.hir_id,
@@ -1213,7 +1217,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12131217
);
12141218
let move_expr = this.expr_ident(desugared_span, ident, new_parameter_id);
12151219
let move_stmt = this.stmt_let_pat(
1216-
&[],
1220+
None,
12171221
desugared_span,
12181222
Some(move_expr),
12191223
move_pat,

compiler/rustc_ast_lowering/src/lib.rs

+33-13
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ struct LoweringContext<'a, 'hir: 'a> {
114114

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

117-
attrs: hir::HirIdVec<&'hir [Attribute]>,
117+
attrs: BTreeMap<hir::HirId, &'hir [Attribute]>,
118118

119119
/// When inside an `async` context, this is the `HirId` of the
120120
/// `task_context` local bound to the resume argument of the generator.
@@ -311,7 +311,7 @@ pub fn lower_crate<'a, 'hir>(
311311
bodies: BTreeMap::new(),
312312
trait_impls: BTreeMap::new(),
313313
modules: BTreeMap::new(),
314-
attrs: hir::HirIdVec::default(),
314+
attrs: BTreeMap::default(),
315315
exported_macros: Vec::new(),
316316
non_exported_macro_attrs: Vec::new(),
317317
catch_scopes: Vec::new(),
@@ -595,8 +595,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
595595

596596
self.resolver.definitions().init_def_id_to_hir_id_mapping(def_id_to_hir_id);
597597

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));
598+
#[cfg(debug_assertions)]
599+
for (&id, attrs) in self.attrs.iter() {
600+
// Verify that we do not store empty slices in the map.
601+
if attrs.is_empty() {
602+
panic!("Stored empty attributes for {:?}", id);
603+
}
604+
}
600605

601606
hir::Crate {
602607
item: hir::CrateItem { module, span: c.span },
@@ -973,10 +978,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
973978
ret
974979
}
975980

976-
fn lower_attrs(&mut self, id: hir::HirId, attrs: &[Attribute]) -> &'hir [Attribute] {
977-
let ret = self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)));
978-
self.attrs.push_sparse(id, ret);
979-
ret
981+
fn lower_attrs(&mut self, id: hir::HirId, attrs: &[Attribute]) -> Option<&'hir [Attribute]> {
982+
if attrs.is_empty() {
983+
None
984+
} else {
985+
let ret = self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)));
986+
debug_assert!(!ret.is_empty());
987+
self.attrs.insert(id, ret);
988+
Some(ret)
989+
}
980990
}
981991

982992
fn lower_attr(&self, attr: &Attribute) -> Attribute {
@@ -999,6 +1009,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
9991009
Attribute { kind, id: attr.id, style: attr.style, span: attr.span }
10001010
}
10011011

1012+
fn alias_attrs(&mut self, id: hir::HirId, target_id: hir::HirId) {
1013+
if let Some(&a) = self.attrs.get(&target_id) {
1014+
debug_assert!(!a.is_empty());
1015+
self.attrs.insert(id, a);
1016+
}
1017+
}
1018+
10021019
fn lower_mac_args(&self, args: &MacArgs) -> MacArgs {
10031020
match *args {
10041021
MacArgs::Empty => MacArgs::Empty,
@@ -2447,7 +2464,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
24472464
})
24482465
.collect();
24492466
let hir_id = self.lower_node_id(s.id);
2450-
self.attrs.push_sparse(hir_id, self.attrs[l.hir_id]);
2467+
self.alias_attrs(hir_id, l.hir_id);
24512468
ids.push({
24522469
hir::Stmt {
24532470
hir_id,
@@ -2476,13 +2493,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
24762493
StmtKind::Expr(ref e) => {
24772494
let e = self.lower_expr(e);
24782495
let hir_id = self.lower_node_id(s.id);
2479-
self.attrs.push_sparse(hir_id, self.attrs[e.hir_id]);
2496+
self.alias_attrs(hir_id, e.hir_id);
24802497
(hir_id, hir::StmtKind::Expr(e))
24812498
}
24822499
StmtKind::Semi(ref e) => {
24832500
let e = self.lower_expr(e);
24842501
let hir_id = self.lower_node_id(s.id);
2485-
self.attrs.push_sparse(hir_id, self.attrs[e.hir_id]);
2502+
self.alias_attrs(hir_id, e.hir_id);
24862503
(hir_id, hir::StmtKind::Semi(e))
24872504
}
24882505
StmtKind::Empty => return smallvec![],
@@ -2532,14 +2549,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
25322549

25332550
fn stmt_let_pat(
25342551
&mut self,
2535-
attrs: &'hir [Attribute],
2552+
attrs: Option<&'hir [Attribute]>,
25362553
span: Span,
25372554
init: Option<&'hir hir::Expr<'hir>>,
25382555
pat: &'hir hir::Pat<'hir>,
25392556
source: hir::LocalSource,
25402557
) -> hir::Stmt<'hir> {
25412558
let hir_id = self.next_id();
2542-
self.attrs.push_sparse(hir_id, attrs);
2559+
if let Some(a) = attrs {
2560+
debug_assert!(!a.is_empty());
2561+
self.attrs.insert(hir_id, a);
2562+
}
25432563
let local = hir::Local { hir_id, init, pat, source, span, ty: None };
25442564
self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))
25452565
}

compiler/rustc_hir/src/hir.rs

+2-2
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, HirIdVec, LangItem};
5+
use crate::{itemlikevisit, LangItem};
66

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

677677
/// Collected attributes from HIR nodes.
678-
pub attrs: HirIdVec<&'hir [Attribute]>,
678+
pub attrs: BTreeMap<HirId, &'hir [Attribute]>,
679679
}
680680

681681
impl Crate<'hir> {

compiler/rustc_hir/src/intravisit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ pub trait Visitor<'v>: Sized {
477477
pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate<'v>) {
478478
visitor.visit_mod(&krate.item.module, krate.item.span, CRATE_HIR_ID);
479479
walk_list!(visitor, visit_macro_def, krate.exported_macros);
480-
for (id, attrs) in krate.attrs.iter_enumerated() {
480+
for (&id, attrs) in krate.attrs.iter() {
481481
for a in *attrs {
482482
visitor.visit_attribute(id, a)
483483
}

compiler/rustc_hir_pretty/src/lib.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_target::spec::abi::Abi;
1616

1717
use std::borrow::Cow;
1818
use std::cell::Cell;
19+
use std::collections::BTreeMap;
1920
use std::vec;
2021

2122
pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: hir::HirId) -> String {
@@ -82,7 +83,7 @@ impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> {
8283
pub struct State<'a> {
8384
pub s: pp::Printer,
8485
comments: Option<Comments<'a>>,
85-
attrs: &'a hir::HirIdVec<&'a [ast::Attribute]>,
86+
attrs: &'a BTreeMap<hir::HirId, &'a [ast::Attribute]>,
8687
ann: &'a (dyn PpAnn + 'a),
8788
}
8889

@@ -169,7 +170,7 @@ pub fn print_crate<'a>(
169170
// When printing the AST, we sometimes need to inject `#[no_std]` here.
170171
// Since you can't compile the HIR, it's not necessary.
171172

172-
s.print_mod(&krate.item.module, krate.attrs[hir::CRATE_HIR_ID]);
173+
s.print_mod(&krate.item.module, s.attrs(hir::CRATE_HIR_ID));
173174
s.print_remaining_comments();
174175
s.s.eof()
175176
}
@@ -179,7 +180,7 @@ impl<'a> State<'a> {
179180
sm: &'a SourceMap,
180181
filename: FileName,
181182
input: String,
182-
attrs: &'a hir::HirIdVec<&[ast::Attribute]>,
183+
attrs: &'a BTreeMap<hir::HirId, &[ast::Attribute]>,
183184
ann: &'a dyn PpAnn,
184185
) -> State<'a> {
185186
State {
@@ -191,7 +192,7 @@ impl<'a> State<'a> {
191192
}
192193

193194
fn attrs(&self, id: hir::HirId) -> &'a [ast::Attribute] {
194-
self.attrs.get(id).map_or(&[], |la| *la)
195+
self.attrs.get(&id).map_or(&[], |la| *la)
195196
}
196197
}
197198

@@ -200,7 +201,7 @@ where
200201
F: FnOnce(&mut State<'_>),
201202
{
202203
let mut printer =
203-
State { s: pp::mk_printer(), comments: None, attrs: &hir::HirIdVec::default(), ann };
204+
State { s: pp::mk_printer(), comments: None, attrs: &BTreeMap::default(), ann };
204205
f(&mut printer);
205206
printer.s.eof()
206207
}

compiler/rustc_middle/src/hir/map/collector.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
132132
hcx,
133133
hir_body_nodes,
134134
map: (0..definitions.def_index_count())
135-
.map(|id| HirOwnerData {
136-
attrs: krate.attrs.get_owner(Idx::new(id)),
137-
signature: None,
138-
with_bodies: None,
139-
})
135+
.map(|_| HirOwnerData { signature: None, with_bodies: None })
140136
.collect(),
141137
};
142138
collector.insert_entry(

compiler/rustc_middle/src/hir/map/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ fn is_body_owner<'hir>(node: Node<'hir>, hir_id: HirId) -> bool {
8888

8989
#[derive(Debug)]
9090
pub(super) struct HirOwnerData<'hir> {
91-
pub(super) attrs: &'hir IndexVec<ItemLocalId, &'hir [ast::Attribute]>,
9291
pub(super) signature: Option<&'hir Owner<'hir>>,
9392
pub(super) with_bodies: Option<&'hir mut OwnerNodes<'hir>>,
9493
}
@@ -851,7 +850,7 @@ impl<'hir> Map<'hir> {
851850
/// Given a node ID, gets a list of attributes associated with the AST
852851
/// corresponding to the node-ID.
853852
pub fn attrs(&self, id: HirId) -> &'hir [ast::Attribute] {
854-
self.tcx.hir_attrs(id.owner).get(id.local_id).copied().unwrap_or(&[])
853+
self.tcx.hir_attrs(id.owner).get(id.local_id)
855854
}
856855

857856
/// Gets the span of the definition of the specified HIR node.

0 commit comments

Comments
 (0)