Skip to content

Commit 361077d

Browse files
committed
Strip unconfigured nodes in the InvocationCollector fold.
1 parent 8691b69 commit 361077d

File tree

2 files changed

+65
-96
lines changed

2 files changed

+65
-96
lines changed

src/libsyntax/config.rs

+8-86
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,13 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use attr::HasAttrs;
11+
use attr::{self, HasAttrs};
1212
use feature_gate::{emit_feature_err, EXPLAIN_STMT_ATTR_SYNTAX, Features, get_features, GateIssue};
13-
use {fold, attr};
1413
use ast;
1514
use codemap::{Spanned, respan};
16-
use parse::{ParseSess, token};
15+
use parse::ParseSess;
1716
use ptr::P;
1817

19-
use util::small_vector::SmallVector;
20-
2118
/// A folder that strips out items that do not belong in the current configuration.
2219
pub struct StripUnconfigured<'a> {
2320
pub config: &'a ast::CrateConfig,
@@ -61,7 +58,7 @@ pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool)
6158
}
6259

6360
impl<'a> StripUnconfigured<'a> {
64-
fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
61+
pub fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
6562
let node = self.process_cfg_attrs(node);
6663
if self.in_cfg(node.attrs()) { Some(node) } else { None }
6764
}
@@ -157,7 +154,7 @@ impl<'a> StripUnconfigured<'a> {
157154
}
158155
}
159156

160-
fn configure_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod {
157+
pub fn configure_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod {
161158
ast::ForeignMod {
162159
abi: foreign_mod.abi,
163160
items: foreign_mod.items.into_iter().filter_map(|item| self.configure(item)).collect(),
@@ -178,7 +175,7 @@ impl<'a> StripUnconfigured<'a> {
178175
}
179176
}
180177

181-
fn configure_item_kind(&mut self, item: ast::ItemKind) -> ast::ItemKind {
178+
pub fn configure_item_kind(&mut self, item: ast::ItemKind) -> ast::ItemKind {
182179
match item {
183180
ast::ItemKind::Struct(def, generics) => {
184181
ast::ItemKind::Struct(self.configure_variant_data(def), generics)
@@ -208,7 +205,7 @@ impl<'a> StripUnconfigured<'a> {
208205
}
209206
}
210207

211-
fn configure_expr_kind(&mut self, expr_kind: ast::ExprKind) -> ast::ExprKind {
208+
pub fn configure_expr_kind(&mut self, expr_kind: ast::ExprKind) -> ast::ExprKind {
212209
if let ast::ExprKind::Match(m, arms) = expr_kind {
213210
let arms = arms.into_iter().filter_map(|a| self.configure(a)).collect();
214211
ast::ExprKind::Match(m, arms)
@@ -217,7 +214,7 @@ impl<'a> StripUnconfigured<'a> {
217214
}
218215
}
219216

220-
fn configure_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
217+
pub fn configure_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
221218
self.visit_stmt_or_expr_attrs(expr.attrs());
222219

223220
// If an expr is valid to cfg away it will have been removed by the
@@ -235,87 +232,12 @@ impl<'a> StripUnconfigured<'a> {
235232
self.process_cfg_attrs(expr)
236233
}
237234

238-
fn configure_stmt(&mut self, stmt: ast::Stmt) -> Option<ast::Stmt> {
235+
pub fn configure_stmt(&mut self, stmt: ast::Stmt) -> Option<ast::Stmt> {
239236
self.visit_stmt_or_expr_attrs(stmt.attrs());
240237
self.configure(stmt)
241238
}
242239
}
243240

244-
impl<'a> fold::Folder for StripUnconfigured<'a> {
245-
fn fold_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod {
246-
let foreign_mod = self.configure_foreign_mod(foreign_mod);
247-
fold::noop_fold_foreign_mod(foreign_mod, self)
248-
}
249-
250-
fn fold_item_kind(&mut self, item: ast::ItemKind) -> ast::ItemKind {
251-
let item = self.configure_item_kind(item);
252-
fold::noop_fold_item_kind(item, self)
253-
}
254-
255-
fn fold_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
256-
let mut expr = self.configure_expr(expr).unwrap();
257-
expr.node = self.configure_expr_kind(expr.node);
258-
259-
P(fold::noop_fold_expr(expr, self))
260-
}
261-
262-
fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
263-
let mut expr = match self.configure(expr) {
264-
Some(expr) => expr.unwrap(),
265-
None => return None,
266-
};
267-
expr.node = self.configure_expr_kind(expr.node);
268-
269-
Some(P(fold::noop_fold_expr(expr, self)))
270-
}
271-
272-
fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVector<ast::Stmt> {
273-
let stmt = match self.configure_stmt(stmt) {
274-
Some(stmt) => stmt,
275-
None => return SmallVector::zero(),
276-
};
277-
278-
fold::noop_fold_stmt(stmt, self)
279-
}
280-
281-
fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
282-
fold::noop_fold_mac(mac, self)
283-
}
284-
285-
fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
286-
let item = match self.configure(item) {
287-
Some(item) => item,
288-
None => return SmallVector::zero(),
289-
};
290-
291-
fold::noop_fold_item(item, self)
292-
}
293-
294-
fn fold_impl_item(&mut self, item: ast::ImplItem) -> SmallVector<ast::ImplItem> {
295-
let item = match self.configure(item) {
296-
Some(item) => item,
297-
None => return SmallVector::zero(),
298-
};
299-
300-
fold::noop_fold_impl_item(item, self)
301-
}
302-
303-
fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVector<ast::TraitItem> {
304-
let item = match self.configure(item) {
305-
Some(item) => item,
306-
None => return SmallVector::zero(),
307-
};
308-
309-
fold::noop_fold_trait_item(item, self)
310-
}
311-
312-
fn fold_interpolated(&mut self, nt: token::Nonterminal) -> token::Nonterminal {
313-
// Don't configure interpolated AST (c.f. #34171).
314-
// Interpolated AST will get configured once the surrounding tokens are parsed.
315-
nt
316-
}
317-
}
318-
319241
fn is_cfg(attr: &ast::Attribute) -> bool {
320242
attr.check_name("cfg")
321243
}

src/libsyntax/ext/expand.rs

+57-10
Original file line numberDiff line numberDiff line change
@@ -208,14 +208,23 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
208208
}
209209

210210
fn collect_invocations(&mut self, expansion: Expansion) -> (Expansion, Vec<Invocation>) {
211-
let expansion = expansion.fold_with(&mut StripUnconfigured {
212-
config: &self.cx.cfg,
213-
should_test: self.cx.ecfg.should_test,
214-
sess: self.cx.parse_sess,
215-
features: self.cx.ecfg.features,
216-
});
217-
let mut collector = InvocationCollector { cx: self.cx, invocations: Vec::new() };
218-
(expansion.fold_with(&mut collector), collector.invocations)
211+
let crate_config = mem::replace(&mut self.cx.cfg, Vec::new());
212+
let result = {
213+
let mut collector = InvocationCollector {
214+
cfg: StripUnconfigured {
215+
config: &crate_config,
216+
should_test: self.cx.ecfg.should_test,
217+
sess: self.cx.parse_sess,
218+
features: self.cx.ecfg.features,
219+
},
220+
cx: self.cx,
221+
invocations: Vec::new(),
222+
};
223+
(expansion.fold_with(&mut collector), collector.invocations)
224+
};
225+
226+
self.cx.cfg = crate_config;
227+
result
219228
}
220229

221230
fn expand_invoc(&mut self, invoc: Invocation) -> Expansion {
@@ -403,6 +412,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
403412

404413
struct InvocationCollector<'a, 'b: 'a> {
405414
cx: &'a mut ExtCtxt<'b>,
415+
cfg: StripUnconfigured<'a>,
406416
invocations: Vec<Invocation>,
407417
}
408418

@@ -479,7 +489,9 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
479489

480490
impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
481491
fn fold_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
482-
let expr = expr.unwrap();
492+
let mut expr = self.cfg.configure_expr(expr).unwrap();
493+
expr.node = self.cfg.configure_expr_kind(expr.node);
494+
483495
if let ast::ExprKind::Mac(mac) = expr.node {
484496
self.collect_bang(mac, expr.attrs.into(), expr.span, ExpansionKind::Expr).make_expr()
485497
} else {
@@ -488,7 +500,12 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
488500
}
489501

490502
fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
491-
let expr = expr.unwrap();
503+
let mut expr = match self.cfg.configure(expr) {
504+
Some(expr) => expr.unwrap(),
505+
None => return None,
506+
};
507+
expr.node = self.cfg.configure_expr_kind(expr.node);
508+
492509
if let ast::ExprKind::Mac(mac) = expr.node {
493510
self.collect_bang(mac, expr.attrs.into(), expr.span, ExpansionKind::OptExpr)
494511
.make_opt_expr()
@@ -511,6 +528,11 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
511528
}
512529

513530
fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVector<ast::Stmt> {
531+
let stmt = match self.cfg.configure_stmt(stmt) {
532+
Some(stmt) => stmt,
533+
None => return SmallVector::zero(),
534+
};
535+
514536
let (mac, style, attrs) = match stmt.node {
515537
StmtKind::Mac(mac) => mac.unwrap(),
516538
_ => return noop_fold_stmt(stmt, self),
@@ -540,6 +562,11 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
540562
}
541563

542564
fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
565+
let item = match self.cfg.configure(item) {
566+
Some(item) => item,
567+
None => return SmallVector::zero(),
568+
};
569+
543570
let (item, attr) = self.classify_item(item);
544571
if let Some(attr) = attr {
545572
let item = Annotatable::Item(item);
@@ -610,6 +637,11 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
610637
}
611638

612639
fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVector<ast::TraitItem> {
640+
let item = match self.cfg.configure(item) {
641+
Some(item) => item,
642+
None => return SmallVector::zero(),
643+
};
644+
613645
let (item, attr) = self.classify_item(item);
614646
if let Some(attr) = attr {
615647
let item = Annotatable::TraitItem(P(item));
@@ -626,6 +658,11 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
626658
}
627659

628660
fn fold_impl_item(&mut self, item: ast::ImplItem) -> SmallVector<ast::ImplItem> {
661+
let item = match self.cfg.configure(item) {
662+
Some(item) => item,
663+
None => return SmallVector::zero(),
664+
};
665+
629666
let (item, attr) = self.classify_item(item);
630667
if let Some(attr) = attr {
631668
let item = Annotatable::ImplItem(P(item));
@@ -653,6 +690,16 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
653690
_ => unreachable!(),
654691
}
655692
}
693+
694+
fn fold_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod {
695+
let foreign_mod = self.cfg.configure_foreign_mod(foreign_mod);
696+
noop_fold_foreign_mod(foreign_mod, self)
697+
}
698+
699+
fn fold_item_kind(&mut self, item: ast::ItemKind) -> ast::ItemKind {
700+
let item = self.cfg.configure_item_kind(item);
701+
noop_fold_item_kind(item, self)
702+
}
656703
}
657704

658705
pub struct ExpansionConfig<'feat> {

0 commit comments

Comments
 (0)