1
Fork 0

Use AttrVec in more places.

In some places we use `Vec<Attribute>` and some places we use
`ThinVec<Attribute>` (a.k.a. `AttrVec`). This results in various points
where we have to convert between `Vec` and `ThinVec`.

This commit changes the places that use `Vec<Attribute>` to use
`AttrVec`. A lot of this is mechanical and boring, but there are
some interesting parts:
- It adds a few new methods to `ThinVec`.
- It implements `MapInPlace` for `ThinVec`, and introduces a macro to
  avoid the repetition of this trait for `Vec`, `SmallVec`, and
  `ThinVec`.

Overall, it makes the code a little nicer, and has little effect on
performance. But it is a precursor to removing
`rustc_data_structures::thin_vec::ThinVec` and replacing it with
`thin_vec::ThinVec`, which is implemented more efficiently.
This commit is contained in:
Nicholas Nethercote 2022-08-17 12:34:33 +10:00
parent 650bff80a6
commit 619b8abaa6
49 changed files with 352 additions and 392 deletions

View file

@ -504,7 +504,7 @@ pub struct WhereEqPredicate {
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]
pub struct Crate { pub struct Crate {
pub attrs: Vec<Attribute>, pub attrs: AttrVec,
pub items: Vec<P<Item>>, pub items: Vec<P<Item>>,
pub spans: ModSpans, pub spans: ModSpans,
/// Must be equal to `CRATE_NODE_ID` after the crate root is expanded, but may hold /// Must be equal to `CRATE_NODE_ID` after the crate root is expanded, but may hold
@ -1268,7 +1268,7 @@ impl Expr {
id: DUMMY_NODE_ID, id: DUMMY_NODE_ID,
kind: ExprKind::Err, kind: ExprKind::Err,
span: DUMMY_SP, span: DUMMY_SP,
attrs: ThinVec::new(), attrs: AttrVec::new(),
tokens: None, tokens: None,
}, },
) )
@ -2669,7 +2669,7 @@ impl VariantData {
/// An item definition. /// An item definition.
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]
pub struct Item<K = ItemKind> { pub struct Item<K = ItemKind> {
pub attrs: Vec<Attribute>, pub attrs: AttrVec,
pub id: NodeId, pub id: NodeId,
pub span: Span, pub span: Span,
pub vis: Visibility, pub vis: Visibility,
@ -3036,19 +3036,19 @@ mod size_asserts {
use super::*; use super::*;
use rustc_data_structures::static_assert_size; use rustc_data_structures::static_assert_size;
// These are in alphabetical order, which is easy to maintain. // These are in alphabetical order, which is easy to maintain.
static_assert_size!(AssocItem, 120); static_assert_size!(AssocItem, 104);
static_assert_size!(AssocItemKind, 32); static_assert_size!(AssocItemKind, 32);
static_assert_size!(Attribute, 32); static_assert_size!(Attribute, 32);
static_assert_size!(Block, 48); static_assert_size!(Block, 48);
static_assert_size!(Expr, 104); static_assert_size!(Expr, 104);
static_assert_size!(ExprKind, 72); static_assert_size!(ExprKind, 72);
static_assert_size!(Fn, 192); static_assert_size!(Fn, 192);
static_assert_size!(ForeignItem, 112); static_assert_size!(ForeignItem, 96);
static_assert_size!(ForeignItemKind, 24); static_assert_size!(ForeignItemKind, 24);
static_assert_size!(GenericBound, 88); static_assert_size!(GenericBound, 88);
static_assert_size!(Generics, 72); static_assert_size!(Generics, 72);
static_assert_size!(Impl, 200); static_assert_size!(Impl, 200);
static_assert_size!(Item, 200); static_assert_size!(Item, 184);
static_assert_size!(ItemKind, 112); static_assert_size!(ItemKind, 112);
static_assert_size!(Lit, 48); static_assert_size!(Lit, 48);
static_assert_size!(LitKind, 24); static_assert_size!(LitKind, 24);

View file

@ -270,7 +270,7 @@ pub trait HasAttrs {
/// during token collection. /// during token collection.
const SUPPORTS_CUSTOM_INNER_ATTRS: bool; const SUPPORTS_CUSTOM_INNER_ATTRS: bool;
fn attrs(&self) -> &[Attribute]; fn attrs(&self) -> &[Attribute];
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)); fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec));
} }
macro_rules! impl_has_attrs { macro_rules! impl_has_attrs {
@ -283,8 +283,8 @@ macro_rules! impl_has_attrs {
&self.attrs &self.attrs
} }
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) { fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
VecOrAttrVec::visit(&mut self.attrs, f) f(&mut self.attrs)
} }
} }
)+ )+
@ -299,7 +299,7 @@ macro_rules! impl_has_attrs_none {
fn attrs(&self) -> &[Attribute] { fn attrs(&self) -> &[Attribute] {
&[] &[]
} }
fn visit_attrs(&mut self, _f: impl FnOnce(&mut Vec<Attribute>)) {} fn visit_attrs(&mut self, _f: impl FnOnce(&mut AttrVec)) {}
} }
)+ )+
}; };
@ -330,7 +330,7 @@ impl<T: AstDeref<Target: HasAttrs>> HasAttrs for T {
fn attrs(&self) -> &[Attribute] { fn attrs(&self) -> &[Attribute] {
self.ast_deref().attrs() self.ast_deref().attrs()
} }
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) { fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
self.ast_deref_mut().visit_attrs(f) self.ast_deref_mut().visit_attrs(f)
} }
} }
@ -340,7 +340,7 @@ impl<T: HasAttrs> HasAttrs for Option<T> {
fn attrs(&self) -> &[Attribute] { fn attrs(&self) -> &[Attribute] {
self.as_ref().map(|inner| inner.attrs()).unwrap_or(&[]) self.as_ref().map(|inner| inner.attrs()).unwrap_or(&[])
} }
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) { fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
if let Some(inner) = self.as_mut() { if let Some(inner) = self.as_mut() {
inner.visit_attrs(f); inner.visit_attrs(f);
} }
@ -362,13 +362,13 @@ impl HasAttrs for StmtKind {
} }
} }
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) { fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
match self { match self {
StmtKind::Local(local) => visit_attrvec(&mut local.attrs, f), StmtKind::Local(local) => f(&mut local.attrs),
StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.visit_attrs(f), StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.visit_attrs(f),
StmtKind::Item(item) => item.visit_attrs(f), StmtKind::Item(item) => item.visit_attrs(f),
StmtKind::Empty => {} StmtKind::Empty => {}
StmtKind::MacCall(mac) => visit_attrvec(&mut mac.attrs, f), StmtKind::MacCall(mac) => f(&mut mac.attrs),
} }
} }
} }
@ -378,38 +378,11 @@ impl HasAttrs for Stmt {
fn attrs(&self) -> &[Attribute] { fn attrs(&self) -> &[Attribute] {
self.kind.attrs() self.kind.attrs()
} }
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) { fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
self.kind.visit_attrs(f); self.kind.visit_attrs(f);
} }
} }
/// Helper trait for the impls above. Abstracts over
/// the two types of attribute fields that AST nodes
/// may have (`Vec<Attribute>` or `AttrVec`).
trait VecOrAttrVec {
fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>));
}
impl VecOrAttrVec for Vec<Attribute> {
fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
f(self)
}
}
impl VecOrAttrVec for AttrVec {
fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
visit_attrvec(self, f)
}
}
fn visit_attrvec(attrs: &mut AttrVec, f: impl FnOnce(&mut Vec<Attribute>)) {
crate::mut_visit::visit_clobber(attrs, |attrs| {
let mut vec = attrs.into();
f(&mut vec);
vec.into()
});
}
/// A newtype around an AST node that implements the traits above if the node implements them. /// A newtype around an AST node that implements the traits above if the node implements them.
pub struct AstNodeWrapper<Wrapped, Tag> { pub struct AstNodeWrapper<Wrapped, Tag> {
pub wrapped: Wrapped, pub wrapped: Wrapped,

View file

@ -12,7 +12,6 @@ use crate::tokenstream::{DelimSpan, Spacing, TokenTree};
use crate::tokenstream::{LazyTokenStream, TokenStream}; use crate::tokenstream::{LazyTokenStream, TokenStream};
use crate::util::comments; use crate::util::comments;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_index::bit_set::GrowableBitSet; use rustc_index::bit_set::GrowableBitSet;
use rustc_span::source_map::BytePos; use rustc_span::source_map::BytePos;
use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::symbol::{sym, Ident, Symbol};
@ -487,7 +486,7 @@ impl MetaItemKind {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
kind: ast::ExprKind::Lit(lit.clone()), kind: ast::ExprKind::Lit(lit.clone()),
span: lit.span, span: lit.span,
attrs: ThinVec::new(), attrs: ast::AttrVec::new(),
tokens: None, tokens: None,
}); });
MacArgs::Eq(span, MacArgsEq::Ast(expr)) MacArgs::Eq(span, MacArgsEq::Ast(expr))

View file

@ -14,7 +14,6 @@ use crate::tokenstream::*;
use rustc_data_structures::map_in_place::MapInPlace; use rustc_data_structures::map_in_place::MapInPlace;
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
use rustc_span::Span; use rustc_span::Span;
@ -338,12 +337,7 @@ where
} }
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
pub fn visit_attrs<T: MutVisitor>(attrs: &mut Vec<Attribute>, vis: &mut T) { pub fn visit_attrs<T: MutVisitor>(attrs: &mut AttrVec, vis: &mut T) {
visit_vec(attrs, |attr| vis.visit_attribute(attr));
}
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
pub fn visit_thin_attrs<T: MutVisitor>(attrs: &mut AttrVec, vis: &mut T) {
for attr in attrs.iter_mut() { for attr in attrs.iter_mut() {
vis.visit_attribute(attr); vis.visit_attribute(attr);
} }
@ -398,7 +392,7 @@ pub fn noop_flat_map_pat_field<T: MutVisitor>(
vis.visit_ident(ident); vis.visit_ident(ident);
vis.visit_pat(pat); vis.visit_pat(pat);
vis.visit_span(span); vis.visit_span(span);
visit_thin_attrs(attrs, vis); visit_attrs(attrs, vis);
smallvec![fp] smallvec![fp]
} }
@ -424,7 +418,7 @@ pub fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) {
pub fn noop_flat_map_arm<T: MutVisitor>(mut arm: Arm, vis: &mut T) -> SmallVec<[Arm; 1]> { pub fn noop_flat_map_arm<T: MutVisitor>(mut arm: Arm, vis: &mut T) -> SmallVec<[Arm; 1]> {
let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm; let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm;
visit_thin_attrs(attrs, vis); visit_attrs(attrs, vis);
vis.visit_id(id); vis.visit_id(id);
vis.visit_pat(pat); vis.visit_pat(pat);
visit_opt(guard, |guard| vis.visit_expr(guard)); visit_opt(guard, |guard| vis.visit_expr(guard));
@ -507,7 +501,7 @@ pub fn noop_flat_map_variant<T: MutVisitor>(
let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant; let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant;
visitor.visit_ident(ident); visitor.visit_ident(ident);
visitor.visit_vis(vis); visitor.visit_vis(vis);
visit_thin_attrs(attrs, visitor); visit_attrs(attrs, visitor);
visitor.visit_id(id); visitor.visit_id(id);
visitor.visit_variant_data(data); visitor.visit_variant_data(data);
visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr)); visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr));
@ -589,7 +583,7 @@ pub fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) {
} }
} }
vis.visit_span(span); vis.visit_span(span);
visit_thin_attrs(attrs, vis); visit_attrs(attrs, vis);
visit_lazy_tts(tokens, vis); visit_lazy_tts(tokens, vis);
} }
@ -640,7 +634,7 @@ pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) {
pub fn noop_flat_map_param<T: MutVisitor>(mut param: Param, vis: &mut T) -> SmallVec<[Param; 1]> { pub fn noop_flat_map_param<T: MutVisitor>(mut param: Param, vis: &mut T) -> SmallVec<[Param; 1]> {
let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param; let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param;
vis.visit_id(id); vis.visit_id(id);
visit_thin_attrs(attrs, vis); visit_attrs(attrs, vis);
vis.visit_pat(pat); vis.visit_pat(pat);
vis.visit_span(span); vis.visit_span(span);
vis.visit_ty(ty); vis.visit_ty(ty);
@ -882,7 +876,7 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>(
if let Some(ref mut colon_span) = colon_span { if let Some(ref mut colon_span) = colon_span {
vis.visit_span(colon_span); vis.visit_span(colon_span);
} }
visit_thin_attrs(attrs, vis); visit_attrs(attrs, vis);
visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis)); visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis));
match kind { match kind {
GenericParamKind::Lifetime => {} GenericParamKind::Lifetime => {}
@ -978,7 +972,7 @@ pub fn noop_flat_map_field_def<T: MutVisitor>(
visitor.visit_vis(vis); visitor.visit_vis(vis);
visitor.visit_id(id); visitor.visit_id(id);
visitor.visit_ty(ty); visitor.visit_ty(ty);
visit_thin_attrs(attrs, visitor); visit_attrs(attrs, visitor);
smallvec![fd] smallvec![fd]
} }
@ -991,7 +985,7 @@ pub fn noop_flat_map_expr_field<T: MutVisitor>(
vis.visit_expr(expr); vis.visit_expr(expr);
vis.visit_id(id); vis.visit_id(id);
vis.visit_span(span); vis.visit_span(span);
visit_thin_attrs(attrs, vis); visit_attrs(attrs, vis);
smallvec![f] smallvec![f]
} }
@ -1432,7 +1426,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
} }
vis.visit_id(id); vis.visit_id(id);
vis.visit_span(span); vis.visit_span(span);
visit_thin_attrs(attrs, vis); visit_attrs(attrs, vis);
visit_lazy_tts(tokens, vis); visit_lazy_tts(tokens, vis);
} }
@ -1478,7 +1472,7 @@ pub fn noop_flat_map_stmt_kind<T: MutVisitor>(
StmtKind::MacCall(mut mac) => { StmtKind::MacCall(mut mac) => {
let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut(); let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut();
vis.visit_mac_call(mac_); vis.visit_mac_call(mac_);
visit_thin_attrs(attrs, vis); visit_attrs(attrs, vis);
visit_lazy_tts(tokens, vis); visit_lazy_tts(tokens, vis);
smallvec![StmtKind::MacCall(mac)] smallvec![StmtKind::MacCall(mac)]
} }
@ -1513,12 +1507,6 @@ impl<T: DummyAstNode + 'static> DummyAstNode for P<T> {
} }
} }
impl<T> DummyAstNode for ThinVec<T> {
fn dummy() -> Self {
Default::default()
}
}
impl DummyAstNode for Item { impl DummyAstNode for Item {
fn dummy() -> Self { fn dummy() -> Self {
Item { Item {

View file

@ -6,7 +6,6 @@ use rustc_ast::attr;
use rustc_ast::ptr::P as AstP; use rustc_ast::ptr::P as AstP;
use rustc_ast::*; use rustc_ast::*;
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_errors::struct_span_err; use rustc_errors::struct_span_err;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::Res; use rustc_hir::def::Res;
@ -448,12 +447,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
let lowered_cond = self.with_loop_condition_scope(|t| t.lower_expr(cond)); let lowered_cond = self.with_loop_condition_scope(|t| t.lower_expr(cond));
let new_cond = self.manage_let_cond(lowered_cond); let new_cond = self.manage_let_cond(lowered_cond);
let then = self.lower_block_expr(body); let then = self.lower_block_expr(body);
let expr_break = self.expr_break(span, ThinVec::new()); let expr_break = self.expr_break(span, AttrVec::new());
let stmt_break = self.stmt_expr(span, expr_break); let stmt_break = self.stmt_expr(span, expr_break);
let else_blk = self.block_all(span, arena_vec![self; stmt_break], None); let else_blk = self.block_all(span, arena_vec![self; stmt_break], None);
let else_expr = self.arena.alloc(self.expr_block(else_blk, ThinVec::new())); let else_expr = self.arena.alloc(self.expr_block(else_blk, AttrVec::new()));
let if_kind = hir::ExprKind::If(new_cond, self.arena.alloc(then), Some(else_expr)); let if_kind = hir::ExprKind::If(new_cond, self.arena.alloc(then), Some(else_expr));
let if_expr = self.expr(span, if_kind, ThinVec::new()); let if_expr = self.expr(span, if_kind, AttrVec::new());
let block = self.block_expr(self.arena.alloc(if_expr)); let block = self.block_expr(self.arena.alloc(if_expr));
let span = self.lower_span(span.with_hi(cond.span.hi())); let span = self.lower_span(span.with_hi(cond.span.hi()));
let opt_label = self.lower_label(opt_label); let opt_label = self.lower_label(opt_label);
@ -512,7 +511,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let constructor = self.arena.alloc(self.expr_lang_item_path( let constructor = self.arena.alloc(self.expr_lang_item_path(
method_span, method_span,
lang_item, lang_item,
ThinVec::new(), AttrVec::new(),
None, None,
)); ));
self.expr_call(overall_span, constructor, std::slice::from_ref(expr)) self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
@ -635,7 +634,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let gen_future = self.expr_lang_item_path( let gen_future = self.expr_lang_item_path(
unstable_span, unstable_span,
hir::LangItem::FromGenerator, hir::LangItem::FromGenerator,
ThinVec::new(), AttrVec::new(),
None, None,
); );
@ -747,7 +746,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let break_x = self.with_loop_scope(loop_node_id, move |this| { let break_x = self.with_loop_scope(loop_node_id, move |this| {
let expr_break = let expr_break =
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr)); hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
this.arena.alloc(this.expr(gen_future_span, expr_break, ThinVec::new())) this.arena.alloc(this.expr(gen_future_span, expr_break, AttrVec::new()))
}); });
self.arm(ready_pat, break_x) self.arm(ready_pat, break_x)
}; };
@ -780,7 +779,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let yield_expr = self.expr( let yield_expr = self.expr(
span, span,
hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }), hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }),
ThinVec::new(), AttrVec::new(),
); );
let yield_expr = self.arena.alloc(yield_expr); let yield_expr = self.arena.alloc(yield_expr);
@ -987,7 +986,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::AsyncGeneratorKind::Closure, hir::AsyncGeneratorKind::Closure,
|this| this.with_new_scopes(|this| this.lower_expr_mut(body)), |this| this.with_new_scopes(|this| this.lower_expr_mut(body)),
); );
this.expr(fn_decl_span, async_body, ThinVec::new()) this.expr(fn_decl_span, async_body, AttrVec::new())
}); });
body_id body_id
}); });
@ -1257,7 +1256,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let ident = self.expr_ident(lhs.span, ident, binding); let ident = self.expr_ident(lhs.span, ident, binding);
let assign = let assign =
hir::ExprKind::Assign(self.lower_expr(lhs), ident, self.lower_span(eq_sign_span)); hir::ExprKind::Assign(self.lower_expr(lhs), ident, self.lower_span(eq_sign_span));
let expr = self.expr(lhs.span, assign, ThinVec::new()); let expr = self.expr(lhs.span, assign, AttrVec::new());
assignments.push(self.stmt_expr(lhs.span, expr)); assignments.push(self.stmt_expr(lhs.span, expr));
pat pat
} }
@ -1299,7 +1298,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let fn_path = let fn_path =
hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None); hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None);
let fn_expr = let fn_expr =
self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new())); self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), AttrVec::new()));
hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2]) hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
} }
@ -1472,7 +1471,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// `None => break` // `None => break`
let none_arm = { let none_arm = {
let break_expr = let break_expr =
self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span, ThinVec::new())); self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span, AttrVec::new()));
let pat = self.pat_none(for_span); let pat = self.pat_none(for_span);
self.arm(pat, break_expr) self.arm(pat, break_expr)
}; };
@ -1481,7 +1480,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let some_arm = { let some_arm = {
let some_pat = self.pat_some(pat_span, pat); let some_pat = self.pat_some(pat_span, pat);
let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false)); let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false));
let body_expr = self.arena.alloc(self.expr_block(body_block, ThinVec::new())); let body_expr = self.arena.alloc(self.expr_block(body_block, AttrVec::new()));
self.arm(some_pat, body_expr) self.arm(some_pat, body_expr)
}; };
@ -1596,7 +1595,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}; };
attr::mk_attr_outer(allow) attr::mk_attr_outer(allow)
}; };
let attrs = vec![attr]; let attrs: AttrVec = vec![attr].into();
// `ControlFlow::Continue(val) => #[allow(unreachable_code)] val,` // `ControlFlow::Continue(val) => #[allow(unreachable_code)] val,`
let continue_arm = { let continue_arm = {
@ -1606,7 +1605,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
span, span,
val_ident, val_ident,
val_pat_nid, val_pat_nid,
ThinVec::from(attrs.clone()), attrs.clone(),
)); ));
let continue_pat = self.pat_cf_continue(unstable_span, val_pat); let continue_pat = self.pat_cf_continue(unstable_span, val_pat);
self.arm(continue_pat, val_expr) self.arm(continue_pat, val_expr)
@ -1625,7 +1624,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.arena.alloc(residual_expr), self.arena.alloc(residual_expr),
unstable_span, unstable_span,
); );
let thin_attrs = ThinVec::from(attrs);
let ret_expr = if let Some(catch_node) = self.catch_scope { let ret_expr = if let Some(catch_node) = self.catch_scope {
let target_id = Ok(self.lower_node_id(catch_node)); let target_id = Ok(self.lower_node_id(catch_node));
self.arena.alloc(self.expr( self.arena.alloc(self.expr(
@ -1634,13 +1632,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::Destination { label: None, target_id }, hir::Destination { label: None, target_id },
Some(from_residual_expr), Some(from_residual_expr),
), ),
thin_attrs, attrs,
)) ))
} else { } else {
self.arena.alloc(self.expr( self.arena.alloc(self.expr(
try_span, try_span,
hir::ExprKind::Ret(Some(from_residual_expr)), hir::ExprKind::Ret(Some(from_residual_expr)),
thin_attrs, attrs,
)) ))
}; };
@ -1728,7 +1726,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
arms: &'hir [hir::Arm<'hir>], arms: &'hir [hir::Arm<'hir>],
source: hir::MatchSource, source: hir::MatchSource,
) -> hir::Expr<'hir> { ) -> hir::Expr<'hir> {
self.expr(span, hir::ExprKind::Match(arg, arms, source), ThinVec::new()) self.expr(span, hir::ExprKind::Match(arg, arms, source), AttrVec::new())
} }
fn expr_break(&mut self, span: Span, attrs: AttrVec) -> hir::Expr<'hir> { fn expr_break(&mut self, span: Span, attrs: AttrVec) -> hir::Expr<'hir> {
@ -1745,12 +1743,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.expr( self.expr(
span, span,
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e), hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e),
ThinVec::new(), AttrVec::new(),
) )
} }
fn expr_unit(&mut self, sp: Span) -> &'hir hir::Expr<'hir> { fn expr_unit(&mut self, sp: Span) -> &'hir hir::Expr<'hir> {
self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]), ThinVec::new())) self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]), AttrVec::new()))
} }
fn expr_call_mut( fn expr_call_mut(
@ -1759,7 +1757,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
e: &'hir hir::Expr<'hir>, e: &'hir hir::Expr<'hir>,
args: &'hir [hir::Expr<'hir>], args: &'hir [hir::Expr<'hir>],
) -> hir::Expr<'hir> { ) -> hir::Expr<'hir> {
self.expr(span, hir::ExprKind::Call(e, args), ThinVec::new()) self.expr(span, hir::ExprKind::Call(e, args), AttrVec::new())
} }
fn expr_call( fn expr_call(
@ -1779,7 +1777,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir_id: Option<hir::HirId>, hir_id: Option<hir::HirId>,
) -> hir::Expr<'hir> { ) -> hir::Expr<'hir> {
let path = let path =
self.arena.alloc(self.expr_lang_item_path(span, lang_item, ThinVec::new(), hir_id)); self.arena.alloc(self.expr_lang_item_path(span, lang_item, AttrVec::new(), hir_id));
self.expr_call_mut(span, path, args) self.expr_call_mut(span, path, args)
} }
@ -1822,7 +1820,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ident: Ident, ident: Ident,
binding: hir::HirId, binding: hir::HirId,
) -> hir::Expr<'hir> { ) -> hir::Expr<'hir> {
self.expr_ident_with_attrs(sp, ident, binding, ThinVec::new()) self.expr_ident_with_attrs(sp, ident, binding, AttrVec::new())
} }
fn expr_ident_with_attrs( fn expr_ident_with_attrs(
@ -1860,13 +1858,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
}), }),
None, None,
), ),
ThinVec::new(), AttrVec::new(),
) )
} }
fn expr_block_empty(&mut self, span: Span) -> &'hir hir::Expr<'hir> { fn expr_block_empty(&mut self, span: Span) -> &'hir hir::Expr<'hir> {
let blk = self.block_all(span, &[], None); let blk = self.block_all(span, &[], None);
let expr = self.expr_block(blk, ThinVec::new()); let expr = self.expr_block(blk, AttrVec::new());
self.arena.alloc(expr) self.arena.alloc(expr)
} }

View file

@ -852,7 +852,7 @@ pub(super) fn expand_global_asm<'cx>(
if let Some(inline_asm) = expand_preparsed_asm(ecx, args) { if let Some(inline_asm) = expand_preparsed_asm(ecx, args) {
MacEager::items(smallvec![P(ast::Item { MacEager::items(smallvec![P(ast::Item {
ident: Ident::empty(), ident: Ident::empty(),
attrs: Vec::new(), attrs: ast::AttrVec::new(),
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)), kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)),
vis: ast::Visibility { vis: ast::Visibility {

View file

@ -119,7 +119,8 @@ impl<'cx, 'a> Context<'cx, 'a> {
vec![self.cx.attribute(attr::mk_list_item( vec![self.cx.attribute(attr::mk_list_item(
Ident::new(sym::allow, self.span), Ident::new(sym::allow, self.span),
vec![attr::mk_nested_word_item(Ident::new(sym::unused_imports, self.span))], vec![attr::mk_nested_word_item(Ident::new(sym::unused_imports, self.span))],
))], ))]
.into(),
ItemKind::Use(UseTree { ItemKind::Use(UseTree {
prefix: self.cx.path(self.span, self.cx.std_path(&[sym::asserting])), prefix: self.cx.path(self.span, self.cx.std_path(&[sym::asserting])),
kind: UseTreeKind::Nested(vec![ kind: UseTreeKind::Nested(vec![

View file

@ -68,7 +68,7 @@ pub fn expand_deriving_clone(
} }
let inline = cx.meta_word(span, sym::inline); let inline = cx.meta_word(span, sym::inline);
let attrs = vec![cx.attribute(inline)]; let attrs = vec![cx.attribute(inline)].into();
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
path: path_std!(clone::Clone), path: path_std!(clone::Clone),

View file

@ -20,7 +20,7 @@ pub fn expand_deriving_eq(
let hidden = rustc_ast::attr::mk_nested_word_item(Ident::new(sym::hidden, span)); let hidden = rustc_ast::attr::mk_nested_word_item(Ident::new(sym::hidden, span));
let doc = rustc_ast::attr::mk_list_item(Ident::new(sym::doc, span), vec![hidden]); let doc = rustc_ast::attr::mk_list_item(Ident::new(sym::doc, span), vec![hidden]);
let no_coverage = cx.meta_word(span, sym::no_coverage); let no_coverage = cx.meta_word(span, sym::no_coverage);
let attrs = vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)]; let attrs = vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)].into();
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
path: path_std!(cmp::Eq), path: path_std!(cmp::Eq),

View file

@ -15,7 +15,7 @@ pub fn expand_deriving_ord(
push: &mut dyn FnMut(Annotatable), push: &mut dyn FnMut(Annotatable),
) { ) {
let inline = cx.meta_word(span, sym::inline); let inline = cx.meta_word(span, sym::inline);
let attrs = vec![cx.attribute(inline)]; let attrs = vec![cx.attribute(inline)].into();
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
path: path_std!(cmp::Ord), path: path_std!(cmp::Ord),

View file

@ -68,7 +68,7 @@ pub fn expand_deriving_partial_eq(
// No need to generate `ne`, the default suffices, and not generating it is // No need to generate `ne`, the default suffices, and not generating it is
// faster. // faster.
let inline = cx.meta_word(span, sym::inline); let inline = cx.meta_word(span, sym::inline);
let attrs = vec![cx.attribute(inline)]; let attrs = vec![cx.attribute(inline)].into();
let methods = vec![MethodDef { let methods = vec![MethodDef {
name: sym::eq, name: sym::eq,
generics: Bounds::empty(), generics: Bounds::empty(),

View file

@ -19,7 +19,7 @@ pub fn expand_deriving_partial_ord(
Path(Path::new_(pathvec_std!(option::Option), vec![Box::new(ordering_ty)], PathKind::Std)); Path(Path::new_(pathvec_std!(option::Option), vec![Box::new(ordering_ty)], PathKind::Std));
let inline = cx.meta_word(span, sym::inline); let inline = cx.meta_word(span, sym::inline);
let attrs = vec![cx.attribute(inline)]; let attrs = vec![cx.attribute(inline)].into();
let partial_cmp_def = MethodDef { let partial_cmp_def = MethodDef {
name: sym::partial_cmp, name: sym::partial_cmp,

View file

@ -29,7 +29,7 @@ pub fn expand_deriving_debug(
explicit_self: true, explicit_self: true,
nonself_args: vec![(fmtr, sym::f)], nonself_args: vec![(fmtr, sym::f)],
ret_ty: Path(path_std!(fmt::Result)), ret_ty: Path(path_std!(fmt::Result)),
attributes: Vec::new(), attributes: ast::AttrVec::new(),
unify_fieldless_variants: false, unify_fieldless_variants: false,
combine_substructure: combine_substructure(Box::new(|a, b, c| { combine_substructure: combine_substructure(Box::new(|a, b, c| {
show_substructure(a, b, c) show_substructure(a, b, c)

View file

@ -47,7 +47,7 @@ pub fn expand_deriving_rustc_decodable(
], ],
PathKind::Std, PathKind::Std,
)), )),
attributes: Vec::new(), attributes: ast::AttrVec::new(),
unify_fieldless_variants: false, unify_fieldless_variants: false,
combine_substructure: combine_substructure(Box::new(|a, b, c| { combine_substructure: combine_substructure(Box::new(|a, b, c| {
decodable_substructure(a, b, c, krate) decodable_substructure(a, b, c, krate)

View file

@ -2,9 +2,7 @@ use crate::deriving::generic::ty::*;
use crate::deriving::generic::*; use crate::deriving::generic::*;
use rustc_ast as ast; use rustc_ast as ast;
use rustc_ast::walk_list; use rustc_ast::{walk_list, EnumDef, VariantData};
use rustc_ast::EnumDef;
use rustc_ast::VariantData;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt}; use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt};
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
@ -22,7 +20,7 @@ pub fn expand_deriving_default(
item.visit_with(&mut DetectNonVariantDefaultAttr { cx }); item.visit_with(&mut DetectNonVariantDefaultAttr { cx });
let inline = cx.meta_word(span, sym::inline); let inline = cx.meta_word(span, sym::inline);
let attrs = vec![cx.attribute(inline)]; let attrs = vec![cx.attribute(inline)].into();
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
path: Path::new(vec![kw::Default, sym::Default]), path: Path::new(vec![kw::Default, sym::Default]),

View file

@ -89,7 +89,7 @@ use crate::deriving::generic::ty::*;
use crate::deriving::generic::*; use crate::deriving::generic::*;
use crate::deriving::pathvec_std; use crate::deriving::pathvec_std;
use rustc_ast::{ExprKind, MetaItem, Mutability}; use rustc_ast::{AttrVec, ExprKind, MetaItem, Mutability};
use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span; use rustc_span::Span;
@ -131,7 +131,7 @@ pub fn expand_deriving_rustc_encodable(
], ],
PathKind::Std, PathKind::Std,
)), )),
attributes: Vec::new(), attributes: AttrVec::new(),
unify_fieldless_variants: false, unify_fieldless_variants: false,
combine_substructure: combine_substructure(Box::new(|a, b, c| { combine_substructure: combine_substructure(Box::new(|a, b, c| {
encodable_substructure(a, b, c, krate) encodable_substructure(a, b, c, krate)

View file

@ -217,7 +217,7 @@ pub struct MethodDef<'a> {
/// Returns type /// Returns type
pub ret_ty: Ty, pub ret_ty: Ty,
pub attributes: Vec<ast::Attribute>, pub attributes: ast::AttrVec,
/// Can we combine fieldless variants for enums into a single match arm? /// Can we combine fieldless variants for enums into a single match arm?
/// If true, indicates that the trait operation uses the enum tag in some /// If true, indicates that the trait operation uses the enum tag in some
@ -562,7 +562,7 @@ impl<'a> TraitDef<'a> {
kind: ast::VisibilityKind::Inherited, kind: ast::VisibilityKind::Inherited,
tokens: None, tokens: None,
}, },
attrs: Vec::new(), attrs: ast::AttrVec::new(),
kind: ast::AssocItemKind::TyAlias(Box::new(ast::TyAlias { kind: ast::AssocItemKind::TyAlias(Box::new(ast::TyAlias {
defaultness: ast::Defaultness::Final, defaultness: ast::Defaultness::Final,
generics: Generics::default(), generics: Generics::default(),
@ -716,7 +716,7 @@ impl<'a> TraitDef<'a> {
let self_type = cx.ty_path(path); let self_type = cx.ty_path(path);
let attr = cx.attribute(cx.meta_word(self.span, sym::automatically_derived)); let attr = cx.attribute(cx.meta_word(self.span, sym::automatically_derived));
let attrs = vec![attr]; let attrs = vec![attr].into();
let opt_trait_ref = Some(trait_ref); let opt_trait_ref = Some(trait_ref);
cx.item( cx.item(

View file

@ -2,7 +2,7 @@ use crate::deriving::generic::ty::*;
use crate::deriving::generic::*; use crate::deriving::generic::*;
use crate::deriving::{path_std, pathvec_std}; use crate::deriving::{path_std, pathvec_std};
use rustc_ast::{MetaItem, Mutability}; use rustc_ast::{AttrVec, MetaItem, Mutability};
use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::Span; use rustc_span::Span;
@ -31,7 +31,7 @@ pub fn expand_deriving_hash(
explicit_self: true, explicit_self: true,
nonself_args: vec![(Ref(Box::new(Path(arg)), Mutability::Mut), sym::state)], nonself_args: vec![(Ref(Box::new(Path(arg)), Mutability::Mut), sym::state)],
ret_ty: Unit, ret_ty: Unit,
attributes: vec![], attributes: AttrVec::new(),
unify_fieldless_variants: true, unify_fieldless_variants: true,
combine_substructure: combine_substructure(Box::new(|a, b, c| { combine_substructure: combine_substructure(Box::new(|a, b, c| {
hash_substructure(a, b, c) hash_substructure(a, b, c)

View file

@ -164,7 +164,7 @@ fn inject_impl_of_structural_trait(
// Keep the lint and stability attributes of the original item, to control // Keep the lint and stability attributes of the original item, to control
// how the generated implementation is linted. // how the generated implementation is linted.
let mut attrs = Vec::new(); let mut attrs = ast::AttrVec::new();
attrs.extend( attrs.extend(
item.attrs item.attrs
.iter() .iter()

View file

@ -4,7 +4,7 @@ use rustc_ast::expand::allocator::{
AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS, AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS,
}; };
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_ast::{self as ast, Attribute, Expr, FnHeader, FnSig, Generics, Param, StmtKind}; use rustc_ast::{self as ast, AttrVec, Expr, FnHeader, FnSig, Generics, Param, StmtKind};
use rustc_ast::{Fn, ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe}; use rustc_ast::{Fn, ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe};
use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
@ -113,10 +113,10 @@ impl AllocFnFactory<'_, '_> {
self.cx.expr_call(self.ty_span, method, args) self.cx.expr_call(self.ty_span, method, args)
} }
fn attrs(&self) -> Vec<Attribute> { fn attrs(&self) -> AttrVec {
let special = sym::rustc_std_internal_symbol; let special = sym::rustc_std_internal_symbol;
let special = self.cx.meta_word(self.span, special); let special = self.cx.meta_word(self.span, special);
vec![self.cx.attribute(special)] vec![self.cx.attribute(special)].into()
} }
fn arg_ty( fn arg_ty(

View file

@ -281,7 +281,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
let span = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id()); let span = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id());
let proc_macro = Ident::new(sym::proc_macro, span); let proc_macro = Ident::new(sym::proc_macro, span);
let krate = cx.item(span, proc_macro, Vec::new(), ast::ItemKind::ExternCrate(None)); let krate = cx.item(span, proc_macro, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None));
let bridge = Ident::new(sym::bridge, span); let bridge = Ident::new(sym::bridge, span);
let client = Ident::new(sym::client, span); let client = Ident::new(sym::client, span);

View file

@ -51,7 +51,7 @@ pub fn inject(
cx.item( cx.item(
span, span,
ident, ident,
vec![cx.attribute(cx.meta_word(span, sym::macro_use))], vec![cx.attribute(cx.meta_word(span, sym::macro_use))].into(),
ast::ItemKind::ExternCrate(None), ast::ItemKind::ExternCrate(None),
), ),
); );
@ -78,7 +78,7 @@ pub fn inject(
let use_item = cx.item( let use_item = cx.item(
span, span,
Ident::empty(), Ident::empty(),
vec![cx.attribute(cx.meta_word(span, sym::prelude_import))], vec![cx.attribute(cx.meta_word(span, sym::prelude_import))].into(),
ast::ItemKind::Use(ast::UseTree { ast::ItemKind::Use(ast::UseTree {
prefix: cx.path(span, import_path), prefix: cx.path(span, import_path),
kind: ast::UseTreeKind::Glob, kind: ast::UseTreeKind::Glob,

View file

@ -227,7 +227,8 @@ pub fn expand_test_or_bench(
)), )),
// #[rustc_test_marker] // #[rustc_test_marker]
cx.attribute(cx.meta_word(attr_sp, sym::rustc_test_marker)), cx.attribute(cx.meta_word(attr_sp, sym::rustc_test_marker)),
], ]
.into(),
// const $ident: test::TestDescAndFn = // const $ident: test::TestDescAndFn =
ast::ItemKind::Const( ast::ItemKind::Const(
ast::Defaultness::Final, ast::Defaultness::Final,
@ -334,7 +335,7 @@ pub fn expand_test_or_bench(
}); });
// extern crate test // extern crate test
let test_extern = cx.item(sp, test_id, vec![], ast::ItemKind::ExternCrate(None)); let test_extern = cx.item(sp, test_id, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None));
tracing::debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const)); tracing::debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const));

View file

@ -298,8 +298,10 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
let call_test_main = ecx.stmt_expr(call_test_main); let call_test_main = ecx.stmt_expr(call_test_main);
// extern crate test // extern crate test
let test_extern_stmt = let test_extern_stmt = ecx.stmt_item(
ecx.stmt_item(sp, ecx.item(sp, test_id, vec![], ast::ItemKind::ExternCrate(None))); sp,
ecx.item(sp, test_id, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None)),
);
// #[rustc_main] // #[rustc_main]
let main_meta = ecx.meta_word(sp, sym::rustc_main); let main_meta = ecx.meta_word(sp, sym::rustc_main);
@ -333,7 +335,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
let main = P(ast::Item { let main = P(ast::Item {
ident: main_id, ident: main_id,
attrs: vec![main_attr], attrs: vec![main_attr].into(),
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
kind: main, kind: main,
vis: ast::Visibility { span: sp, kind: ast::VisibilityKind::Public, tokens: None }, vis: ast::Visibility { span: sp, kind: ast::VisibilityKind::Public, tokens: None },

View file

@ -1,3 +1,4 @@
use crate::thin_vec::ThinVec;
use smallvec::{Array, SmallVec}; use smallvec::{Array, SmallVec};
use std::ptr; use std::ptr;
@ -15,94 +16,64 @@ pub trait MapInPlace<T>: Sized {
I: IntoIterator<Item = T>; I: IntoIterator<Item = T>;
} }
impl<T> MapInPlace<T> for Vec<T> { // The implementation of this method is syntactically identical for all the
fn flat_map_in_place<F, I>(&mut self, mut f: F) // different vector types.
where macro_rules! flat_map_in_place {
F: FnMut(T) -> I, () => {
I: IntoIterator<Item = T>, fn flat_map_in_place<F, I>(&mut self, mut f: F)
{ where
let mut read_i = 0; F: FnMut(T) -> I,
let mut write_i = 0; I: IntoIterator<Item = T>,
unsafe { {
let mut old_len = self.len(); let mut read_i = 0;
self.set_len(0); // make sure we just leak elements in case of panic let mut write_i = 0;
unsafe {
let mut old_len = self.len();
self.set_len(0); // make sure we just leak elements in case of panic
while read_i < old_len { while read_i < old_len {
// move the read_i'th item out of the vector and map it // move the read_i'th item out of the vector and map it
// to an iterator // to an iterator
let e = ptr::read(self.as_ptr().add(read_i)); let e = ptr::read(self.as_ptr().add(read_i));
let iter = f(e).into_iter(); let iter = f(e).into_iter();
read_i += 1; read_i += 1;
for e in iter { for e in iter {
if write_i < read_i { if write_i < read_i {
ptr::write(self.as_mut_ptr().add(write_i), e); ptr::write(self.as_mut_ptr().add(write_i), e);
write_i += 1; write_i += 1;
} else { } else {
// If this is reached we ran out of space // If this is reached we ran out of space
// in the middle of the vector. // in the middle of the vector.
// However, the vector is in a valid state here, // However, the vector is in a valid state here,
// so we just do a somewhat inefficient insert. // so we just do a somewhat inefficient insert.
self.set_len(old_len); self.set_len(old_len);
self.insert(write_i, e); self.insert(write_i, e);
old_len = self.len(); old_len = self.len();
self.set_len(0); self.set_len(0);
read_i += 1; read_i += 1;
write_i += 1; write_i += 1;
}
} }
} }
}
// write_i tracks the number of actually written new items. // write_i tracks the number of actually written new items.
self.set_len(write_i); self.set_len(write_i);
}
} }
} };
}
impl<T> MapInPlace<T> for Vec<T> {
flat_map_in_place!();
} }
impl<T, A: Array<Item = T>> MapInPlace<T> for SmallVec<A> { impl<T, A: Array<Item = T>> MapInPlace<T> for SmallVec<A> {
fn flat_map_in_place<F, I>(&mut self, mut f: F) flat_map_in_place!();
where }
F: FnMut(T) -> I,
I: IntoIterator<Item = T>, impl<T> MapInPlace<T> for ThinVec<T> {
{ flat_map_in_place!();
let mut read_i = 0;
let mut write_i = 0;
unsafe {
let mut old_len = self.len();
self.set_len(0); // make sure we just leak elements in case of panic
while read_i < old_len {
// move the read_i'th item out of the vector and map it
// to an iterator
let e = ptr::read(self.as_ptr().add(read_i));
let iter = f(e).into_iter();
read_i += 1;
for e in iter {
if write_i < read_i {
ptr::write(self.as_mut_ptr().add(write_i), e);
write_i += 1;
} else {
// If this is reached we ran out of space
// in the middle of the vector.
// However, the vector is in a valid state here,
// so we just do a somewhat inefficient insert.
self.set_len(old_len);
self.insert(write_i, e);
old_len = self.len();
self.set_len(0);
read_i += 1;
write_i += 1;
}
}
}
// write_i tracks the number of actually written new items.
self.set_len(write_i);
}
}
} }

View file

@ -27,6 +27,51 @@ impl<T> ThinVec<T> {
ThinVec(None) => *self = vec![item].into(), ThinVec(None) => *self = vec![item].into(),
} }
} }
/// Note: if `set_len(0)` is called on a non-empty `ThinVec`, it will
/// remain in the `Some` form. This is required for some code sequences
/// (such as the one in `flat_map_in_place`) that call `set_len(0)` before
/// an operation that might panic, and then call `set_len(n)` again
/// afterwards.
pub unsafe fn set_len(&mut self, new_len: usize) {
match *self {
ThinVec(None) => {
// A prerequisite of `Vec::set_len` is that `new_len` must be
// less than or equal to capacity(). The same applies here.
if new_len != 0 {
panic!("unsafe ThinVec::set_len({})", new_len);
}
}
ThinVec(Some(ref mut vec)) => vec.set_len(new_len),
}
}
pub fn insert(&mut self, index: usize, value: T) {
match *self {
ThinVec(None) => {
if index == 0 {
*self = vec![value].into();
} else {
panic!("invalid ThinVec::insert");
}
}
ThinVec(Some(ref mut vec)) => vec.insert(index, value),
}
}
pub fn remove(&mut self, index: usize) -> T {
match self {
ThinVec(None) => panic!("invalid ThinVec::remove"),
ThinVec(Some(vec)) => vec.remove(index),
}
}
pub fn as_slice(&self) -> &[T] {
match self {
ThinVec(None) => &[],
ThinVec(Some(vec)) => vec.as_slice(),
}
}
} }
impl<T> From<Vec<T>> for ThinVec<T> { impl<T> From<Vec<T>> for ThinVec<T> {

View file

@ -1070,7 +1070,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
Some(matches) Some(matches)
} }
fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, Vec<ast::Attribute>> { fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::AttrVec> {
match input { match input {
Input::File(ifile) => rustc_parse::parse_crate_attrs_from_file(ifile, &sess.parse_sess), Input::File(ifile) => rustc_parse::parse_crate_attrs_from_file(ifile, &sess.parse_sess),
Input::Str { name, input } => rustc_parse::parse_crate_attrs_from_source_str( Input::Str { name, input } => rustc_parse::parse_crate_attrs_from_source_str(

View file

@ -6,7 +6,7 @@ use rustc_ast::ptr::P;
use rustc_ast::token::{self, Nonterminal}; use rustc_ast::token::{self, Nonterminal};
use rustc_ast::tokenstream::TokenStream; use rustc_ast::tokenstream::TokenStream;
use rustc_ast::visit::{AssocCtxt, Visitor}; use rustc_ast::visit::{AssocCtxt, Visitor};
use rustc_ast::{self as ast, Attribute, HasAttrs, Item, NodeId, PatKind}; use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind};
use rustc_attr::{self as attr, Deprecation, Stability}; use rustc_attr::{self as attr, Deprecation, Stability};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_data_structures::sync::{self, Lrc}; use rustc_data_structures::sync::{self, Lrc};
@ -71,7 +71,7 @@ impl Annotatable {
} }
} }
pub fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) { pub fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
match self { match self {
Annotatable::Item(item) => item.visit_attrs(f), Annotatable::Item(item) => item.visit_attrs(f),
Annotatable::TraitItem(trait_item) => trait_item.visit_attrs(f), Annotatable::TraitItem(trait_item) => trait_item.visit_attrs(f),

View file

@ -575,7 +575,7 @@ impl<'a> ExtCtxt<'a> {
&self, &self,
span: Span, span: Span,
name: Ident, name: Ident,
attrs: Vec<ast::Attribute>, attrs: ast::AttrVec,
kind: ast::ItemKind, kind: ast::ItemKind,
) -> P<ast::Item> { ) -> P<ast::Item> {
// FIXME: Would be nice if our generated code didn't violate // FIXME: Would be nice if our generated code didn't violate
@ -603,7 +603,7 @@ impl<'a> ExtCtxt<'a> {
mutbl: ast::Mutability, mutbl: ast::Mutability,
expr: P<ast::Expr>, expr: P<ast::Expr>,
) -> P<ast::Item> { ) -> P<ast::Item> {
self.item(span, name, Vec::new(), ast::ItemKind::Static(ty, mutbl, Some(expr))) self.item(span, name, AttrVec::new(), ast::ItemKind::Static(ty, mutbl, Some(expr)))
} }
pub fn item_const( pub fn item_const(
@ -614,7 +614,7 @@ impl<'a> ExtCtxt<'a> {
expr: P<ast::Expr>, expr: P<ast::Expr>,
) -> P<ast::Item> { ) -> P<ast::Item> {
let def = ast::Defaultness::Final; let def = ast::Defaultness::Final;
self.item(span, name, Vec::new(), ast::ItemKind::Const(def, ty, Some(expr))) self.item(span, name, AttrVec::new(), ast::ItemKind::Const(def, ty, Some(expr)))
} }
pub fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute { pub fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute {

View file

@ -215,7 +215,7 @@ pub fn features(
let features = match strip_unconfigured.configure_krate_attrs(krate.attrs) { let features = match strip_unconfigured.configure_krate_attrs(krate.attrs) {
None => { None => {
// The entire crate is unconfigured. // The entire crate is unconfigured.
krate.attrs = Vec::new(); krate.attrs = ast::AttrVec::new();
krate.items = Vec::new(); krate.items = Vec::new();
Features::default() Features::default()
} }
@ -265,7 +265,7 @@ impl<'a> StripUnconfigured<'a> {
} }
} }
fn configure_krate_attrs(&self, mut attrs: Vec<ast::Attribute>) -> Option<Vec<ast::Attribute>> { fn configure_krate_attrs(&self, mut attrs: ast::AttrVec) -> Option<ast::AttrVec> {
attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr)); attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
if self.in_cfg(&attrs) { Some(attrs) } else { None } if self.in_cfg(&attrs) { Some(attrs) } else { None }
} }
@ -292,9 +292,7 @@ impl<'a> StripUnconfigured<'a> {
.iter() .iter()
.flat_map(|(tree, spacing)| match tree.clone() { .flat_map(|(tree, spacing)| match tree.clone() {
AttrAnnotatedTokenTree::Attributes(mut data) => { AttrAnnotatedTokenTree::Attributes(mut data) => {
let mut attrs: Vec<_> = std::mem::take(&mut data.attrs).into(); data.attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
data.attrs = attrs.into();
if self.in_cfg(&data.attrs) { if self.in_cfg(&data.attrs) {
data.tokens = LazyTokenStream::new( data.tokens = LazyTokenStream::new(

View file

@ -11,7 +11,7 @@ use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter}; use rustc_ast::token::{self, Delimiter};
use rustc_ast::tokenstream::TokenStream; use rustc_ast::tokenstream::TokenStream;
use rustc_ast::visit::{self, AssocCtxt, Visitor}; use rustc_ast::visit::{self, AssocCtxt, Visitor};
use rustc_ast::{AssocItemKind, AstNodeWrapper, AttrStyle, ExprKind, ForeignItemKind}; use rustc_ast::{AssocItemKind, AstNodeWrapper, AttrStyle, AttrVec, ExprKind, ForeignItemKind};
use rustc_ast::{HasAttrs, HasNodeId}; use rustc_ast::{HasAttrs, HasNodeId};
use rustc_ast::{Inline, ItemKind, MacArgs, MacStmtStyle, MetaItemKind, ModKind}; use rustc_ast::{Inline, ItemKind, MacArgs, MacStmtStyle, MetaItemKind, ModKind};
use rustc_ast::{NestedMetaItem, NodeId, PatKind, StmtKind, TyKind}; use rustc_ast::{NestedMetaItem, NodeId, PatKind, StmtKind, TyKind};
@ -1001,7 +1001,7 @@ enum AddSemicolon {
/// of functionality used by `InvocationCollector`. /// of functionality used by `InvocationCollector`.
trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized { trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized {
type OutputTy = SmallVec<[Self; 1]>; type OutputTy = SmallVec<[Self; 1]>;
type AttrsTy: Deref<Target = [ast::Attribute]> = Vec<ast::Attribute>; type AttrsTy: Deref<Target = [ast::Attribute]> = ast::AttrVec;
const KIND: AstFragmentKind; const KIND: AstFragmentKind;
fn to_annotatable(self) -> Annotatable; fn to_annotatable(self) -> Annotatable;
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy; fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy;
@ -1333,7 +1333,7 @@ impl InvocationCollectorNode for ast::Stmt {
} }
StmtKind::Item(item) => match item.into_inner() { StmtKind::Item(item) => match item.into_inner() {
ast::Item { kind: ItemKind::MacCall(mac), attrs, .. } => { ast::Item { kind: ItemKind::MacCall(mac), attrs, .. } => {
(mac.args.need_semicolon(), mac, attrs.into()) (mac.args.need_semicolon(), mac, attrs)
} }
_ => unreachable!(), _ => unreachable!(),
}, },
@ -1390,7 +1390,7 @@ impl InvocationCollectorNode for P<ast::Ty> {
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) { fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
let node = self.into_inner(); let node = self.into_inner();
match node.kind { match node.kind {
TyKind::MacCall(mac) => (mac, Vec::new(), AddSemicolon::No), TyKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No),
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -1414,7 +1414,7 @@ impl InvocationCollectorNode for P<ast::Pat> {
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) { fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
let node = self.into_inner(); let node = self.into_inner();
match node.kind { match node.kind {
PatKind::MacCall(mac) => (mac, Vec::new(), AddSemicolon::No), PatKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No),
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -1646,7 +1646,11 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
fn expand_cfg_attr(&self, node: &mut impl HasAttrs, attr: ast::Attribute, pos: usize) { fn expand_cfg_attr(&self, node: &mut impl HasAttrs, attr: ast::Attribute, pos: usize) {
node.visit_attrs(|attrs| { node.visit_attrs(|attrs| {
attrs.splice(pos..pos, self.cfg().expand_cfg_attr(attr, false)); // Repeated `insert` calls is inefficient, but the number of
// insertions is almost always 0 or 1 in practice.
for cfg in self.cfg().expand_cfg_attr(attr, false).into_iter().rev() {
attrs.insert(pos, cfg)
}
}); });
} }

View file

@ -1,6 +1,6 @@
use crate::base::ModuleData; use crate::base::ModuleData;
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_ast::{token, Attribute, Inline, Item, ModSpans}; use rustc_ast::{token, AttrVec, Attribute, Inline, Item, ModSpans};
use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorGuaranteed}; use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorGuaranteed};
use rustc_parse::new_parser_from_file; use rustc_parse::new_parser_from_file;
use rustc_parse::validate_attr; use rustc_parse::validate_attr;
@ -48,7 +48,7 @@ pub(crate) fn parse_external_mod(
span: Span, // The span to blame on errors. span: Span, // The span to blame on errors.
module: &ModuleData, module: &ModuleData,
mut dir_ownership: DirOwnership, mut dir_ownership: DirOwnership,
attrs: &mut Vec<Attribute>, attrs: &mut AttrVec,
) -> ParsedExternalMod { ) -> ParsedExternalMod {
// We bail on the first error, but that error does not cause a fatal error... (1) // We bail on the first error, but that error does not cause a fatal error... (1)
let result: Result<_, ModError<'_>> = try { let result: Result<_, ModError<'_>> = try {
@ -63,9 +63,9 @@ pub(crate) fn parse_external_mod(
// Actually parse the external file as a module. // Actually parse the external file as a module.
let mut parser = new_parser_from_file(&sess.parse_sess, &mp.file_path, Some(span)); let mut parser = new_parser_from_file(&sess.parse_sess, &mp.file_path, Some(span));
let (mut inner_attrs, items, inner_span) = let (inner_attrs, items, inner_span) =
parser.parse_mod(&token::Eof).map_err(|err| ModError::ParserError(err))?; parser.parse_mod(&token::Eof).map_err(|err| ModError::ParserError(err))?;
attrs.append(&mut inner_attrs); attrs.extend(inner_attrs);
(items, inner_span, mp.file_path) (items, inner_span, mp.file_path)
}; };
// (1) ...instead, we return a dummy module. // (1) ...instead, we return a dummy module.

View file

@ -24,7 +24,7 @@ pub fn placeholder(
} }
let ident = Ident::empty(); let ident = Ident::empty();
let attrs = Vec::new(); let attrs = ast::AttrVec::new();
let vis = vis.unwrap_or(ast::Visibility { let vis = vis.unwrap_or(ast::Visibility {
span: DUMMY_SP, span: DUMMY_SP,
kind: ast::VisibilityKind::Inherited, kind: ast::VisibilityKind::Inherited,

View file

@ -62,7 +62,7 @@ pub fn parse_crate_from_file<'a>(input: &Path, sess: &'a ParseSess) -> PResult<'
pub fn parse_crate_attrs_from_file<'a>( pub fn parse_crate_attrs_from_file<'a>(
input: &Path, input: &Path,
sess: &'a ParseSess, sess: &'a ParseSess,
) -> PResult<'a, Vec<ast::Attribute>> { ) -> PResult<'a, ast::AttrVec> {
let mut parser = new_parser_from_file(sess, input, None); let mut parser = new_parser_from_file(sess, input, None);
parser.parse_inner_attributes() parser.parse_inner_attributes()
} }
@ -79,7 +79,7 @@ pub fn parse_crate_attrs_from_source_str(
name: FileName, name: FileName,
source: String, source: String,
sess: &ParseSess, sess: &ParseSess,
) -> PResult<'_, Vec<ast::Attribute>> { ) -> PResult<'_, ast::AttrVec> {
new_parser_from_source_str(sess, name, source).parse_inner_attributes() new_parser_from_source_str(sess, name, source).parse_inner_attributes()
} }

View file

@ -34,7 +34,7 @@ enum OuterAttributeType {
impl<'a> Parser<'a> { impl<'a> Parser<'a> {
/// Parses attributes that appear before an item. /// Parses attributes that appear before an item.
pub(super) fn parse_outer_attributes(&mut self) -> PResult<'a, AttrWrapper> { pub(super) fn parse_outer_attributes(&mut self) -> PResult<'a, AttrWrapper> {
let mut outer_attrs: Vec<ast::Attribute> = Vec::new(); let mut outer_attrs = ast::AttrVec::new();
let mut just_parsed_doc_comment = false; let mut just_parsed_doc_comment = false;
let start_pos = self.token_cursor.num_next_calls; let start_pos = self.token_cursor.num_next_calls;
loop { loop {
@ -106,7 +106,7 @@ impl<'a> Parser<'a> {
break; break;
} }
} }
Ok(AttrWrapper::new(outer_attrs.into(), start_pos)) Ok(AttrWrapper::new(outer_attrs, start_pos))
} }
/// Matches `attribute = # ! [ meta_item ]`. /// Matches `attribute = # ! [ meta_item ]`.
@ -283,8 +283,8 @@ impl<'a> Parser<'a> {
/// terminated by a semicolon. /// terminated by a semicolon.
/// ///
/// Matches `inner_attrs*`. /// Matches `inner_attrs*`.
pub(crate) fn parse_inner_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> { pub(crate) fn parse_inner_attributes(&mut self) -> PResult<'a, ast::AttrVec> {
let mut attrs: Vec<ast::Attribute> = vec![]; let mut attrs = ast::AttrVec::new();
loop { loop {
let start_pos: u32 = self.token_cursor.num_next_calls.try_into().unwrap(); let start_pos: u32 = self.token_cursor.num_next_calls.try_into().unwrap();
// Only try to parse if it is an inner attribute (has `!`). // Only try to parse if it is an inner attribute (has `!`).

View file

@ -15,11 +15,11 @@ use std::ops::Range;
/// for the attribute target. This allows us to perform cfg-expansion on /// for the attribute target. This allows us to perform cfg-expansion on
/// a token stream before we invoke a derive proc-macro. /// a token stream before we invoke a derive proc-macro.
/// ///
/// This wrapper prevents direct access to the underlying `Vec<ast::Attribute>`. /// This wrapper prevents direct access to the underlying `ast::AttrVec>`.
/// Parsing code can only get access to the underlying attributes /// Parsing code can only get access to the underlying attributes
/// by passing an `AttrWrapper` to `collect_tokens_trailing_tokens`. /// by passing an `AttrWrapper` to `collect_tokens_trailing_tokens`.
/// This makes it difficult to accidentally construct an AST node /// This makes it difficult to accidentally construct an AST node
/// (which stores a `Vec<ast::Attribute>`) without first collecting tokens. /// (which stores an `ast::AttrVec`) without first collecting tokens.
/// ///
/// This struct has its own module, to ensure that the parser code /// This struct has its own module, to ensure that the parser code
/// cannot directly access the `attrs` field /// cannot directly access the `attrs` field
@ -49,9 +49,10 @@ impl AttrWrapper {
self.attrs self.attrs
} }
// Prepend `self.attrs` to `attrs`.
// FIXME: require passing an NT to prevent misuse of this method // FIXME: require passing an NT to prevent misuse of this method
pub(crate) fn prepend_to_nt_inner(self, attrs: &mut Vec<Attribute>) { pub(crate) fn prepend_to_nt_inner(self, attrs: &mut AttrVec) {
let mut self_attrs: Vec<_> = self.attrs.into(); let mut self_attrs = self.attrs.clone();
std::mem::swap(attrs, &mut self_attrs); std::mem::swap(attrs, &mut self_attrs);
attrs.extend(self_attrs); attrs.extend(self_attrs);
} }
@ -196,7 +197,7 @@ impl<'a> Parser<'a> {
&mut self, &mut self,
attrs: AttrWrapper, attrs: AttrWrapper,
force_collect: ForceCollect, force_collect: ForceCollect,
f: impl FnOnce(&mut Self, Vec<ast::Attribute>) -> PResult<'a, (R, TrailingToken)>, f: impl FnOnce(&mut Self, ast::AttrVec) -> PResult<'a, (R, TrailingToken)>,
) -> PResult<'a, R> { ) -> PResult<'a, R> {
// We only bail out when nothing could possibly observe the collected tokens: // We only bail out when nothing could possibly observe the collected tokens:
// 1. We cannot be force collecting tokens (since force-collecting requires tokens // 1. We cannot be force collecting tokens (since force-collecting requires tokens
@ -212,7 +213,7 @@ impl<'a> Parser<'a> {
// or `#[cfg_attr]` attributes. // or `#[cfg_attr]` attributes.
&& !self.capture_cfg && !self.capture_cfg
{ {
return Ok(f(self, attrs.attrs.into())?.0); return Ok(f(self, attrs.attrs)?.0);
} }
let start_token = (self.token.clone(), self.token_spacing); let start_token = (self.token.clone(), self.token_spacing);
@ -222,7 +223,7 @@ impl<'a> Parser<'a> {
let prev_capturing = std::mem::replace(&mut self.capture_state.capturing, Capturing::Yes); let prev_capturing = std::mem::replace(&mut self.capture_state.capturing, Capturing::Yes);
let replace_ranges_start = self.capture_state.replace_ranges.len(); let replace_ranges_start = self.capture_state.replace_ranges.len();
let ret = f(self, attrs.attrs.into()); let ret = f(self, attrs.attrs);
self.capture_state.capturing = prev_capturing; self.capture_state.capturing = prev_capturing;
@ -352,7 +353,7 @@ impl<'a> Parser<'a> {
// on the captured token stream. // on the captured token stream.
if self.capture_cfg if self.capture_cfg
&& matches!(self.capture_state.capturing, Capturing::Yes) && matches!(self.capture_state.capturing, Capturing::Yes)
&& has_cfg_or_cfg_attr(&final_attrs) && has_cfg_or_cfg_attr(final_attrs)
{ {
let attr_data = AttributesData { attrs: final_attrs.to_vec().into(), tokens }; let attr_data = AttributesData { attrs: final_attrs.to_vec().into(), tokens };

View file

@ -2370,7 +2370,7 @@ impl<'a> Parser<'a> {
fn recover_const_param_decl(&mut self, ty_generics: Option<&Generics>) -> Option<GenericArg> { fn recover_const_param_decl(&mut self, ty_generics: Option<&Generics>) -> Option<GenericArg> {
let snapshot = self.create_snapshot_for_diagnostic(); let snapshot = self.create_snapshot_for_diagnostic();
let param = match self.parse_const_param(vec![]) { let param = match self.parse_const_param(AttrVec::new()) {
Ok(param) => param, Ok(param) => param,
Err(err) => { Err(err) => {
err.cancel(); err.cancel();

View file

@ -950,15 +950,15 @@ impl<'a> Parser<'a> {
&mut self, &mut self,
e0: P<Expr>, e0: P<Expr>,
lo: Span, lo: Span,
mut attrs: Vec<ast::Attribute>, mut attrs: ast::AttrVec,
) -> PResult<'a, P<Expr>> { ) -> PResult<'a, P<Expr>> {
// Stitch the list of outer attributes onto the return value. // Stitch the list of outer attributes onto the return value.
// A little bit ugly, but the best way given the current code // A little bit ugly, but the best way given the current code
// structure // structure
self.parse_dot_or_call_expr_with_(e0, lo).map(|expr| { self.parse_dot_or_call_expr_with_(e0, lo).map(|expr| {
expr.map(|mut expr| { expr.map(|mut expr| {
attrs.extend::<Vec<_>>(expr.attrs.into()); attrs.extend(expr.attrs);
expr.attrs = attrs.into(); expr.attrs = attrs;
expr expr
}) })
}) })
@ -2224,7 +2224,7 @@ impl<'a> Parser<'a> {
Ok(( Ok((
Param { Param {
attrs: attrs.into(), attrs,
ty, ty,
pat, pat,
span: lo.to(this.prev_token.span), span: lo.to(this.prev_token.span),
@ -2732,7 +2732,7 @@ impl<'a> Parser<'a> {
let span = body.span; let span = body.span;
return Ok(( return Ok((
ast::Arm { ast::Arm {
attrs: attrs.into(), attrs,
pat, pat,
guard, guard,
body, body,
@ -2810,7 +2810,7 @@ impl<'a> Parser<'a> {
Ok(( Ok((
ast::Arm { ast::Arm {
attrs: attrs.into(), attrs,
pat, pat,
guard, guard,
body: expr, body: expr,
@ -3123,7 +3123,7 @@ impl<'a> Parser<'a> {
span: lo.to(expr.span), span: lo.to(expr.span),
expr, expr,
is_shorthand, is_shorthand,
attrs: attrs.into(), attrs,
id: DUMMY_NODE_ID, id: DUMMY_NODE_ID,
is_placeholder: false, is_placeholder: false,
}, },
@ -3219,14 +3219,10 @@ impl<'a> Parser<'a> {
await_expr await_expr
} }
pub(crate) fn mk_expr_with_attrs<A>(&self, span: Span, kind: ExprKind, attrs: A) -> P<Expr> pub(crate) fn mk_expr_with_attrs(&self, span: Span, kind: ExprKind, attrs: AttrVec) -> P<Expr> {
where P(Expr { kind, span, attrs, id: DUMMY_NODE_ID, tokens: None })
A: Into<AttrVec>,
{
P(Expr { kind, span, attrs: attrs.into(), id: DUMMY_NODE_ID, tokens: None })
} }
// njn: rename
pub(crate) fn mk_expr(&self, span: Span, kind: ExprKind) -> P<Expr> { pub(crate) fn mk_expr(&self, span: Span, kind: ExprKind) -> P<Expr> {
P(Expr { kind, span, attrs: AttrVec::new(), id: DUMMY_NODE_ID, tokens: None }) P(Expr { kind, span, attrs: AttrVec::new(), id: DUMMY_NODE_ID, tokens: None })
} }
@ -3248,7 +3244,7 @@ impl<'a> Parser<'a> {
fn collect_tokens_for_expr( fn collect_tokens_for_expr(
&mut self, &mut self,
attrs: AttrWrapper, attrs: AttrWrapper,
f: impl FnOnce(&mut Self, Vec<ast::Attribute>) -> PResult<'a, P<Expr>>, f: impl FnOnce(&mut Self, ast::AttrVec) -> PResult<'a, P<Expr>>,
) -> PResult<'a, P<Expr>> { ) -> PResult<'a, P<Expr>> {
self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
let res = f(this, attrs)?; let res = f(this, attrs)?;

View file

@ -1,9 +1,7 @@
use super::{ForceCollect, Parser, TrailingToken}; use super::{ForceCollect, Parser, TrailingToken};
use rustc_ast::token; use rustc_ast::token;
use rustc_ast::{ use rustc_ast::{self as ast, AttrVec, GenericBounds, GenericParam, GenericParamKind, WhereClause};
self as ast, Attribute, GenericBounds, GenericParam, GenericParamKind, WhereClause,
};
use rustc_errors::{Applicability, PResult}; use rustc_errors::{Applicability, PResult};
use rustc_span::symbol::kw; use rustc_span::symbol::kw;
@ -26,7 +24,7 @@ impl<'a> Parser<'a> {
} }
/// Matches `typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?`. /// Matches `typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?`.
fn parse_ty_param(&mut self, preceding_attrs: Vec<Attribute>) -> PResult<'a, GenericParam> { fn parse_ty_param(&mut self, preceding_attrs: AttrVec) -> PResult<'a, GenericParam> {
let ident = self.parse_ident()?; let ident = self.parse_ident()?;
// Parse optional colon and param bounds. // Parse optional colon and param bounds.
@ -43,7 +41,7 @@ impl<'a> Parser<'a> {
Ok(GenericParam { Ok(GenericParam {
ident, ident,
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
attrs: preceding_attrs.into(), attrs: preceding_attrs,
bounds, bounds,
kind: GenericParamKind::Type { default }, kind: GenericParamKind::Type { default },
is_placeholder: false, is_placeholder: false,
@ -53,7 +51,7 @@ impl<'a> Parser<'a> {
pub(crate) fn parse_const_param( pub(crate) fn parse_const_param(
&mut self, &mut self,
preceding_attrs: Vec<Attribute>, preceding_attrs: AttrVec,
) -> PResult<'a, GenericParam> { ) -> PResult<'a, GenericParam> {
let const_span = self.token.span; let const_span = self.token.span;
@ -68,7 +66,7 @@ impl<'a> Parser<'a> {
Ok(GenericParam { Ok(GenericParam {
ident, ident,
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
attrs: preceding_attrs.into(), attrs: preceding_attrs,
bounds: Vec::new(), bounds: Vec::new(),
kind: GenericParamKind::Const { ty, kw_span: const_span, default }, kind: GenericParamKind::Const { ty, kw_span: const_span, default },
is_placeholder: false, is_placeholder: false,
@ -109,7 +107,7 @@ impl<'a> Parser<'a> {
Some(ast::GenericParam { Some(ast::GenericParam {
ident: lifetime.ident, ident: lifetime.ident,
id: lifetime.id, id: lifetime.id,
attrs: attrs.into(), attrs,
bounds, bounds,
kind: ast::GenericParamKind::Lifetime, kind: ast::GenericParamKind::Lifetime,
is_placeholder: false, is_placeholder: false,

View file

@ -32,7 +32,7 @@ impl<'a> Parser<'a> {
} }
/// Parses a `mod <foo> { ... }` or `mod <foo>;` item. /// Parses a `mod <foo> { ... }` or `mod <foo>;` item.
fn parse_item_mod(&mut self, attrs: &mut Vec<Attribute>) -> PResult<'a, ItemInfo> { fn parse_item_mod(&mut self, attrs: &mut AttrVec) -> PResult<'a, ItemInfo> {
let unsafety = self.parse_unsafety(); let unsafety = self.parse_unsafety();
self.expect_keyword(kw::Mod)?; self.expect_keyword(kw::Mod)?;
let id = self.parse_ident()?; let id = self.parse_ident()?;
@ -40,9 +40,9 @@ impl<'a> Parser<'a> {
ModKind::Unloaded ModKind::Unloaded
} else { } else {
self.expect(&token::OpenDelim(Delimiter::Brace))?; self.expect(&token::OpenDelim(Delimiter::Brace))?;
let (mut inner_attrs, items, inner_span) = let (inner_attrs, items, inner_span) =
self.parse_mod(&token::CloseDelim(Delimiter::Brace))?; self.parse_mod(&token::CloseDelim(Delimiter::Brace))?;
attrs.append(&mut inner_attrs); attrs.extend(inner_attrs);
ModKind::Loaded(items, Inline::Yes, inner_span) ModKind::Loaded(items, Inline::Yes, inner_span)
}; };
Ok((id, ItemKind::Mod(unsafety, mod_kind))) Ok((id, ItemKind::Mod(unsafety, mod_kind)))
@ -52,7 +52,7 @@ impl<'a> Parser<'a> {
pub fn parse_mod( pub fn parse_mod(
&mut self, &mut self,
term: &TokenKind, term: &TokenKind,
) -> PResult<'a, (Vec<Attribute>, Vec<P<Item>>, ModSpans)> { ) -> PResult<'a, (AttrVec, Vec<P<Item>>, ModSpans)> {
let lo = self.token.span; let lo = self.token.span;
let attrs = self.parse_inner_attributes()?; let attrs = self.parse_inner_attributes()?;
@ -134,7 +134,7 @@ impl<'a> Parser<'a> {
fn parse_item_common_( fn parse_item_common_(
&mut self, &mut self,
mut attrs: Vec<Attribute>, mut attrs: AttrVec,
mac_allowed: bool, mac_allowed: bool,
attrs_allowed: bool, attrs_allowed: bool,
fn_parse_mode: FnParseMode, fn_parse_mode: FnParseMode,
@ -198,7 +198,7 @@ impl<'a> Parser<'a> {
/// Parses one of the items allowed by the flags. /// Parses one of the items allowed by the flags.
fn parse_item_kind( fn parse_item_kind(
&mut self, &mut self,
attrs: &mut Vec<Attribute>, attrs: &mut AttrVec,
macros_allowed: bool, macros_allowed: bool,
lo: Span, lo: Span,
vis: &Visibility, vis: &Visibility,
@ -534,7 +534,7 @@ impl<'a> Parser<'a> {
/// ``` /// ```
fn parse_item_impl( fn parse_item_impl(
&mut self, &mut self,
attrs: &mut Vec<Attribute>, attrs: &mut AttrVec,
defaultness: Defaultness, defaultness: Defaultness,
) -> PResult<'a, ItemInfo> { ) -> PResult<'a, ItemInfo> {
let unsafety = self.parse_unsafety(); let unsafety = self.parse_unsafety();
@ -661,12 +661,12 @@ impl<'a> Parser<'a> {
fn parse_item_list<T>( fn parse_item_list<T>(
&mut self, &mut self,
attrs: &mut Vec<Attribute>, attrs: &mut AttrVec,
mut parse_item: impl FnMut(&mut Parser<'a>) -> PResult<'a, Option<Option<T>>>, mut parse_item: impl FnMut(&mut Parser<'a>) -> PResult<'a, Option<Option<T>>>,
) -> PResult<'a, Vec<T>> { ) -> PResult<'a, Vec<T>> {
let open_brace_span = self.token.span; let open_brace_span = self.token.span;
self.expect(&token::OpenDelim(Delimiter::Brace))?; self.expect(&token::OpenDelim(Delimiter::Brace))?;
attrs.append(&mut self.parse_inner_attributes()?); attrs.extend(self.parse_inner_attributes()?);
let mut items = Vec::new(); let mut items = Vec::new();
while !self.eat(&token::CloseDelim(Delimiter::Brace)) { while !self.eat(&token::CloseDelim(Delimiter::Brace)) {
@ -775,7 +775,7 @@ impl<'a> Parser<'a> {
} }
/// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`. /// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`.
fn parse_item_trait(&mut self, attrs: &mut Vec<Attribute>, lo: Span) -> PResult<'a, ItemInfo> { fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemInfo> {
let unsafety = self.parse_unsafety(); let unsafety = self.parse_unsafety();
// Parse optional `auto` prefix. // Parse optional `auto` prefix.
let is_auto = if self.eat_keyword(kw::Auto) { IsAuto::Yes } else { IsAuto::No }; let is_auto = if self.eat_keyword(kw::Auto) { IsAuto::Yes } else { IsAuto::No };
@ -1061,7 +1061,7 @@ impl<'a> Parser<'a> {
/// ``` /// ```
fn parse_item_foreign_mod( fn parse_item_foreign_mod(
&mut self, &mut self,
attrs: &mut Vec<Attribute>, attrs: &mut AttrVec,
mut unsafety: Unsafe, mut unsafety: Unsafe,
) -> PResult<'a, ItemInfo> { ) -> PResult<'a, ItemInfo> {
let abi = self.parse_abi(); // ABI? let abi = self.parse_abi(); // ABI?
@ -1179,7 +1179,7 @@ impl<'a> Parser<'a> {
fn recover_const_impl( fn recover_const_impl(
&mut self, &mut self,
const_span: Span, const_span: Span,
attrs: &mut Vec<Attribute>, attrs: &mut AttrVec,
defaultness: Defaultness, defaultness: Defaultness,
) -> PResult<'a, ItemInfo> { ) -> PResult<'a, ItemInfo> {
let impl_span = self.token.span; let impl_span = self.token.span;
@ -1337,7 +1337,7 @@ impl<'a> Parser<'a> {
ident, ident,
vis, vis,
id: DUMMY_NODE_ID, id: DUMMY_NODE_ID,
attrs: variant_attrs.into(), attrs: variant_attrs,
data: struct_def, data: struct_def,
disr_expr, disr_expr,
span: vlo.to(this.prev_token.span), span: vlo.to(this.prev_token.span),
@ -1494,7 +1494,7 @@ impl<'a> Parser<'a> {
ident: None, ident: None,
id: DUMMY_NODE_ID, id: DUMMY_NODE_ID,
ty, ty,
attrs: attrs.into(), attrs,
is_placeholder: false, is_placeholder: false,
}, },
TrailingToken::MaybeComma, TrailingToken::MaybeComma,
@ -1520,7 +1520,7 @@ impl<'a> Parser<'a> {
adt_ty: &str, adt_ty: &str,
lo: Span, lo: Span,
vis: Visibility, vis: Visibility,
attrs: Vec<Attribute>, attrs: AttrVec,
) -> PResult<'a, FieldDef> { ) -> PResult<'a, FieldDef> {
let mut seen_comma: bool = false; let mut seen_comma: bool = false;
let a_var = self.parse_name_and_ty(adt_ty, lo, vis, attrs)?; let a_var = self.parse_name_and_ty(adt_ty, lo, vis, attrs)?;
@ -1650,7 +1650,7 @@ impl<'a> Parser<'a> {
adt_ty: &str, adt_ty: &str,
lo: Span, lo: Span,
vis: Visibility, vis: Visibility,
attrs: Vec<Attribute>, attrs: AttrVec,
) -> PResult<'a, FieldDef> { ) -> PResult<'a, FieldDef> {
let name = self.parse_field_ident(adt_ty, lo)?; let name = self.parse_field_ident(adt_ty, lo)?;
self.expect_field_ty_separator()?; self.expect_field_ty_separator()?;
@ -1684,7 +1684,7 @@ impl<'a> Parser<'a> {
vis, vis,
id: DUMMY_NODE_ID, id: DUMMY_NODE_ID,
ty, ty,
attrs: attrs.into(), attrs,
is_placeholder: false, is_placeholder: false,
}) })
} }
@ -1703,7 +1703,7 @@ impl<'a> Parser<'a> {
// We use `parse_fn` to get a span for the function // We use `parse_fn` to get a span for the function
let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true }; let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true };
if let Err(mut db) = if let Err(mut db) =
self.parse_fn(&mut Vec::new(), fn_parse_mode, lo, &inherited_vis) self.parse_fn(&mut AttrVec::new(), fn_parse_mode, lo, &inherited_vis)
{ {
db.delay_as_bug(); db.delay_as_bug();
} }
@ -1979,7 +1979,7 @@ impl<'a> Parser<'a> {
/// Parse a function starting from the front matter (`const ...`) to the body `{ ... }` or `;`. /// Parse a function starting from the front matter (`const ...`) to the body `{ ... }` or `;`.
fn parse_fn( fn parse_fn(
&mut self, &mut self,
attrs: &mut Vec<Attribute>, attrs: &mut AttrVec,
fn_parse_mode: FnParseMode, fn_parse_mode: FnParseMode,
sig_lo: Span, sig_lo: Span,
vis: &Visibility, vis: &Visibility,
@ -2002,7 +2002,7 @@ impl<'a> Parser<'a> {
/// or e.g. a block when the function is a provided one. /// or e.g. a block when the function is a provided one.
fn parse_fn_body( fn parse_fn_body(
&mut self, &mut self,
attrs: &mut Vec<Attribute>, attrs: &mut AttrVec,
ident: &Ident, ident: &Ident,
sig_hi: &mut Span, sig_hi: &mut Span,
req_body: bool, req_body: bool,
@ -2017,7 +2017,7 @@ impl<'a> Parser<'a> {
// Include the trailing semicolon in the span of the signature // Include the trailing semicolon in the span of the signature
self.expect_semi()?; self.expect_semi()?;
*sig_hi = self.prev_token.span; *sig_hi = self.prev_token.span;
(Vec::new(), None) (AttrVec::new(), None)
} else if self.check(&token::OpenDelim(Delimiter::Brace)) || self.token.is_whole_block() { } else if self.check(&token::OpenDelim(Delimiter::Brace)) || self.token.is_whole_block() {
self.parse_inner_attrs_and_block().map(|(attrs, body)| (attrs, Some(body)))? self.parse_inner_attrs_and_block().map(|(attrs, body)| (attrs, Some(body)))?
} else if self.token.kind == token::Eq { } else if self.token.kind == token::Eq {
@ -2034,7 +2034,7 @@ impl<'a> Parser<'a> {
Applicability::MachineApplicable, Applicability::MachineApplicable,
) )
.emit(); .emit();
(Vec::new(), Some(self.mk_block_err(span))) (AttrVec::new(), Some(self.mk_block_err(span)))
} else { } else {
let expected = if req_body { let expected = if req_body {
&[token::OpenDelim(Delimiter::Brace)][..] &[token::OpenDelim(Delimiter::Brace)][..]
@ -2051,7 +2051,7 @@ impl<'a> Parser<'a> {
return Err(err); return Err(err);
} }
} }
(Vec::new(), None) (AttrVec::new(), None)
}; };
attrs.extend(inner_attrs); attrs.extend(inner_attrs);
Ok(body) Ok(body)
@ -2280,7 +2280,7 @@ impl<'a> Parser<'a> {
self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
// Possibly parse `self`. Recover if we parsed it and it wasn't allowed here. // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
if let Some(mut param) = this.parse_self_param()? { if let Some(mut param) = this.parse_self_param()? {
param.attrs = attrs.into(); param.attrs = attrs;
let res = if first_param { Ok(param) } else { this.recover_bad_self_param(param) }; let res = if first_param { Ok(param) } else { this.recover_bad_self_param(param) };
return Ok((res?, TrailingToken::None)); return Ok((res?, TrailingToken::None));
} }
@ -2341,14 +2341,7 @@ impl<'a> Parser<'a> {
let span = lo.to(this.prev_token.span); let span = lo.to(this.prev_token.span);
Ok(( Ok((
Param { Param { attrs, id: ast::DUMMY_NODE_ID, is_placeholder: false, pat, span, ty },
attrs: attrs.into(),
id: ast::DUMMY_NODE_ID,
is_placeholder: false,
pat,
span,
ty,
},
TrailingToken::None, TrailingToken::None,
)) ))
}) })

View file

@ -4,8 +4,8 @@ use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor};
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter}; use rustc_ast::token::{self, Delimiter};
use rustc_ast::{ use rustc_ast::{
self as ast, Attribute, BindingMode, Expr, ExprKind, MacCall, Mutability, Pat, PatField, self as ast, AttrVec, BindingMode, Expr, ExprKind, MacCall, Mutability, Pat, PatField, PatKind,
PatKind, Path, QSelf, RangeEnd, RangeSyntax, Path, QSelf, RangeEnd, RangeSyntax,
}; };
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult};
@ -1093,7 +1093,7 @@ impl<'a> Parser<'a> {
.emit(); .emit();
} }
fn parse_pat_field(&mut self, lo: Span, attrs: Vec<Attribute>) -> PResult<'a, PatField> { fn parse_pat_field(&mut self, lo: Span, attrs: AttrVec) -> PResult<'a, PatField> {
// Check if a colon exists one ahead. This means we're parsing a fieldname. // Check if a colon exists one ahead. This means we're parsing a fieldname.
let hi; let hi;
let (subpat, fieldname, is_shorthand) = if self.look_ahead(1, |t| t == &token::Colon) { let (subpat, fieldname, is_shorthand) = if self.look_ahead(1, |t| t == &token::Colon) {
@ -1134,7 +1134,7 @@ impl<'a> Parser<'a> {
ident: fieldname, ident: fieldname,
pat: subpat, pat: subpat,
is_shorthand, is_shorthand,
attrs: attrs.into(), attrs,
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
span: lo.to(hi), span: lo.to(hi),
is_placeholder: false, is_placeholder: false,

View file

@ -130,7 +130,7 @@ impl<'a> Parser<'a> {
let path = this.parse_path(PathStyle::Expr)?; let path = this.parse_path(PathStyle::Expr)?;
if this.eat(&token::Not) { if this.eat(&token::Not) {
let stmt_mac = this.parse_stmt_mac(lo, attrs.into(), path)?; let stmt_mac = this.parse_stmt_mac(lo, attrs, path)?;
if this.token == token::Semi { if this.token == token::Semi {
return Ok((stmt_mac, TrailingToken::Semi)); return Ok((stmt_mac, TrailingToken::Semi));
} else { } else {
@ -190,7 +190,7 @@ impl<'a> Parser<'a> {
// Since none of the above applied, this is an expression statement macro. // Since none of the above applied, this is an expression statement macro.
let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac)); let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac));
let e = self.maybe_recover_from_bad_qpath(e)?; let e = self.maybe_recover_from_bad_qpath(e)?;
let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?; let e = self.parse_dot_or_call_expr_with(e, lo, attrs)?;
let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?; let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
StmtKind::Expr(e) StmtKind::Expr(e)
}; };
@ -229,7 +229,7 @@ impl<'a> Parser<'a> {
) -> PResult<'a, Stmt> { ) -> PResult<'a, Stmt> {
self.collect_tokens_trailing_token(attrs, force_collect, |this, attrs| { self.collect_tokens_trailing_token(attrs, force_collect, |this, attrs| {
this.expect_keyword(kw::Let)?; this.expect_keyword(kw::Let)?;
let local = this.parse_local(attrs.into())?; let local = this.parse_local(attrs)?;
let trailing = if capture_semi && this.token.kind == token::Semi { let trailing = if capture_semi && this.token.kind == token::Semi {
TrailingToken::Semi TrailingToken::Semi
} else { } else {
@ -241,7 +241,7 @@ impl<'a> Parser<'a> {
fn recover_local_after_let(&mut self, lo: Span, attrs: AttrWrapper) -> PResult<'a, Stmt> { fn recover_local_after_let(&mut self, lo: Span, attrs: AttrWrapper) -> PResult<'a, Stmt> {
self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
let local = this.parse_local(attrs.into())?; let local = this.parse_local(attrs)?;
// FIXME - maybe capture semicolon in recovery? // FIXME - maybe capture semicolon in recovery?
Ok(( Ok((
this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Local(local)), this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Local(local)),
@ -509,9 +509,7 @@ impl<'a> Parser<'a> {
} }
/// Parses a block. Inner attributes are allowed. /// Parses a block. Inner attributes are allowed.
pub(super) fn parse_inner_attrs_and_block( pub(super) fn parse_inner_attrs_and_block(&mut self) -> PResult<'a, (AttrVec, P<Block>)> {
&mut self,
) -> PResult<'a, (Vec<Attribute>, P<Block>)> {
self.parse_block_common(self.token.span, BlockCheckMode::Default) self.parse_block_common(self.token.span, BlockCheckMode::Default)
} }
@ -520,8 +518,8 @@ impl<'a> Parser<'a> {
&mut self, &mut self,
lo: Span, lo: Span,
blk_mode: BlockCheckMode, blk_mode: BlockCheckMode,
) -> PResult<'a, (Vec<Attribute>, P<Block>)> { ) -> PResult<'a, (AttrVec, P<Block>)> {
maybe_whole!(self, NtBlock, |x| (Vec::new(), x)); maybe_whole!(self, NtBlock, |x| (AttrVec::new(), x));
self.maybe_recover_unexpected_block_label(); self.maybe_recover_unexpected_block_label();
if !self.eat(&token::OpenDelim(Delimiter::Brace)) { if !self.eat(&token::OpenDelim(Delimiter::Brace)) {

View file

@ -1130,7 +1130,7 @@ pub struct RenderedLink {
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub(crate) struct Attributes { pub(crate) struct Attributes {
pub(crate) doc_strings: Vec<DocFragment>, pub(crate) doc_strings: Vec<DocFragment>,
pub(crate) other_attrs: Vec<ast::Attribute>, pub(crate) other_attrs: ast::AttrVec,
} }
impl Attributes { impl Attributes {
@ -1173,7 +1173,7 @@ impl Attributes {
doc_only: bool, doc_only: bool,
) -> Attributes { ) -> Attributes {
let mut doc_strings = Vec::new(); let mut doc_strings = Vec::new();
let mut other_attrs = Vec::new(); let mut other_attrs = ast::AttrVec::new();
for (attr, parent_module) in attrs { for (attr, parent_module) in attrs {
if let Some((doc_str, comment_kind)) = attr.doc_str_and_comment_kind() { if let Some((doc_str, comment_kind)) = attr.doc_str_and_comment_kind() {
trace!("got doc_str={doc_str:?}"); trace!("got doc_str={doc_str:?}");

View file

@ -30,7 +30,6 @@ use rustc_ast::mut_visit::{self, visit_clobber, MutVisitor};
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_ast::*; use rustc_ast::*;
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_parse::new_parser_from_source_str; use rustc_parse::new_parser_from_source_str;
use rustc_session::parse::ParseSess; use rustc_session::parse::ParseSess;
use rustc_span::source_map::FilePathMapping; use rustc_span::source_map::FilePathMapping;
@ -47,7 +46,7 @@ fn parse_expr(ps: &ParseSess, src: &str) -> Option<P<Expr>> {
// Helper functions for building exprs // Helper functions for building exprs
fn expr(kind: ExprKind) -> P<Expr> { fn expr(kind: ExprKind) -> P<Expr> {
P(Expr { id: DUMMY_NODE_ID, kind, span: DUMMY_SP, attrs: ThinVec::new(), tokens: None }) P(Expr { id: DUMMY_NODE_ID, kind, span: DUMMY_SP, attrs: AttrVec::new(), tokens: None })
} }
fn make_x() -> P<Expr> { fn make_x() -> P<Expr> {
@ -196,7 +195,7 @@ impl MutVisitor for AddParens {
id: DUMMY_NODE_ID, id: DUMMY_NODE_ID,
kind: ExprKind::Paren(e), kind: ExprKind::Paren(e),
span: DUMMY_SP, span: DUMMY_SP,
attrs: ThinVec::new(), attrs: AttrVec::new(),
tokens: None, tokens: None,
}) })
}); });

View file

@ -4,58 +4,58 @@ PRE EXPANSION AST STATS
Name Accumulated Size Count Item Size Name Accumulated Size Count Item Size
---------------------------------------------------------------- ----------------------------------------------------------------
ExprField 48 ( 0.6%) 1 48 ExprField 48 ( 0.6%) 1 48
Attribute 64 ( 0.7%) 2 32 Crate 56 ( 0.7%) 1 56
Attribute 64 ( 0.8%) 2 32
- Normal 32 ( 0.4%) 1 - Normal 32 ( 0.4%) 1
- DocComment 32 ( 0.4%) 1 - DocComment 32 ( 0.4%) 1
GenericArgs 64 ( 0.7%) 1 64 GenericArgs 64 ( 0.8%) 1 64
- AngleBracketed 64 ( 0.7%) 1 - AngleBracketed 64 ( 0.8%) 1
Local 72 ( 0.8%) 1 72 Local 72 ( 0.9%) 1 72
WherePredicate 72 ( 0.8%) 1 72 WherePredicate 72 ( 0.9%) 1 72
- BoundPredicate 72 ( 0.8%) 1 - BoundPredicate 72 ( 0.9%) 1
Crate 72 ( 0.8%) 1 72
Arm 96 ( 1.1%) 2 48 Arm 96 ( 1.1%) 2 48
ForeignItem 112 ( 1.3%) 1 112 ForeignItem 96 ( 1.1%) 1 96
- Fn 112 ( 1.3%) 1 - Fn 96 ( 1.1%) 1
FieldDef 160 ( 1.8%) 2 80 FieldDef 160 ( 1.9%) 2 80
Stmt 160 ( 1.8%) 5 32 Stmt 160 ( 1.9%) 5 32
- Local 32 ( 0.4%) 1 - Local 32 ( 0.4%) 1
- MacCall 32 ( 0.4%) 1 - MacCall 32 ( 0.4%) 1
- Expr 96 ( 1.1%) 3 - Expr 96 ( 1.1%) 3
Param 160 ( 1.8%) 4 40 Param 160 ( 1.9%) 4 40
FnDecl 200 ( 2.3%) 5 40 FnDecl 200 ( 2.4%) 5 40
Variant 240 ( 2.8%) 2 120 Variant 240 ( 2.8%) 2 120
Block 288 ( 3.3%) 6 48 Block 288 ( 3.4%) 6 48
GenericBound 352 ( 4.0%) 4 88 GenericBound 352 ( 4.2%) 4 88
- Trait 352 ( 4.0%) 4 - Trait 352 ( 4.2%) 4
AssocItem 480 ( 5.5%) 4 120 AssocItem 416 ( 4.9%) 4 104
- TyAlias 240 ( 2.8%) 2 - TyAlias 208 ( 2.5%) 2
- Fn 240 ( 2.8%) 2 - Fn 208 ( 2.5%) 2
GenericParam 520 ( 6.0%) 5 104 GenericParam 520 ( 6.1%) 5 104
PathSegment 720 ( 8.3%) 30 24 PathSegment 720 ( 8.5%) 30 24
Expr 832 ( 9.6%) 8 104 Expr 832 ( 9.8%) 8 104
- Path 104 ( 1.2%) 1 - Path 104 ( 1.2%) 1
- Match 104 ( 1.2%) 1 - Match 104 ( 1.2%) 1
- Struct 104 ( 1.2%) 1 - Struct 104 ( 1.2%) 1
- Lit 208 ( 2.4%) 2 - Lit 208 ( 2.5%) 2
- Block 312 ( 3.6%) 3 - Block 312 ( 3.7%) 3
Pat 840 ( 9.7%) 7 120 Pat 840 ( 9.9%) 7 120
- Struct 120 ( 1.4%) 1 - Struct 120 ( 1.4%) 1
- Wild 120 ( 1.4%) 1 - Wild 120 ( 1.4%) 1
- Ident 600 ( 6.9%) 5 - Ident 600 ( 7.1%) 5
Ty 1_344 (15.5%) 14 96 Ty 1_344 (15.9%) 14 96
- Rptr 96 ( 1.1%) 1 - Rptr 96 ( 1.1%) 1
- Ptr 96 ( 1.1%) 1 - Ptr 96 ( 1.1%) 1
- ImplicitSelf 192 ( 2.2%) 2 - ImplicitSelf 192 ( 2.3%) 2
- Path 960 (11.0%) 10 - Path 960 (11.4%) 10
Item 1_800 (20.7%) 9 200 Item 1_656 (19.6%) 9 184
- Trait 200 ( 2.3%) 1 - Trait 184 ( 2.2%) 1
- Enum 200 ( 2.3%) 1 - Enum 184 ( 2.2%) 1
- ForeignMod 200 ( 2.3%) 1 - ForeignMod 184 ( 2.2%) 1
- Impl 200 ( 2.3%) 1 - Impl 184 ( 2.2%) 1
- Fn 400 ( 4.6%) 2 - Fn 368 ( 4.4%) 2
- Use 600 ( 6.9%) 3 - Use 552 ( 6.5%) 3
---------------------------------------------------------------- ----------------------------------------------------------------
Total 8_696 Total 8_456
POST EXPANSION AST STATS POST EXPANSION AST STATS
@ -63,15 +63,15 @@ POST EXPANSION AST STATS
Name Accumulated Size Count Item Size Name Accumulated Size Count Item Size
---------------------------------------------------------------- ----------------------------------------------------------------
ExprField 48 ( 0.5%) 1 48 ExprField 48 ( 0.5%) 1 48
Crate 56 ( 0.6%) 1 56
GenericArgs 64 ( 0.7%) 1 64 GenericArgs 64 ( 0.7%) 1 64
- AngleBracketed 64 ( 0.7%) 1 - AngleBracketed 64 ( 0.7%) 1
Local 72 ( 0.8%) 1 72 Local 72 ( 0.8%) 1 72
WherePredicate 72 ( 0.8%) 1 72 WherePredicate 72 ( 0.8%) 1 72
- BoundPredicate 72 ( 0.8%) 1 - BoundPredicate 72 ( 0.8%) 1
Crate 72 ( 0.8%) 1 72
Arm 96 ( 1.0%) 2 48 Arm 96 ( 1.0%) 2 48
ForeignItem 112 ( 1.2%) 1 112 ForeignItem 96 ( 1.0%) 1 96
- Fn 112 ( 1.2%) 1 - Fn 96 ( 1.0%) 1
InlineAsm 120 ( 1.3%) 1 120 InlineAsm 120 ( 1.3%) 1 120
Attribute 128 ( 1.4%) 4 32 Attribute 128 ( 1.4%) 4 32
- DocComment 32 ( 0.3%) 1 - DocComment 32 ( 0.3%) 1
@ -82,42 +82,42 @@ Stmt 160 ( 1.7%) 5 32
- Semi 32 ( 0.3%) 1 - Semi 32 ( 0.3%) 1
- Expr 96 ( 1.0%) 3 - Expr 96 ( 1.0%) 3
Param 160 ( 1.7%) 4 40 Param 160 ( 1.7%) 4 40
FnDecl 200 ( 2.1%) 5 40 FnDecl 200 ( 2.2%) 5 40
Variant 240 ( 2.5%) 2 120 Variant 240 ( 2.6%) 2 120
Block 288 ( 3.0%) 6 48 Block 288 ( 3.1%) 6 48
GenericBound 352 ( 3.7%) 4 88 GenericBound 352 ( 3.8%) 4 88
- Trait 352 ( 3.7%) 4 - Trait 352 ( 3.8%) 4
AssocItem 480 ( 5.1%) 4 120 AssocItem 416 ( 4.5%) 4 104
- TyAlias 240 ( 2.5%) 2 - TyAlias 208 ( 2.3%) 2
- Fn 240 ( 2.5%) 2 - Fn 208 ( 2.3%) 2
GenericParam 520 ( 5.5%) 5 104 GenericParam 520 ( 5.7%) 5 104
PathSegment 792 ( 8.4%) 33 24 PathSegment 792 ( 8.6%) 33 24
Pat 840 ( 8.9%) 7 120 Pat 840 ( 9.1%) 7 120
- Struct 120 ( 1.3%) 1 - Struct 120 ( 1.3%) 1
- Wild 120 ( 1.3%) 1 - Wild 120 ( 1.3%) 1
- Ident 600 ( 6.3%) 5 - Ident 600 ( 6.5%) 5
Expr 936 ( 9.9%) 9 104 Expr 936 (10.2%) 9 104
- Path 104 ( 1.1%) 1 - Path 104 ( 1.1%) 1
- Match 104 ( 1.1%) 1 - Match 104 ( 1.1%) 1
- Struct 104 ( 1.1%) 1 - Struct 104 ( 1.1%) 1
- InlineAsm 104 ( 1.1%) 1 - InlineAsm 104 ( 1.1%) 1
- Lit 208 ( 2.2%) 2 - Lit 208 ( 2.3%) 2
- Block 312 ( 3.3%) 3 - Block 312 ( 3.4%) 3
Ty 1_344 (14.2%) 14 96 Ty 1_344 (14.6%) 14 96
- Rptr 96 ( 1.0%) 1 - Rptr 96 ( 1.0%) 1
- Ptr 96 ( 1.0%) 1 - Ptr 96 ( 1.0%) 1
- ImplicitSelf 192 ( 2.0%) 2 - ImplicitSelf 192 ( 2.1%) 2
- Path 960 (10.2%) 10 - Path 960 (10.5%) 10
Item 2_200 (23.3%) 11 200 Item 2_024 (22.0%) 11 184
- Trait 200 ( 2.1%) 1 - Trait 184 ( 2.0%) 1
- Enum 200 ( 2.1%) 1 - Enum 184 ( 2.0%) 1
- ExternCrate 200 ( 2.1%) 1 - ExternCrate 184 ( 2.0%) 1
- ForeignMod 200 ( 2.1%) 1 - ForeignMod 184 ( 2.0%) 1
- Impl 200 ( 2.1%) 1 - Impl 184 ( 2.0%) 1
- Fn 400 ( 4.2%) 2 - Fn 368 ( 4.0%) 2
- Use 800 ( 8.5%) 4 - Use 736 ( 8.0%) 4
---------------------------------------------------------------- ----------------------------------------------------------------
Total 9_456 Total 9_184
HIR STATS HIR STATS

View file

@ -49,10 +49,7 @@ pub(crate) fn get_span_without_attrs(stmt: &ast::Stmt) -> Span {
} }
/// Returns attributes that are within `outer_span`. /// Returns attributes that are within `outer_span`.
pub(crate) fn filter_inline_attrs( pub(crate) fn filter_inline_attrs(attrs: &[ast::Attribute], outer_span: Span) -> ast::AttrVec {
attrs: &[ast::Attribute],
outer_span: Span,
) -> Vec<ast::Attribute> {
attrs attrs
.iter() .iter()
.filter(|a| outer_span.lo() <= a.span.lo() && a.span.hi() <= outer_span.hi()) .filter(|a| outer_span.lo() <= a.span.lo() && a.span.hi() <= outer_span.hi())

View file

@ -116,7 +116,7 @@ pub(crate) struct UseTree {
// Additional fields for top level use items. // Additional fields for top level use items.
// Should we have another struct for top-level use items rather than reusing this? // Should we have another struct for top-level use items rather than reusing this?
visibility: Option<ast::Visibility>, visibility: Option<ast::Visibility>,
attrs: Option<Vec<ast::Attribute>>, attrs: Option<ast::AttrVec>,
} }
impl PartialEq for UseTree { impl PartialEq for UseTree {
@ -417,7 +417,7 @@ impl UseTree {
list_item: Option<ListItem>, list_item: Option<ListItem>,
visibility: Option<ast::Visibility>, visibility: Option<ast::Visibility>,
opt_lo: Option<BytePos>, opt_lo: Option<BytePos>,
attrs: Option<Vec<ast::Attribute>>, attrs: Option<ast::AttrVec>,
) -> UseTree { ) -> UseTree {
let span = if let Some(lo) = opt_lo { let span = if let Some(lo) = opt_lo {
mk_sp(lo, a.span.hi()) mk_sp(lo, a.span.hi())

View file

@ -26,7 +26,7 @@ type FileModMap<'ast> = BTreeMap<FileName, Module<'ast>>;
pub(crate) struct Module<'a> { pub(crate) struct Module<'a> {
ast_mod_kind: Option<Cow<'a, ast::ModKind>>, ast_mod_kind: Option<Cow<'a, ast::ModKind>>,
pub(crate) items: Cow<'a, Vec<rustc_ast::ptr::P<ast::Item>>>, pub(crate) items: Cow<'a, Vec<rustc_ast::ptr::P<ast::Item>>>,
inner_attr: Vec<ast::Attribute>, inner_attr: ast::AttrVec,
pub(crate) span: Span, pub(crate) span: Span,
} }
@ -35,7 +35,7 @@ impl<'a> Module<'a> {
mod_span: Span, mod_span: Span,
ast_mod_kind: Option<Cow<'a, ast::ModKind>>, ast_mod_kind: Option<Cow<'a, ast::ModKind>>,
mod_items: Cow<'a, Vec<rustc_ast::ptr::P<ast::Item>>>, mod_items: Cow<'a, Vec<rustc_ast::ptr::P<ast::Item>>>,
mod_attrs: Cow<'a, Vec<ast::Attribute>>, mod_attrs: Cow<'a, ast::AttrVec>,
) -> Self { ) -> Self {
let inner_attr = mod_attrs let inner_attr = mod_attrs
.iter() .iter()
@ -158,7 +158,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
module_item.item.span, module_item.item.span,
Some(Cow::Owned(sub_mod_kind.clone())), Some(Cow::Owned(sub_mod_kind.clone())),
Cow::Owned(vec![]), Cow::Owned(vec![]),
Cow::Owned(vec![]), Cow::Owned(ast::AttrVec::new()),
), ),
)?; )?;
} }
@ -185,7 +185,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
span, span,
Some(Cow::Owned(sub_mod_kind.clone())), Some(Cow::Owned(sub_mod_kind.clone())),
Cow::Owned(vec![]), Cow::Owned(vec![]),
Cow::Owned(vec![]), Cow::Owned(ast::AttrVec::new()),
), ),
)?; )?;
} }

View file

@ -109,7 +109,7 @@ impl<'a> Parser<'a> {
sess: &'a ParseSess, sess: &'a ParseSess,
path: &Path, path: &Path,
span: Span, span: Span,
) -> Result<(Vec<ast::Attribute>, Vec<ptr::P<ast::Item>>, Span), ParserError> { ) -> Result<(ast::AttrVec, Vec<ptr::P<ast::Item>>, Span), ParserError> {
let result = catch_unwind(AssertUnwindSafe(|| { let result = catch_unwind(AssertUnwindSafe(|| {
let mut parser = new_parser_from_file(sess.inner(), path, Some(span)); let mut parser = new_parser_from_file(sess.inner(), path, Some(span));
match parser.parse_mod(&TokenKind::Eof) { match parser.parse_mod(&TokenKind::Eof) {