Skip to content

Commit

Permalink
Auto merge of #79519 - cjgillot:noattr, r=wesleywiser
Browse files Browse the repository at this point in the history
Store HIR attributes in a side table

Same idea as #72015 but for attributes.
The objective is to reduce incr-comp invalidations due to modified attributes.
Notably, those due to modified doc comments.

Implementation:
- collect attributes during AST->HIR lowering, in `LocalDefId -> ItemLocalId -> &[Attributes]` nested tables;
- access the attributes through a `hir_owner_attrs` query;
- local refactorings to use this access;
- remove `attrs` from HIR data structures one-by-one.

Change in behaviour:
- the HIR visitor traverses all attributes at once instead of parent-by-parent;
- attribute arrays are sometimes duplicated: for statements and variant constructors;
- as a consequence, attributes are marked as used after unused-attribute lint emission to avoid duplicate lints.

~~Current bug: the lint level is not correctly applied in `std::backtrace_rs`, triggering an unused attribute warning on `#![no_std]`. I welcome suggestions.~~
  • Loading branch information
bors committed Mar 10, 2021
2 parents 861872b + 77c0f21 commit dff1edf
Show file tree
Hide file tree
Showing 88 changed files with 869 additions and 853 deletions.
73 changes: 30 additions & 43 deletions compiler/rustc_ast_lowering/src/expr.rs
Expand Up @@ -258,9 +258,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
ex.span = e.span;
}
// 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());
ex.attrs = attrs.into();
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;
}

Expand All @@ -272,12 +281,9 @@ 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);
self.lower_attrs(hir_id, &e.attrs);
hir::Expr { hir_id, kind, span: e.span }
})
}

Expand Down Expand Up @@ -618,14 +624,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::Guard::If(self.lower_expr(cond))
}
});
hir::Arm {
hir_id: self.next_id(),
attrs: self.lower_attrs(&arm.attrs),
pat,
guard,
body: self.lower_expr(&arm.body),
span: arm.span,
}
let hir_id = self.next_id();
self.lower_attrs(hir_id, &arm.attrs);
hir::Arm { hir_id, pat, guard, body: self.lower_expr(&arm.body), span: arm.span }
}

/// Lower an `async` construct to a generator that is then wrapped so it implements `Future`.
Expand Down Expand Up @@ -669,7 +670,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
Ident::with_dummy_span(sym::_task_context),
hir::BindingAnnotation::Mutable,
);
let param = hir::Param { attrs: &[], hir_id: self.next_id(), pat, ty_span: span, span };
let param = hir::Param { hir_id: self.next_id(), pat, ty_span: span, span };
let params = arena_vec![self; param];

let body_id = self.lower_body(move |this| {
Expand All @@ -690,12 +691,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
span,
Some(hir::Movability::Static),
);
let generator = hir::Expr {
hir_id: self.lower_node_id(closure_node_id),
kind: generator_kind,
span,
attrs: ThinVec::new(),
};
let generator =
hir::Expr { hir_id: self.lower_node_id(closure_node_id), kind: generator_kind, span };

// `future::from_generator`:
let unstable_span =
Expand Down Expand Up @@ -849,7 +846,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir_id: loop_hir_id,
kind: hir::ExprKind::Loop(loop_block, None, hir::LoopSource::Loop, span),
span,
attrs: ThinVec::new(),
});

// mut pinned => loop { ... }
Expand Down Expand Up @@ -1026,7 +1022,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

// Introduce a `let` for destructuring: `let (lhs1, lhs2) = t`.
let destructure_let = self.stmt_let_pat(
ThinVec::new(),
None,
whole_span,
Some(rhs),
pat,
Expand Down Expand Up @@ -1785,7 +1781,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

// `let mut __next`
let next_let = self.stmt_let_pat(
ThinVec::new(),
None,
desugared_span,
None,
next_pat,
Expand All @@ -1795,7 +1791,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// `let <pat> = __next`
let pat = self.lower_pat(pat);
let pat_let = self.stmt_let_pat(
ThinVec::new(),
None,
desugared_span,
Some(next_expr),
pat,
Expand All @@ -1819,12 +1815,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::LoopSource::ForLoop,
e.span.with_hi(orig_head_span.hi()),
);
let loop_expr = self.arena.alloc(hir::Expr {
hir_id: self.lower_node_id(e.id),
kind,
span: e.span,
attrs: ThinVec::new(),
});
let loop_expr =
self.arena.alloc(hir::Expr { hir_id: self.lower_node_id(e.id), kind, span: e.span });

// `mut iter => { ... }`
let iter_arm = self.arm(iter_pat, loop_expr);
Expand Down Expand Up @@ -2159,21 +2151,16 @@ 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.lower_attrs(hir_id, &attrs);
hir::Expr { hir_id, kind, span }
}

fn field(&mut self, ident: Ident, expr: &'hir hir::Expr<'hir>, span: Span) -> hir::Field<'hir> {
hir::Field { hir_id: self.next_id(), ident, span, expr, is_shorthand: false }
}

fn arm(&mut self, pat: &'hir hir::Pat<'hir>, expr: &'hir hir::Expr<'hir>) -> hir::Arm<'hir> {
hir::Arm {
hir_id: self.next_id(),
attrs: &[],
pat,
guard: None,
span: expr.span,
body: expr,
}
hir::Arm { hir_id: self.next_id(), pat, guard: None, span: expr.span, body: expr }
}
}

0 comments on commit dff1edf

Please sign in to comment.