Skip to content

Commit a9ff07e

Browse files
committed
Convert StripUnconfigured to MutVisitor
1 parent f2060b6 commit a9ff07e

File tree

9 files changed

+276
-104
lines changed

9 files changed

+276
-104
lines changed

src/librustc_data_structures/thin_vec.rs

+8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ impl<T> ThinVec<T> {
88
pub fn new() -> Self {
99
ThinVec(None)
1010
}
11+
12+
#[inline]
13+
pub fn as_vec(&mut self) -> Option<&mut Vec<T>> {
14+
match *self {
15+
ThinVec(None) => None,
16+
ThinVec(Some(ref mut vec)) => Some(vec),
17+
}
18+
}
1119
}
1220

1321
impl<T> From<Vec<T>> for ThinVec<T> {

src/libsyntax/ast.rs

-7
Original file line numberDiff line numberDiff line change
@@ -2114,13 +2114,6 @@ impl VariantData {
21142114
_ => &[],
21152115
}
21162116
}
2117-
pub fn fields_mut(&mut self) -> &mut [StructField] {
2118-
match *self {
2119-
VariantData::Struct(ref mut fields, _) |
2120-
VariantData::Tuple(ref mut fields, _) => fields,
2121-
_ => &mut [],
2122-
}
2123-
}
21242117
pub fn id(&self) -> NodeId {
21252118
match *self {
21262119
VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id,

src/libsyntax/attr/mod.rs

+39-1
Original file line numberDiff line numberDiff line change
@@ -695,11 +695,17 @@ impl LitKind {
695695

696696
pub trait HasAttrs: Sized {
697697
fn attrs(&self) -> &[ast::Attribute];
698+
fn attrs_mut(&mut self) -> Option<&mut Vec<ast::Attribute>>;
698699
fn map_attrs<F: FnOnce(Vec<ast::Attribute>) -> Vec<ast::Attribute>>(self, f: F) -> Self;
699700
}
700701

701702
impl<T: HasAttrs> HasAttrs for Spanned<T> {
702-
fn attrs(&self) -> &[ast::Attribute] { self.node.attrs() }
703+
fn attrs(&self) -> &[ast::Attribute] {
704+
self.node.attrs()
705+
}
706+
fn attrs_mut(&mut self) -> Option<&mut Vec<ast::Attribute>> {
707+
self.node.attrs_mut()
708+
}
703709
fn map_attrs<F: FnOnce(Vec<ast::Attribute>) -> Vec<ast::Attribute>>(self, f: F) -> Self {
704710
respan(self.span, self.node.map_attrs(f))
705711
}
@@ -709,6 +715,9 @@ impl HasAttrs for Vec<Attribute> {
709715
fn attrs(&self) -> &[Attribute] {
710716
self
711717
}
718+
fn attrs_mut(&mut self) -> Option<&mut Vec<ast::Attribute>> {
719+
Some(self)
720+
}
712721
fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
713722
f(self)
714723
}
@@ -718,6 +727,9 @@ impl HasAttrs for ThinVec<Attribute> {
718727
fn attrs(&self) -> &[Attribute] {
719728
self
720729
}
730+
fn attrs_mut(&mut self) -> Option<&mut Vec<ast::Attribute>> {
731+
self.as_vec()
732+
}
721733
fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
722734
f(self.into()).into()
723735
}
@@ -727,6 +739,9 @@ impl<T: HasAttrs + 'static> HasAttrs for P<T> {
727739
fn attrs(&self) -> &[Attribute] {
728740
(**self).attrs()
729741
}
742+
fn attrs_mut(&mut self) -> Option<&mut Vec<ast::Attribute>> {
743+
(**self).attrs_mut()
744+
}
730745
fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
731746
self.map(|t| t.map_attrs(f))
732747
}
@@ -745,6 +760,18 @@ impl HasAttrs for StmtKind {
745760
}
746761
}
747762

763+
fn attrs_mut(&mut self) -> Option<&mut Vec<ast::Attribute>> {
764+
match *self {
765+
StmtKind::Local(ref mut local) => local.attrs_mut(),
766+
StmtKind::Item(..) => None,
767+
StmtKind::Expr(ref mut expr) | StmtKind::Semi(ref mut expr) => expr.attrs_mut(),
768+
StmtKind::Mac(ref mut mac) => {
769+
let (_, _, ref mut attrs) = **mac;
770+
attrs.attrs_mut()
771+
}
772+
}
773+
}
774+
748775
fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
749776
match self {
750777
StmtKind::Local(local) => StmtKind::Local(local.map_attrs(f)),
@@ -760,6 +787,9 @@ impl HasAttrs for StmtKind {
760787

761788
impl HasAttrs for Stmt {
762789
fn attrs(&self) -> &[ast::Attribute] { self.node.attrs() }
790+
fn attrs_mut(&mut self) -> Option<&mut Vec<ast::Attribute>> {
791+
self.node.attrs_mut()
792+
}
763793
fn map_attrs<F: FnOnce(Vec<ast::Attribute>) -> Vec<ast::Attribute>>(self, f: F) -> Self {
764794
Stmt { id: self.id, node: self.node.map_attrs(f), span: self.span }
765795
}
@@ -770,6 +800,10 @@ impl HasAttrs for GenericParam {
770800
&self.attrs
771801
}
772802

803+
fn attrs_mut(&mut self) -> Option<&mut Vec<ast::Attribute>> {
804+
self.attrs.attrs_mut()
805+
}
806+
773807
fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(mut self, f: F) -> Self {
774808
self.attrs = self.attrs.map_attrs(f);
775809
self
@@ -783,6 +817,10 @@ macro_rules! derive_has_attrs {
783817
&self.attrs
784818
}
785819

820+
fn attrs_mut(&mut self) -> Option<&mut Vec<ast::Attribute>> {
821+
self.attrs.attrs_mut()
822+
}
823+
786824
fn map_attrs<F>(mut self, f: F) -> Self
787825
where F: FnOnce(Vec<Attribute>) -> Vec<Attribute>,
788826
{

src/libsyntax/config.rs

+99-44
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ use feature_gate::{
66
get_features,
77
GateIssue,
88
};
9-
use {fold, attr};
9+
use attr;
1010
use ast;
1111
use source_map::Spanned;
1212
use edition::Edition;
1313
use parse::{token, ParseSess};
1414
use smallvec::SmallVec;
1515
use errors::Applicability;
16+
use visit_mut::{self, Action};
1617

1718
use ptr::P;
1819

@@ -64,8 +65,26 @@ macro_rules! configure {
6465
}
6566

6667
impl<'a> StripUnconfigured<'a> {
67-
pub fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
68-
let node = self.process_cfg_attrs(node);
68+
pub fn keep_then<T: HasAttrs, R>(
69+
&mut self,
70+
node: &mut T,
71+
then: impl FnOnce(&mut Self, &mut T)
72+
) -> Action<R> {
73+
if likely!(self.keep(node)) {
74+
then(self, node);
75+
Action::Reuse
76+
} else {
77+
Action::Remove
78+
}
79+
}
80+
81+
pub fn keep<T: HasAttrs>(&mut self, node: &mut T) -> bool {
82+
self.process_cfg_attrs(node);
83+
self.in_cfg(node.attrs())
84+
}
85+
86+
pub fn configure<T: HasAttrs>(&mut self, mut node: T) -> Option<T> {
87+
self.process_cfg_attrs(&mut node);
6988
if self.in_cfg(node.attrs()) { Some(node) } else { None }
7089
}
7190

@@ -75,10 +94,23 @@ impl<'a> StripUnconfigured<'a> {
7594
/// Gives compiler warnigns if any `cfg_attr` does not contain any
7695
/// attributes and is in the original source code. Gives compiler errors if
7796
/// the syntax of any `cfg_attr` is incorrect.
78-
pub fn process_cfg_attrs<T: HasAttrs>(&mut self, node: T) -> T {
79-
node.map_attrs(|attrs| {
80-
attrs.into_iter().flat_map(|attr| self.process_cfg_attr(attr)).collect()
81-
})
97+
pub fn process_cfg_attrs<T: HasAttrs>(&mut self, node: &mut T) {
98+
let attrs = if let Some(attrs) = node.attrs_mut() {
99+
attrs
100+
} else {
101+
// No attributes so nothing to do
102+
return;
103+
};
104+
if likely!(attrs.is_empty()) {
105+
return;
106+
}
107+
if likely!(!attrs.iter().any(|attr| attr.check_name("cfg_attr"))) {
108+
return;
109+
}
110+
let new_attrs: Vec<_> = attrs.drain(..).flat_map(|attr| {
111+
self.process_cfg_attr(attr)
112+
}).collect();
113+
*attrs = new_attrs;
82114
}
83115

84116
/// Parse and expand a single `cfg_attr` attribute into a list of attributes
@@ -88,9 +120,9 @@ impl<'a> StripUnconfigured<'a> {
88120
/// Gives a compiler warning when the `cfg_attr` contains no attributes and
89121
/// is in the original source file. Gives a compiler error if the syntax of
90122
/// the attribute is incorrect
91-
fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec<ast::Attribute> {
123+
fn process_cfg_attr(&mut self, attr: ast::Attribute) -> SmallVec<[ast::Attribute; 1]> {
92124
if !attr.check_name("cfg_attr") {
93-
return vec![attr];
125+
return smallvec![attr];
94126
}
95127

96128
let (cfg_predicate, expanded_attrs) = match attr.parse(self.sess, |parser| {
@@ -100,7 +132,7 @@ impl<'a> StripUnconfigured<'a> {
100132
parser.expect(&token::Comma)?;
101133

102134
// Presumably, the majority of the time there will only be one attr.
103-
let mut expanded_attrs = Vec::with_capacity(1);
135+
let mut expanded_attrs: SmallVec<[_; 1]> = SmallVec::new();
104136

105137
while !parser.check(&token::CloseDelim(token::Paren)) {
106138
let lo = parser.span.lo();
@@ -115,7 +147,7 @@ impl<'a> StripUnconfigured<'a> {
115147
Ok(result) => result,
116148
Err(mut e) => {
117149
e.emit();
118-
return Vec::new();
150+
return SmallVec::new();
119151
}
120152
};
121153

@@ -141,7 +173,7 @@ impl<'a> StripUnconfigured<'a> {
141173
}))
142174
.collect()
143175
} else {
144-
Vec::new()
176+
SmallVec::new()
145177
}
146178
}
147179

@@ -286,7 +318,7 @@ impl<'a> StripUnconfigured<'a> {
286318
}
287319
}
288320

289-
pub fn configure_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
321+
pub fn configure_expr(&mut self, expr: &mut ast::Expr) {
290322
self.visit_expr_attrs(expr.attrs());
291323

292324
// If an expr is valid to cfg away it will have been removed by the
@@ -300,7 +332,6 @@ impl<'a> StripUnconfigured<'a> {
300332
let msg = "removing an expression is not supported in this position";
301333
self.sess.span_diagnostic.span_err(attr.span, msg);
302334
}
303-
304335
self.process_cfg_attrs(expr)
305336
}
306337

@@ -343,57 +374,81 @@ impl<'a> StripUnconfigured<'a> {
343374
}
344375
}
345376

346-
impl<'a> fold::Folder for StripUnconfigured<'a> {
347-
fn fold_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod {
348-
let foreign_mod = self.configure_foreign_mod(foreign_mod);
349-
fold::noop_fold_foreign_mod(foreign_mod, self)
377+
impl<'a> visit_mut::MutVisitor for StripUnconfigured<'a> {
378+
fn visit_foreign_item(&mut self, i: &mut ast::ForeignItem) -> Action<ast::ForeignItem> {
379+
self.keep_then(i, |this, i| visit_mut::walk_foreign_item(this, i))
350380
}
351381

352-
fn fold_item_kind(&mut self, item: ast::ItemKind) -> ast::ItemKind {
353-
let item = self.configure_item_kind(item);
354-
fold::noop_fold_item_kind(item, self)
382+
fn visit_variant(
383+
&mut self,
384+
v: &mut ast::Variant,
385+
g: &mut ast::Generics,
386+
item_id: ast::NodeId
387+
) -> Action<ast::Variant> {
388+
if likely!(self.keep(v)) {
389+
visit_mut::walk_variant(self, v, g, item_id);
390+
Action::Reuse
391+
} else {
392+
Action::Remove
393+
}
394+
}
395+
396+
fn visit_struct_field(&mut self, s: &mut ast::StructField) -> Action<ast::StructField> {
397+
self.keep_then(s, |this, s| visit_mut::walk_struct_field(this, s))
355398
}
356399

357-
fn fold_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
358-
let mut expr = self.configure_expr(expr).into_inner();
359-
expr.node = self.configure_expr_kind(expr.node);
360-
P(fold::noop_fold_expr(expr, self))
400+
fn visit_arm(&mut self, a: &mut ast::Arm) -> Action<ast::Arm> {
401+
self.keep_then(a, |this, a| visit_mut::walk_arm(this, a))
361402
}
362403

363-
fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
364-
let mut expr = configure!(self, expr).into_inner();
365-
expr.node = self.configure_expr_kind(expr.node);
366-
Some(P(fold::noop_fold_expr(expr, self)))
404+
fn visit_field(&mut self, field: &mut ast::Field) -> Action<ast::Field> {
405+
self.keep_then(field, |this, field| visit_mut::walk_field(this, field))
367406
}
368407

369-
fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> {
370-
match self.configure_stmt(stmt) {
371-
Some(stmt) => fold::noop_fold_stmt(stmt, self),
372-
None => return SmallVec::new(),
408+
fn visit_opt_expr(&mut self, ex: &mut ast::Expr) -> bool {
409+
if likely!(self.keep(ex)) {
410+
visit_mut::walk_expr(self, ex);
411+
true
412+
} else {
413+
false
373414
}
374415
}
375416

376-
fn fold_item(&mut self, item: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
377-
fold::noop_fold_item(configure!(self, item), self)
417+
fn visit_expr(&mut self, ex: &mut ast::Expr) {
418+
self.configure_expr(ex);
419+
visit_mut::walk_expr(self, ex)
378420
}
379421

380-
fn fold_impl_item(&mut self, item: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]>
381-
{
382-
fold::noop_fold_impl_item(configure!(self, item), self)
422+
fn visit_stmt(&mut self, s: &mut ast::Stmt) -> Action<ast::Stmt> {
423+
if likely!(self.keep(s)) {
424+
visit_mut::walk_stmt(self, s)
425+
} else {
426+
Action::Remove
427+
}
428+
}
429+
430+
fn visit_item(&mut self, i: &mut P<ast::Item>) -> Action<P<ast::Item>> {
431+
self.keep_then(i, |this, i| visit_mut::walk_item(this, i))
432+
}
433+
434+
fn visit_trait_item(&mut self, i: &mut ast::TraitItem) -> Action<ast::TraitItem> {
435+
self.keep_then(i, |this, i| visit_mut::walk_trait_item(this, i))
383436
}
384437

385-
fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> {
386-
fold::noop_fold_trait_item(configure!(self, item), self)
438+
fn visit_impl_item(&mut self, ii: &mut ast::ImplItem) -> Action<ast::ImplItem> {
439+
self.keep_then(ii, |this, ii| visit_mut::walk_impl_item(this, ii))
387440
}
388441

389-
fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
442+
fn visit_mac(&mut self, _mac: &mut ast::Mac) {
390443
// Don't configure interpolated AST (cf. issue #34171).
391444
// Interpolated AST will get configured once the surrounding tokens are parsed.
392-
mac
393445
}
394446

395-
fn fold_pat(&mut self, pattern: P<ast::Pat>) -> P<ast::Pat> {
396-
fold::noop_fold_pat(self.configure_pat(pattern), self)
447+
fn visit_field_pat(
448+
&mut self,
449+
p: &mut Spanned<ast::FieldPat>
450+
) -> Action<Spanned<ast::FieldPat>> {
451+
self.keep_then(p, |this, p| visit_mut::walk_field_pat(this, p))
397452
}
398453
}
399454

src/libsyntax/ext/base.rs

+11
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ impl HasAttrs for Annotatable {
4747
}
4848
}
4949

50+
fn attrs_mut(&mut self) -> Option<&mut Vec<Attribute>> {
51+
match *self {
52+
Annotatable::Item(ref mut item) => item.attrs.attrs_mut(),
53+
Annotatable::TraitItem(ref mut trait_item) => trait_item.attrs.attrs_mut(),
54+
Annotatable::ImplItem(ref mut impl_item) => impl_item.attrs.attrs_mut(),
55+
Annotatable::ForeignItem(ref mut foreign_item) => foreign_item.attrs.attrs_mut(),
56+
Annotatable::Stmt(ref mut stmt) => stmt.attrs_mut(),
57+
Annotatable::Expr(ref mut expr) => expr.attrs.attrs_mut(),
58+
}
59+
}
60+
5061
fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
5162
match self {
5263
Annotatable::Item(item) => Annotatable::Item(item.map_attrs(f)),

0 commit comments

Comments
 (0)