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)]
pub struct Crate {
pub attrs: Vec<Attribute>,
pub attrs: AttrVec,
pub items: Vec<P<Item>>,
pub spans: ModSpans,
/// 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,
kind: ExprKind::Err,
span: DUMMY_SP,
attrs: ThinVec::new(),
attrs: AttrVec::new(),
tokens: None,
},
)
@ -2669,7 +2669,7 @@ impl VariantData {
/// An item definition.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Item<K = ItemKind> {
pub attrs: Vec<Attribute>,
pub attrs: AttrVec,
pub id: NodeId,
pub span: Span,
pub vis: Visibility,
@ -3036,19 +3036,19 @@ mod size_asserts {
use super::*;
use rustc_data_structures::static_assert_size;
// 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!(Attribute, 32);
static_assert_size!(Block, 48);
static_assert_size!(Expr, 104);
static_assert_size!(ExprKind, 72);
static_assert_size!(Fn, 192);
static_assert_size!(ForeignItem, 112);
static_assert_size!(ForeignItem, 96);
static_assert_size!(ForeignItemKind, 24);
static_assert_size!(GenericBound, 88);
static_assert_size!(Generics, 72);
static_assert_size!(Impl, 200);
static_assert_size!(Item, 200);
static_assert_size!(Item, 184);
static_assert_size!(ItemKind, 112);
static_assert_size!(Lit, 48);
static_assert_size!(LitKind, 24);

View File

@ -270,7 +270,7 @@ pub trait HasAttrs {
/// during token collection.
const SUPPORTS_CUSTOM_INNER_ATTRS: bool;
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 {
@ -283,8 +283,8 @@ macro_rules! impl_has_attrs {
&self.attrs
}
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
VecOrAttrVec::visit(&mut self.attrs, f)
fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
f(&mut self.attrs)
}
}
)+
@ -299,7 +299,7 @@ macro_rules! impl_has_attrs_none {
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] {
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)
}
}
@ -340,7 +340,7 @@ impl<T: HasAttrs> HasAttrs for Option<T> {
fn attrs(&self) -> &[Attribute] {
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() {
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 {
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::Item(item) => item.visit_attrs(f),
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] {
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);
}
}
/// 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.
pub struct AstNodeWrapper<Wrapped, Tag> {
pub wrapped: Wrapped,

View File

@ -12,7 +12,6 @@ use crate::tokenstream::{DelimSpan, Spacing, TokenTree};
use crate::tokenstream::{LazyTokenStream, TokenStream};
use crate::util::comments;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_index::bit_set::GrowableBitSet;
use rustc_span::source_map::BytePos;
use rustc_span::symbol::{sym, Ident, Symbol};
@ -487,7 +486,7 @@ impl MetaItemKind {
id: ast::DUMMY_NODE_ID,
kind: ast::ExprKind::Lit(lit.clone()),
span: lit.span,
attrs: ThinVec::new(),
attrs: ast::AttrVec::new(),
tokens: None,
});
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::sync::Lrc;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::Ident;
use rustc_span::Span;
@ -338,12 +337,7 @@ where
}
// 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) {
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) {
pub fn visit_attrs<T: MutVisitor>(attrs: &mut AttrVec, vis: &mut T) {
for attr in attrs.iter_mut() {
vis.visit_attribute(attr);
}
@ -398,7 +392,7 @@ pub fn noop_flat_map_pat_field<T: MutVisitor>(
vis.visit_ident(ident);
vis.visit_pat(pat);
vis.visit_span(span);
visit_thin_attrs(attrs, vis);
visit_attrs(attrs, vis);
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]> {
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_pat(pat);
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;
visitor.visit_ident(ident);
visitor.visit_vis(vis);
visit_thin_attrs(attrs, visitor);
visit_attrs(attrs, visitor);
visitor.visit_id(id);
visitor.visit_variant_data(data);
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);
visit_thin_attrs(attrs, vis);
visit_attrs(attrs, 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]> {
let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param;
vis.visit_id(id);
visit_thin_attrs(attrs, vis);
visit_attrs(attrs, vis);
vis.visit_pat(pat);
vis.visit_span(span);
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 {
vis.visit_span(colon_span);
}
visit_thin_attrs(attrs, vis);
visit_attrs(attrs, vis);
visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis));
match kind {
GenericParamKind::Lifetime => {}
@ -978,7 +972,7 @@ pub fn noop_flat_map_field_def<T: MutVisitor>(
visitor.visit_vis(vis);
visitor.visit_id(id);
visitor.visit_ty(ty);
visit_thin_attrs(attrs, visitor);
visit_attrs(attrs, visitor);
smallvec![fd]
}
@ -991,7 +985,7 @@ pub fn noop_flat_map_expr_field<T: MutVisitor>(
vis.visit_expr(expr);
vis.visit_id(id);
vis.visit_span(span);
visit_thin_attrs(attrs, vis);
visit_attrs(attrs, vis);
smallvec![f]
}
@ -1432,7 +1426,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
}
vis.visit_id(id);
vis.visit_span(span);
visit_thin_attrs(attrs, vis);
visit_attrs(attrs, vis);
visit_lazy_tts(tokens, vis);
}
@ -1478,7 +1472,7 @@ pub fn noop_flat_map_stmt_kind<T: MutVisitor>(
StmtKind::MacCall(mut mac) => {
let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut();
vis.visit_mac_call(mac_);
visit_thin_attrs(attrs, vis);
visit_attrs(attrs, vis);
visit_lazy_tts(tokens, vis);
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 {
fn dummy() -> Self {
Item {

View File

@ -6,7 +6,6 @@ use rustc_ast::attr;
use rustc_ast::ptr::P as AstP;
use rustc_ast::*;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
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 new_cond = self.manage_let_cond(lowered_cond);
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 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_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 span = self.lower_span(span.with_hi(cond.span.hi()));
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(
method_span,
lang_item,
ThinVec::new(),
AttrVec::new(),
None,
));
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(
unstable_span,
hir::LangItem::FromGenerator,
ThinVec::new(),
AttrVec::new(),
None,
);
@ -747,7 +746,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let break_x = self.with_loop_scope(loop_node_id, move |this| {
let expr_break =
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)
};
@ -780,7 +779,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let yield_expr = self.expr(
span,
hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }),
ThinVec::new(),
AttrVec::new(),
);
let yield_expr = self.arena.alloc(yield_expr);
@ -987,7 +986,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::AsyncGeneratorKind::Closure,
|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
});
@ -1257,7 +1256,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let ident = self.expr_ident(lhs.span, ident, binding);
let assign =
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));
pat
}
@ -1299,7 +1298,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let fn_path =
hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None);
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])
}
@ -1472,7 +1471,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// `None => break`
let none_arm = {
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);
self.arm(pat, break_expr)
};
@ -1481,7 +1480,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let some_arm = {
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_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)
};
@ -1596,7 +1595,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
};
attr::mk_attr_outer(allow)
};
let attrs = vec![attr];
let attrs: AttrVec = vec![attr].into();
// `ControlFlow::Continue(val) => #[allow(unreachable_code)] val,`
let continue_arm = {
@ -1606,7 +1605,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
span,
val_ident,
val_pat_nid,
ThinVec::from(attrs.clone()),
attrs.clone(),
));
let continue_pat = self.pat_cf_continue(unstable_span, val_pat);
self.arm(continue_pat, val_expr)
@ -1625,7 +1624,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.arena.alloc(residual_expr),
unstable_span,
);
let thin_attrs = ThinVec::from(attrs);
let ret_expr = if let Some(catch_node) = self.catch_scope {
let target_id = Ok(self.lower_node_id(catch_node));
self.arena.alloc(self.expr(
@ -1634,13 +1632,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::Destination { label: None, target_id },
Some(from_residual_expr),
),
thin_attrs,
attrs,
))
} else {
self.arena.alloc(self.expr(
try_span,
hir::ExprKind::Ret(Some(from_residual_expr)),
thin_attrs,
attrs,
))
};
@ -1728,7 +1726,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
arms: &'hir [hir::Arm<'hir>],
source: hir::MatchSource,
) -> 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> {
@ -1745,12 +1743,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.expr(
span,
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> {
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(
@ -1759,7 +1757,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
e: &'hir hir::Expr<'hir>,
args: &'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(
@ -1779,7 +1777,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir_id: Option<hir::HirId>,
) -> hir::Expr<'hir> {
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)
}
@ -1822,7 +1820,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ident: Ident,
binding: hir::HirId,
) -> 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(
@ -1860,13 +1858,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
}),
None,
),
ThinVec::new(),
AttrVec::new(),
)
}
fn expr_block_empty(&mut self, span: Span) -> &'hir hir::Expr<'hir> {
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)
}

View File

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

View File

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

View File

@ -68,7 +68,7 @@ pub fn expand_deriving_clone(
}
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 {
span,
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 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 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 {
span,
path: path_std!(cmp::Eq),

View File

@ -15,7 +15,7 @@ pub fn expand_deriving_ord(
push: &mut dyn FnMut(Annotatable),
) {
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 {
span,
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
// faster.
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 {
name: sym::eq,
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));
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 {
name: sym::partial_cmp,

View File

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

View File

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

View File

@ -2,9 +2,7 @@ use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use rustc_ast as ast;
use rustc_ast::walk_list;
use rustc_ast::EnumDef;
use rustc_ast::VariantData;
use rustc_ast::{walk_list, EnumDef, VariantData};
use rustc_errors::Applicability;
use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt};
use rustc_span::symbol::Ident;
@ -22,7 +20,7 @@ pub fn expand_deriving_default(
item.visit_with(&mut DetectNonVariantDefaultAttr { cx });
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 {
span,
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::pathvec_std;
use rustc_ast::{ExprKind, MetaItem, Mutability};
use rustc_ast::{AttrVec, ExprKind, MetaItem, Mutability};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
@ -131,7 +131,7 @@ pub fn expand_deriving_rustc_encodable(
],
PathKind::Std,
)),
attributes: Vec::new(),
attributes: AttrVec::new(),
unify_fieldless_variants: false,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
encodable_substructure(a, b, c, krate)

View File

@ -217,7 +217,7 @@ pub struct MethodDef<'a> {
/// Returns type
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?
/// 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,
tokens: None,
},
attrs: Vec::new(),
attrs: ast::AttrVec::new(),
kind: ast::AssocItemKind::TyAlias(Box::new(ast::TyAlias {
defaultness: ast::Defaultness::Final,
generics: Generics::default(),
@ -716,7 +716,7 @@ impl<'a> TraitDef<'a> {
let self_type = cx.ty_path(path);
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);
cx.item(

View File

@ -2,7 +2,7 @@ use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
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_span::symbol::sym;
use rustc_span::Span;
@ -31,7 +31,7 @@ pub fn expand_deriving_hash(
explicit_self: true,
nonself_args: vec![(Ref(Box::new(Path(arg)), Mutability::Mut), sym::state)],
ret_ty: Unit,
attributes: vec![],
attributes: AttrVec::new(),
unify_fieldless_variants: true,
combine_substructure: combine_substructure(Box::new(|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
// how the generated implementation is linted.
let mut attrs = Vec::new();
let mut attrs = ast::AttrVec::new();
attrs.extend(
item.attrs
.iter()

View File

@ -4,7 +4,7 @@ use rustc_ast::expand::allocator::{
AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS,
};
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_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
@ -113,10 +113,10 @@ impl AllocFnFactory<'_, '_> {
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 = self.cx.meta_word(self.span, special);
vec![self.cx.attribute(special)]
vec![self.cx.attribute(special)].into()
}
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 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 client = Ident::new(sym::client, span);

View File

@ -51,7 +51,7 @@ pub fn inject(
cx.item(
span,
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),
),
);
@ -78,7 +78,7 @@ pub fn inject(
let use_item = cx.item(
span,
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 {
prefix: cx.path(span, import_path),
kind: ast::UseTreeKind::Glob,

View File

@ -227,7 +227,8 @@ pub fn expand_test_or_bench(
)),
// #[rustc_test_marker]
cx.attribute(cx.meta_word(attr_sp, sym::rustc_test_marker)),
],
]
.into(),
// const $ident: test::TestDescAndFn =
ast::ItemKind::Const(
ast::Defaultness::Final,
@ -334,7 +335,7 @@ pub fn expand_test_or_bench(
});
// 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));

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);
// extern crate test
let test_extern_stmt =
ecx.stmt_item(sp, ecx.item(sp, test_id, vec![], ast::ItemKind::ExternCrate(None)));
let test_extern_stmt = ecx.stmt_item(
sp,
ecx.item(sp, test_id, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None)),
);
// #[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 {
ident: main_id,
attrs: vec![main_attr],
attrs: vec![main_attr].into(),
id: ast::DUMMY_NODE_ID,
kind: main,
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 std::ptr;
@ -15,94 +16,64 @@ pub trait MapInPlace<T>: Sized {
I: IntoIterator<Item = T>;
}
impl<T> MapInPlace<T> for Vec<T> {
fn flat_map_in_place<F, I>(&mut self, mut f: F)
where
F: FnMut(T) -> I,
I: IntoIterator<Item = T>,
{
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
// The implementation of this method is syntactically identical for all the
// different vector types.
macro_rules! flat_map_in_place {
() => {
fn flat_map_in_place<F, I>(&mut self, mut f: F)
where
F: FnMut(T) -> I,
I: IntoIterator<Item = T>,
{
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;
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);
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);
old_len = self.len();
self.set_len(0);
read_i += 1;
write_i += 1;
read_i += 1;
write_i += 1;
}
}
}
}
// write_i tracks the number of actually written new items.
self.set_len(write_i);
// write_i tracks the number of actually written new items.
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> {
fn flat_map_in_place<F, I>(&mut self, mut f: F)
where
F: FnMut(T) -> I,
I: IntoIterator<Item = T>,
{
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);
}
}
flat_map_in_place!();
}
impl<T> MapInPlace<T> for ThinVec<T> {
flat_map_in_place!();
}

View File

@ -27,6 +27,51 @@ impl<T> ThinVec<T> {
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> {

View File

@ -1070,7 +1070,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::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 {
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(

View File

@ -6,7 +6,7 @@ use rustc_ast::ptr::P;
use rustc_ast::token::{self, Nonterminal};
use rustc_ast::tokenstream::TokenStream;
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_data_structures::fx::{FxHashSet, FxIndexMap};
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 {
Annotatable::Item(item) => item.visit_attrs(f),
Annotatable::TraitItem(trait_item) => trait_item.visit_attrs(f),

View File

@ -575,7 +575,7 @@ impl<'a> ExtCtxt<'a> {
&self,
span: Span,
name: Ident,
attrs: Vec<ast::Attribute>,
attrs: ast::AttrVec,
kind: ast::ItemKind,
) -> P<ast::Item> {
// FIXME: Would be nice if our generated code didn't violate
@ -603,7 +603,7 @@ impl<'a> ExtCtxt<'a> {
mutbl: ast::Mutability,
expr: P<ast::Expr>,
) -> 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(
@ -614,7 +614,7 @@ impl<'a> ExtCtxt<'a> {
expr: P<ast::Expr>,
) -> P<ast::Item> {
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 {

View File

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

View File

@ -11,7 +11,7 @@ use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter};
use rustc_ast::tokenstream::TokenStream;
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::{Inline, ItemKind, MacArgs, MacStmtStyle, MetaItemKind, ModKind};
use rustc_ast::{NestedMetaItem, NodeId, PatKind, StmtKind, TyKind};
@ -1001,7 +1001,7 @@ enum AddSemicolon {
/// of functionality used by `InvocationCollector`.
trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized {
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;
fn to_annotatable(self) -> Annotatable;
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy;
@ -1333,7 +1333,7 @@ impl InvocationCollectorNode for ast::Stmt {
}
StmtKind::Item(item) => match item.into_inner() {
ast::Item { kind: ItemKind::MacCall(mac), attrs, .. } => {
(mac.args.need_semicolon(), mac, attrs.into())
(mac.args.need_semicolon(), mac, attrs)
}
_ => unreachable!(),
},
@ -1390,7 +1390,7 @@ impl InvocationCollectorNode for P<ast::Ty> {
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
let node = self.into_inner();
match node.kind {
TyKind::MacCall(mac) => (mac, Vec::new(), AddSemicolon::No),
TyKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No),
_ => unreachable!(),
}
}
@ -1414,7 +1414,7 @@ impl InvocationCollectorNode for P<ast::Pat> {
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
let node = self.into_inner();
match node.kind {
PatKind::MacCall(mac) => (mac, Vec::new(), AddSemicolon::No),
PatKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No),
_ => 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) {
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 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_parse::new_parser_from_file;
use rustc_parse::validate_attr;
@ -48,7 +48,7 @@ pub(crate) fn parse_external_mod(
span: Span, // The span to blame on errors.
module: &ModuleData,
mut dir_ownership: DirOwnership,
attrs: &mut Vec<Attribute>,
attrs: &mut AttrVec,
) -> ParsedExternalMod {
// We bail on the first error, but that error does not cause a fatal error... (1)
let result: Result<_, ModError<'_>> = try {
@ -63,9 +63,9 @@ pub(crate) fn parse_external_mod(
// 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 inner_attrs, items, inner_span) =
let (inner_attrs, items, inner_span) =
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)
};
// (1) ...instead, we return a dummy module.

View File

@ -24,7 +24,7 @@ pub fn placeholder(
}
let ident = Ident::empty();
let attrs = Vec::new();
let attrs = ast::AttrVec::new();
let vis = vis.unwrap_or(ast::Visibility {
span: DUMMY_SP,
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>(
input: &Path,
sess: &'a ParseSess,
) -> PResult<'a, Vec<ast::Attribute>> {
) -> PResult<'a, ast::AttrVec> {
let mut parser = new_parser_from_file(sess, input, None);
parser.parse_inner_attributes()
}
@ -79,7 +79,7 @@ pub fn parse_crate_attrs_from_source_str(
name: FileName,
source: String,
sess: &ParseSess,
) -> PResult<'_, Vec<ast::Attribute>> {
) -> PResult<'_, ast::AttrVec> {
new_parser_from_source_str(sess, name, source).parse_inner_attributes()
}

View File

@ -34,7 +34,7 @@ enum OuterAttributeType {
impl<'a> Parser<'a> {
/// Parses attributes that appear before an item.
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 start_pos = self.token_cursor.num_next_calls;
loop {
@ -106,7 +106,7 @@ impl<'a> Parser<'a> {
break;
}
}
Ok(AttrWrapper::new(outer_attrs.into(), start_pos))
Ok(AttrWrapper::new(outer_attrs, start_pos))
}
/// Matches `attribute = # ! [ meta_item ]`.
@ -283,8 +283,8 @@ impl<'a> Parser<'a> {
/// terminated by a semicolon.
///
/// Matches `inner_attrs*`.
pub(crate) fn parse_inner_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
let mut attrs: Vec<ast::Attribute> = vec![];
pub(crate) fn parse_inner_attributes(&mut self) -> PResult<'a, ast::AttrVec> {
let mut attrs = ast::AttrVec::new();
loop {
let start_pos: u32 = self.token_cursor.num_next_calls.try_into().unwrap();
// 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
/// 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
/// by passing an `AttrWrapper` to `collect_tokens_trailing_tokens`.
/// 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
/// cannot directly access the `attrs` field
@ -49,9 +49,10 @@ impl AttrWrapper {
self.attrs
}
// Prepend `self.attrs` to `attrs`.
// FIXME: require passing an NT to prevent misuse of this method
pub(crate) fn prepend_to_nt_inner(self, attrs: &mut Vec<Attribute>) {
let mut self_attrs: Vec<_> = self.attrs.into();
pub(crate) fn prepend_to_nt_inner(self, attrs: &mut AttrVec) {
let mut self_attrs = self.attrs.clone();
std::mem::swap(attrs, &mut self_attrs);
attrs.extend(self_attrs);
}
@ -196,7 +197,7 @@ impl<'a> Parser<'a> {
&mut self,
attrs: AttrWrapper,
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> {
// We only bail out when nothing could possibly observe the collected 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.
&& !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);
@ -222,7 +223,7 @@ impl<'a> Parser<'a> {
let prev_capturing = std::mem::replace(&mut self.capture_state.capturing, Capturing::Yes);
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;
@ -352,7 +353,7 @@ impl<'a> Parser<'a> {
// on the captured token stream.
if self.capture_cfg
&& 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 };

View File

@ -2370,7 +2370,7 @@ impl<'a> Parser<'a> {
fn recover_const_param_decl(&mut self, ty_generics: Option<&Generics>) -> Option<GenericArg> {
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,
Err(err) => {
err.cancel();

View File

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

View File

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

View File

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

View File

@ -130,7 +130,7 @@ impl<'a> Parser<'a> {
let path = this.parse_path(PathStyle::Expr)?;
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 {
return Ok((stmt_mac, TrailingToken::Semi));
} else {
@ -190,7 +190,7 @@ impl<'a> Parser<'a> {
// 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.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))?;
StmtKind::Expr(e)
};
@ -229,7 +229,7 @@ impl<'a> Parser<'a> {
) -> PResult<'a, Stmt> {
self.collect_tokens_trailing_token(attrs, force_collect, |this, attrs| {
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 {
TrailingToken::Semi
} else {
@ -241,7 +241,7 @@ impl<'a> Parser<'a> {
fn recover_local_after_let(&mut self, lo: Span, attrs: AttrWrapper) -> PResult<'a, Stmt> {
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?
Ok((
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.
pub(super) fn parse_inner_attrs_and_block(
&mut self,
) -> PResult<'a, (Vec<Attribute>, P<Block>)> {
pub(super) fn parse_inner_attrs_and_block(&mut self) -> PResult<'a, (AttrVec, P<Block>)> {
self.parse_block_common(self.token.span, BlockCheckMode::Default)
}
@ -520,8 +518,8 @@ impl<'a> Parser<'a> {
&mut self,
lo: Span,
blk_mode: BlockCheckMode,
) -> PResult<'a, (Vec<Attribute>, P<Block>)> {
maybe_whole!(self, NtBlock, |x| (Vec::new(), x));
) -> PResult<'a, (AttrVec, P<Block>)> {
maybe_whole!(self, NtBlock, |x| (AttrVec::new(), x));
self.maybe_recover_unexpected_block_label();
if !self.eat(&token::OpenDelim(Delimiter::Brace)) {

View File

@ -1130,7 +1130,7 @@ pub struct RenderedLink {
#[derive(Clone, Debug, Default)]
pub(crate) struct Attributes {
pub(crate) doc_strings: Vec<DocFragment>,
pub(crate) other_attrs: Vec<ast::Attribute>,
pub(crate) other_attrs: ast::AttrVec,
}
impl Attributes {
@ -1173,7 +1173,7 @@ impl Attributes {
doc_only: bool,
) -> Attributes {
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 {
if let Some((doc_str, comment_kind)) = attr.doc_str_and_comment_kind() {
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::*;
use rustc_ast_pretty::pprust;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_parse::new_parser_from_source_str;
use rustc_session::parse::ParseSess;
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
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> {
@ -196,7 +195,7 @@ impl MutVisitor for AddParens {
id: DUMMY_NODE_ID,
kind: ExprKind::Paren(e),
span: DUMMY_SP,
attrs: ThinVec::new(),
attrs: AttrVec::new(),
tokens: None,
})
});

View File

@ -4,58 +4,58 @@ PRE EXPANSION AST STATS
Name Accumulated Size Count Item Size
----------------------------------------------------------------
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
- DocComment 32 ( 0.4%) 1
GenericArgs 64 ( 0.7%) 1 64
- AngleBracketed 64 ( 0.7%) 1
Local 72 ( 0.8%) 1 72
WherePredicate 72 ( 0.8%) 1 72
- BoundPredicate 72 ( 0.8%) 1
Crate 72 ( 0.8%) 1 72
GenericArgs 64 ( 0.8%) 1 64
- AngleBracketed 64 ( 0.8%) 1
Local 72 ( 0.9%) 1 72
WherePredicate 72 ( 0.9%) 1 72
- BoundPredicate 72 ( 0.9%) 1
Arm 96 ( 1.1%) 2 48
ForeignItem 112 ( 1.3%) 1 112
- Fn 112 ( 1.3%) 1
FieldDef 160 ( 1.8%) 2 80
Stmt 160 ( 1.8%) 5 32
ForeignItem 96 ( 1.1%) 1 96
- Fn 96 ( 1.1%) 1
FieldDef 160 ( 1.9%) 2 80
Stmt 160 ( 1.9%) 5 32
- Local 32 ( 0.4%) 1
- MacCall 32 ( 0.4%) 1
- Expr 96 ( 1.1%) 3
Param 160 ( 1.8%) 4 40
FnDecl 200 ( 2.3%) 5 40
Param 160 ( 1.9%) 4 40
FnDecl 200 ( 2.4%) 5 40
Variant 240 ( 2.8%) 2 120
Block 288 ( 3.3%) 6 48
GenericBound 352 ( 4.0%) 4 88
- Trait 352 ( 4.0%) 4
AssocItem 480 ( 5.5%) 4 120
- TyAlias 240 ( 2.8%) 2
- Fn 240 ( 2.8%) 2
GenericParam 520 ( 6.0%) 5 104
PathSegment 720 ( 8.3%) 30 24
Expr 832 ( 9.6%) 8 104
Block 288 ( 3.4%) 6 48
GenericBound 352 ( 4.2%) 4 88
- Trait 352 ( 4.2%) 4
AssocItem 416 ( 4.9%) 4 104
- TyAlias 208 ( 2.5%) 2
- Fn 208 ( 2.5%) 2
GenericParam 520 ( 6.1%) 5 104
PathSegment 720 ( 8.5%) 30 24
Expr 832 ( 9.8%) 8 104
- Path 104 ( 1.2%) 1
- Match 104 ( 1.2%) 1
- Struct 104 ( 1.2%) 1
- Lit 208 ( 2.4%) 2
- Block 312 ( 3.6%) 3
Pat 840 ( 9.7%) 7 120
- Lit 208 ( 2.5%) 2
- Block 312 ( 3.7%) 3
Pat 840 ( 9.9%) 7 120
- Struct 120 ( 1.4%) 1
- Wild 120 ( 1.4%) 1
- Ident 600 ( 6.9%) 5
Ty 1_344 (15.5%) 14 96
- Ident 600 ( 7.1%) 5
Ty 1_344 (15.9%) 14 96
- Rptr 96 ( 1.1%) 1
- Ptr 96 ( 1.1%) 1
- ImplicitSelf 192 ( 2.2%) 2
- Path 960 (11.0%) 10
Item 1_800 (20.7%) 9 200
- Trait 200 ( 2.3%) 1
- Enum 200 ( 2.3%) 1
- ForeignMod 200 ( 2.3%) 1
- Impl 200 ( 2.3%) 1
- Fn 400 ( 4.6%) 2
- Use 600 ( 6.9%) 3
- ImplicitSelf 192 ( 2.3%) 2
- Path 960 (11.4%) 10
Item 1_656 (19.6%) 9 184
- Trait 184 ( 2.2%) 1
- Enum 184 ( 2.2%) 1
- ForeignMod 184 ( 2.2%) 1
- Impl 184 ( 2.2%) 1
- Fn 368 ( 4.4%) 2
- Use 552 ( 6.5%) 3
----------------------------------------------------------------
Total 8_696
Total 8_456
POST EXPANSION AST STATS
@ -63,15 +63,15 @@ POST EXPANSION AST STATS
Name Accumulated Size Count Item Size
----------------------------------------------------------------
ExprField 48 ( 0.5%) 1 48
Crate 56 ( 0.6%) 1 56
GenericArgs 64 ( 0.7%) 1 64
- AngleBracketed 64 ( 0.7%) 1
Local 72 ( 0.8%) 1 72
WherePredicate 72 ( 0.8%) 1 72
- BoundPredicate 72 ( 0.8%) 1
Crate 72 ( 0.8%) 1 72
Arm 96 ( 1.0%) 2 48
ForeignItem 112 ( 1.2%) 1 112
- Fn 112 ( 1.2%) 1
ForeignItem 96 ( 1.0%) 1 96
- Fn 96 ( 1.0%) 1
InlineAsm 120 ( 1.3%) 1 120
Attribute 128 ( 1.4%) 4 32
- DocComment 32 ( 0.3%) 1
@ -82,42 +82,42 @@ Stmt 160 ( 1.7%) 5 32
- Semi 32 ( 0.3%) 1
- Expr 96 ( 1.0%) 3
Param 160 ( 1.7%) 4 40
FnDecl 200 ( 2.1%) 5 40
Variant 240 ( 2.5%) 2 120
Block 288 ( 3.0%) 6 48
GenericBound 352 ( 3.7%) 4 88
- Trait 352 ( 3.7%) 4
AssocItem 480 ( 5.1%) 4 120
- TyAlias 240 ( 2.5%) 2
- Fn 240 ( 2.5%) 2
GenericParam 520 ( 5.5%) 5 104
PathSegment 792 ( 8.4%) 33 24
Pat 840 ( 8.9%) 7 120
FnDecl 200 ( 2.2%) 5 40
Variant 240 ( 2.6%) 2 120
Block 288 ( 3.1%) 6 48
GenericBound 352 ( 3.8%) 4 88
- Trait 352 ( 3.8%) 4
AssocItem 416 ( 4.5%) 4 104
- TyAlias 208 ( 2.3%) 2
- Fn 208 ( 2.3%) 2
GenericParam 520 ( 5.7%) 5 104
PathSegment 792 ( 8.6%) 33 24
Pat 840 ( 9.1%) 7 120
- Struct 120 ( 1.3%) 1
- Wild 120 ( 1.3%) 1
- Ident 600 ( 6.3%) 5
Expr 936 ( 9.9%) 9 104
- Ident 600 ( 6.5%) 5
Expr 936 (10.2%) 9 104
- Path 104 ( 1.1%) 1
- Match 104 ( 1.1%) 1
- Struct 104 ( 1.1%) 1
- InlineAsm 104 ( 1.1%) 1
- Lit 208 ( 2.2%) 2
- Block 312 ( 3.3%) 3
Ty 1_344 (14.2%) 14 96
- Lit 208 ( 2.3%) 2
- Block 312 ( 3.4%) 3
Ty 1_344 (14.6%) 14 96
- Rptr 96 ( 1.0%) 1
- Ptr 96 ( 1.0%) 1
- ImplicitSelf 192 ( 2.0%) 2
- Path 960 (10.2%) 10
Item 2_200 (23.3%) 11 200
- Trait 200 ( 2.1%) 1
- Enum 200 ( 2.1%) 1
- ExternCrate 200 ( 2.1%) 1
- ForeignMod 200 ( 2.1%) 1
- Impl 200 ( 2.1%) 1
- Fn 400 ( 4.2%) 2
- Use 800 ( 8.5%) 4
- ImplicitSelf 192 ( 2.1%) 2
- Path 960 (10.5%) 10
Item 2_024 (22.0%) 11 184
- Trait 184 ( 2.0%) 1
- Enum 184 ( 2.0%) 1
- ExternCrate 184 ( 2.0%) 1
- ForeignMod 184 ( 2.0%) 1
- Impl 184 ( 2.0%) 1
- Fn 368 ( 4.0%) 2
- Use 736 ( 8.0%) 4
----------------------------------------------------------------
Total 9_456
Total 9_184
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`.
pub(crate) fn filter_inline_attrs(
attrs: &[ast::Attribute],
outer_span: Span,
) -> Vec<ast::Attribute> {
pub(crate) fn filter_inline_attrs(attrs: &[ast::Attribute], outer_span: Span) -> ast::AttrVec {
attrs
.iter()
.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.
// Should we have another struct for top-level use items rather than reusing this?
visibility: Option<ast::Visibility>,
attrs: Option<Vec<ast::Attribute>>,
attrs: Option<ast::AttrVec>,
}
impl PartialEq for UseTree {
@ -417,7 +417,7 @@ impl UseTree {
list_item: Option<ListItem>,
visibility: Option<ast::Visibility>,
opt_lo: Option<BytePos>,
attrs: Option<Vec<ast::Attribute>>,
attrs: Option<ast::AttrVec>,
) -> UseTree {
let span = if let Some(lo) = opt_lo {
mk_sp(lo, a.span.hi())

View File

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

View File

@ -109,7 +109,7 @@ impl<'a> Parser<'a> {
sess: &'a ParseSess,
path: &Path,
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 mut parser = new_parser_from_file(sess.inner(), path, Some(span));
match parser.parse_mod(&TokenKind::Eof) {