Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3ad7d38

Browse files
authoredAug 14, 2019
Rollup merge of rust-lang#63537 - petrochenkov:novisit, r=alexcrichton
expand: Unimplement `MutVisitor` on `MacroExpander` Each call to `fully_expand_fragment` is something unique, interesting, and requiring attention. It represents a "root" of expansion and its use means that something unusual is happening, like eager expansion or expansion performed outside of the primary expansion pass. So, it shouldn't hide under a generic visitor call. Also, from all the implemented visitor methods only two were actually used. cc rust-lang#63468 (comment)
2 parents fc29781 + d416ebe commit 3ad7d38

File tree

4 files changed

+33
-35
lines changed

4 files changed

+33
-35
lines changed
 

‎src/libsyntax/ext/base.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -920,8 +920,10 @@ pub fn expr_to_spanned_string<'a>(
920920
// Update `expr.span`'s ctxt now in case expr is an `include!` macro invocation.
921921
expr.span = expr.span.apply_mark(cx.current_expansion.id);
922922

923-
// we want to be able to handle e.g., `concat!("foo", "bar")`
924-
cx.expander().visit_expr(&mut expr);
923+
// Perform eager expansion on the expression.
924+
// We want to be able to handle e.g., `concat!("foo", "bar")`.
925+
let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();
926+
925927
Err(match expr.node {
926928
ast::ExprKind::Lit(ref l) => match l.node {
927929
ast::LitKind::Str(s, style) => return Ok(respan(expr.span, (s, style))),
@@ -986,8 +988,12 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt<'_>,
986988
let mut p = cx.new_parser_from_tts(tts);
987989
let mut es = Vec::new();
988990
while p.token != token::Eof {
989-
let mut expr = panictry!(p.parse_expr());
990-
cx.expander().visit_expr(&mut expr);
991+
let expr = panictry!(p.parse_expr());
992+
993+
// Perform eager expansion on the expression.
994+
// We want to be able to handle e.g., `concat!("foo", "bar")`.
995+
let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();
996+
991997
es.push(expr);
992998
if p.eat(&token::Comma) {
993999
continue;

‎src/libsyntax/ext/expand.rs

+3-15
Original file line numberDiff line numberDiff line change
@@ -116,18 +116,6 @@ macro_rules! ast_fragments {
116116
}
117117
}
118118

119-
impl<'a, 'b> MutVisitor for MacroExpander<'a, 'b> {
120-
fn filter_map_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
121-
self.expand_fragment(AstFragment::OptExpr(Some(expr))).make_opt_expr()
122-
}
123-
$($(fn $mut_visit_ast(&mut self, ast: &mut $AstTy) {
124-
visit_clobber(ast, |ast| self.expand_fragment(AstFragment::$Kind(ast)).$make_ast());
125-
})?)*
126-
$($(fn $flat_map_ast_elt(&mut self, ast_elt: <$AstTy as IntoIterator>::Item) -> $AstTy {
127-
self.expand_fragment(AstFragment::$Kind(smallvec![ast_elt])).$make_ast()
128-
})?)*
129-
}
130-
131119
impl<'a> MacResult for crate::ext::tt::macro_rules::ParserAnyMacro<'a> {
132120
$(fn $make_ast(self: Box<crate::ext::tt::macro_rules::ParserAnyMacro<'a>>)
133121
-> Option<$AstTy> {
@@ -265,7 +253,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
265253
tokens: None,
266254
})]);
267255

268-
match self.expand_fragment(krate_item).make_items().pop().map(P::into_inner) {
256+
match self.fully_expand_fragment(krate_item).make_items().pop().map(P::into_inner) {
269257
Some(ast::Item { attrs, node: ast::ItemKind::Mod(module), .. }) => {
270258
krate.attrs = attrs;
271259
krate.module = module;
@@ -285,8 +273,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
285273
krate
286274
}
287275

288-
// Fully expand all macro invocations in this AST fragment.
289-
fn expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragment {
276+
// Recursively expand all macro invocations in this AST fragment.
277+
pub fn fully_expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragment {
290278
let orig_expansion_data = self.cx.current_expansion.clone();
291279
self.cx.current_expansion.depth = 0;
292280

‎src/libsyntax_ext/proc_macro_harness.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
use std::mem;
22

3+
use smallvec::smallvec;
34
use syntax::ast::{self, Ident};
45
use syntax::attr;
56
use syntax::source_map::{ExpnInfo, ExpnKind, respan};
67
use syntax::ext::base::{ExtCtxt, MacroKind};
7-
use syntax::ext::expand::ExpansionConfig;
8+
use syntax::ext::expand::{AstFragment, ExpansionConfig};
89
use syntax::ext::hygiene::ExpnId;
910
use syntax::ext::proc_macro::is_proc_macro_attr;
10-
use syntax::mut_visit::MutVisitor;
1111
use syntax::parse::ParseSess;
1212
use syntax::ptr::P;
1313
use syntax::symbol::{kw, sym};
1414
use syntax::visit::{self, Visitor};
15-
1615
use syntax_pos::{Span, DUMMY_SP};
1716

1817
struct ProcMacroDerive {
@@ -409,5 +408,7 @@ fn mk_decls(
409408
i
410409
});
411410

412-
cx.monotonic_expander().flat_map_item(module).pop().unwrap()
411+
// Integrate the new module into existing module structures.
412+
let module = AstFragment::Items(smallvec![module]);
413+
cx.monotonic_expander().fully_expand_fragment(module).make_items().pop().unwrap()
413414
}

‎src/libsyntax_ext/test_harness.rs

+15-12
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use syntax::ast::{self, Ident};
66
use syntax::attr;
77
use syntax::entry::{self, EntryPointType};
88
use syntax::ext::base::{ExtCtxt, Resolver};
9-
use syntax::ext::expand::ExpansionConfig;
9+
use syntax::ext::expand::{AstFragment, ExpansionConfig};
1010
use syntax::ext::hygiene::{ExpnId, MacroKind};
1111
use syntax::feature_gate::Features;
1212
use syntax::mut_visit::{*, ExpectOne};
@@ -74,12 +74,7 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
7474
noop_visit_crate(c, self);
7575

7676
// Create a main function to run our tests
77-
let test_main = {
78-
let unresolved = mk_main(&mut self.cx);
79-
self.cx.ext_cx.monotonic_expander().flat_map_item(unresolved).pop().unwrap()
80-
};
81-
82-
c.module.items.push(test_main);
77+
c.module.items.push(mk_main(&mut self.cx));
8378
}
8479

8580
fn flat_map_item(&mut self, i: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
@@ -216,17 +211,22 @@ fn mk_reexport_mod(cx: &mut TestCtxt<'_>,
216211
let name = Ident::from_str("__test_reexports").gensym();
217212
let parent = if parent == ast::DUMMY_NODE_ID { ast::CRATE_NODE_ID } else { parent };
218213
cx.ext_cx.current_expansion.id = cx.ext_cx.resolver.get_module_scope(parent);
219-
let it = cx.ext_cx.monotonic_expander().flat_map_item(P(ast::Item {
214+
let module = P(ast::Item {
220215
ident: name,
221216
attrs: Vec::new(),
222217
id: ast::DUMMY_NODE_ID,
223218
node: ast::ItemKind::Mod(reexport_mod),
224219
vis: dummy_spanned(ast::VisibilityKind::Public),
225220
span: DUMMY_SP,
226221
tokens: None,
227-
})).pop().unwrap();
222+
});
228223

229-
(it, name)
224+
// Integrate the new module into existing module structures.
225+
let module = AstFragment::Items(smallvec![module]);
226+
let module =
227+
cx.ext_cx.monotonic_expander().fully_expand_fragment(module).make_items().pop().unwrap();
228+
229+
(module, name)
230230
}
231231

232232
/// Crawl over the crate, inserting test reexports and the test main function
@@ -321,16 +321,19 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
321321
None => Ident::from_str_and_span("main", sp).gensym(),
322322
};
323323

324-
P(ast::Item {
324+
let main = P(ast::Item {
325325
ident: main_id,
326326
attrs: vec![main_attr],
327327
id: ast::DUMMY_NODE_ID,
328328
node: main,
329329
vis: dummy_spanned(ast::VisibilityKind::Public),
330330
span: sp,
331331
tokens: None,
332-
})
332+
});
333333

334+
// Integrate the new item into existing module structures.
335+
let main = AstFragment::Items(smallvec![main]);
336+
cx.ext_cx.monotonic_expander().fully_expand_fragment(main).make_items().pop().unwrap()
334337
}
335338

336339
fn path_name_i(idents: &[Ident]) -> String {

0 commit comments

Comments
 (0)
Please sign in to comment.