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:
parent
650bff80a6
commit
619b8abaa6
49 changed files with 352 additions and 392 deletions
|
@ -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),
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue