Use BTreeMap to store attributes.
This commit is contained in:
parent
90a562c7ff
commit
38d9d09a58
10 changed files with 117 additions and 47 deletions
|
@ -258,12 +258,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
ex.span = e.span;
|
||||
}
|
||||
// Merge attributes into the inner expression.
|
||||
self.attrs[ex.hir_id] = &*self.arena.alloc_from_iter(
|
||||
e.attrs
|
||||
.iter()
|
||||
.map(|a| self.lower_attr(a))
|
||||
.chain(self.attrs[ex.hir_id].iter().cloned()),
|
||||
);
|
||||
if !e.attrs.is_empty() {
|
||||
let old_attrs = self.attrs.get(&ex.hir_id).map(|la| *la).unwrap_or(&[]);
|
||||
self.attrs.insert(
|
||||
ex.hir_id,
|
||||
&*self.arena.alloc_from_iter(
|
||||
e.attrs
|
||||
.iter()
|
||||
.map(|a| self.lower_attr(a))
|
||||
.chain(old_attrs.iter().cloned()),
|
||||
),
|
||||
);
|
||||
}
|
||||
return ex;
|
||||
}
|
||||
|
||||
|
@ -1016,7 +1022,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
|
||||
// Introduce a `let` for destructuring: `let (lhs1, lhs2) = t`.
|
||||
let destructure_let = self.stmt_let_pat(
|
||||
&[],
|
||||
None,
|
||||
whole_span,
|
||||
Some(rhs),
|
||||
pat,
|
||||
|
@ -1775,7 +1781,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
|
||||
// `let mut __next`
|
||||
let next_let = self.stmt_let_pat(
|
||||
&[],
|
||||
None,
|
||||
desugared_span,
|
||||
None,
|
||||
next_pat,
|
||||
|
@ -1785,7 +1791,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
// `let <pat> = __next`
|
||||
let pat = self.lower_pat(pat);
|
||||
let pat_let = self.stmt_let_pat(
|
||||
&[],
|
||||
None,
|
||||
desugared_span,
|
||||
Some(next_expr),
|
||||
pat,
|
||||
|
|
|
@ -251,7 +251,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
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> {
|
||||
|
@ -502,7 +502,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
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);
|
||||
|
@ -551,7 +551,9 @@ 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);
|
||||
if let Some(attrs) = attrs {
|
||||
this.attrs.insert(new_id, attrs);
|
||||
}
|
||||
|
||||
this.insert_item(hir::Item {
|
||||
def_id: new_id.expect_owner(),
|
||||
|
@ -623,7 +625,9 @@ 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);
|
||||
if let Some(attrs) = attrs {
|
||||
this.attrs.insert(new_hir_id, attrs);
|
||||
}
|
||||
|
||||
this.insert_item(hir::Item {
|
||||
def_id: new_hir_id.expect_owner(),
|
||||
|
@ -770,7 +774,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
),
|
||||
VariantData::Tuple(ref fields, id) => {
|
||||
let ctor_id = self.lower_node_id(id);
|
||||
self.attrs.push_sparse(ctor_id, self.attrs[parent_id]);
|
||||
self.alias_attrs(ctor_id, parent_id);
|
||||
hir::VariantData::Tuple(
|
||||
self.arena.alloc_from_iter(
|
||||
fields.iter().enumerate().map(|f| self.lower_struct_field(f)),
|
||||
|
@ -780,7 +784,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}
|
||||
VariantData::Unit(id) => {
|
||||
let ctor_id = self.lower_node_id(id);
|
||||
self.attrs.push_sparse(ctor_id, self.attrs[parent_id]);
|
||||
self.alias_attrs(ctor_id, parent_id);
|
||||
hir::VariantData::Unit(ctor_id)
|
||||
}
|
||||
}
|
||||
|
@ -1168,7 +1172,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
//
|
||||
// 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 stmt_attrs = this.attrs[parameter.hir_id];
|
||||
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 {
|
||||
hir_id: parameter.hir_id,
|
||||
|
@ -1213,7 +1217,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
);
|
||||
let move_expr = this.expr_ident(desugared_span, ident, new_parameter_id);
|
||||
let move_stmt = this.stmt_let_pat(
|
||||
&[],
|
||||
None,
|
||||
desugared_span,
|
||||
Some(move_expr),
|
||||
move_pat,
|
||||
|
|
|
@ -114,7 +114,7 @@ struct LoweringContext<'a, 'hir: 'a> {
|
|||
|
||||
generator_kind: Option<hir::GeneratorKind>,
|
||||
|
||||
attrs: hir::HirIdVec<&'hir [Attribute]>,
|
||||
attrs: BTreeMap<hir::HirId, &'hir [Attribute]>,
|
||||
|
||||
/// When inside an `async` context, this is the `HirId` of the
|
||||
/// `task_context` local bound to the resume argument of the generator.
|
||||
|
@ -311,7 +311,7 @@ pub fn lower_crate<'a, 'hir>(
|
|||
bodies: BTreeMap::new(),
|
||||
trait_impls: BTreeMap::new(),
|
||||
modules: BTreeMap::new(),
|
||||
attrs: hir::HirIdVec::default(),
|
||||
attrs: BTreeMap::default(),
|
||||
exported_macros: Vec::new(),
|
||||
non_exported_macro_attrs: Vec::new(),
|
||||
catch_scopes: Vec::new(),
|
||||
|
@ -595,8 +595,13 @@ 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));
|
||||
#[cfg(debug_assertions)]
|
||||
for (&id, attrs) in self.attrs.iter() {
|
||||
// Verify that we do not store empty slices in the map.
|
||||
if attrs.is_empty() {
|
||||
panic!("Stored empty attributes for {:?}", id);
|
||||
}
|
||||
}
|
||||
|
||||
hir::Crate {
|
||||
item: hir::CrateItem { module, span: c.span },
|
||||
|
@ -973,10 +978,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
ret
|
||||
}
|
||||
|
||||
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_attrs(&mut self, id: hir::HirId, attrs: &[Attribute]) -> Option<&'hir [Attribute]> {
|
||||
if attrs.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let ret = self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)));
|
||||
debug_assert!(!ret.is_empty());
|
||||
self.attrs.insert(id, ret);
|
||||
Some(ret)
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_attr(&self, attr: &Attribute) -> Attribute {
|
||||
|
@ -999,6 +1009,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
Attribute { kind, id: attr.id, style: attr.style, span: attr.span }
|
||||
}
|
||||
|
||||
fn alias_attrs(&mut self, id: hir::HirId, target_id: hir::HirId) {
|
||||
if let Some(&a) = self.attrs.get(&target_id) {
|
||||
debug_assert!(!a.is_empty());
|
||||
self.attrs.insert(id, a);
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_mac_args(&self, args: &MacArgs) -> MacArgs {
|
||||
match *args {
|
||||
MacArgs::Empty => MacArgs::Empty,
|
||||
|
@ -2447,7 +2464,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
})
|
||||
.collect();
|
||||
let hir_id = self.lower_node_id(s.id);
|
||||
self.attrs.push_sparse(hir_id, self.attrs[l.hir_id]);
|
||||
self.alias_attrs(hir_id, l.hir_id);
|
||||
ids.push({
|
||||
hir::Stmt {
|
||||
hir_id,
|
||||
|
@ -2476,13 +2493,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
StmtKind::Expr(ref e) => {
|
||||
let e = self.lower_expr(e);
|
||||
let hir_id = self.lower_node_id(s.id);
|
||||
self.attrs.push_sparse(hir_id, self.attrs[e.hir_id]);
|
||||
self.alias_attrs(hir_id, e.hir_id);
|
||||
(hir_id, hir::StmtKind::Expr(e))
|
||||
}
|
||||
StmtKind::Semi(ref e) => {
|
||||
let e = self.lower_expr(e);
|
||||
let hir_id = self.lower_node_id(s.id);
|
||||
self.attrs.push_sparse(hir_id, self.attrs[e.hir_id]);
|
||||
self.alias_attrs(hir_id, e.hir_id);
|
||||
(hir_id, hir::StmtKind::Semi(e))
|
||||
}
|
||||
StmtKind::Empty => return smallvec![],
|
||||
|
@ -2532,14 +2549,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
fn stmt_let_pat(
|
||||
&mut self,
|
||||
attrs: &'hir [Attribute],
|
||||
attrs: Option<&'hir [Attribute]>,
|
||||
span: Span,
|
||||
init: Option<&'hir hir::Expr<'hir>>,
|
||||
pat: &'hir hir::Pat<'hir>,
|
||||
source: hir::LocalSource,
|
||||
) -> hir::Stmt<'hir> {
|
||||
let hir_id = self.next_id();
|
||||
self.attrs.push_sparse(hir_id, attrs);
|
||||
if let Some(a) = attrs {
|
||||
debug_assert!(!a.is_empty());
|
||||
self.attrs.insert(hir_id, a);
|
||||
}
|
||||
let local = hir::Local { hir_id, init, pat, source, span, ty: None };
|
||||
self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue