Skip to content

Commit 9594f16

Browse files
committed
Implement stackless placeholder expansion.
1 parent 361077d commit 9594f16

File tree

2 files changed

+22
-8
lines changed

2 files changed

+22
-8
lines changed

src/libsyntax/ext/expand.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ use ptr::P;
2626
use tokenstream::TokenTree;
2727
use util::small_vector::SmallVector;
2828

29-
use std::collections::HashMap;
3029
use std::mem;
3130
use std::path::PathBuf;
3231
use std::rc::Rc;
@@ -182,10 +181,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
182181

183182
// Fully expand all the invocations in `expansion`.
184183
fn expand(&mut self, expansion: Expansion) -> Expansion {
184+
self.cx.recursion_count = 0;
185185
let (expansion, mut invocations) = self.collect_invocations(expansion);
186186
invocations.reverse();
187187

188-
let mut expansions = HashMap::new();
188+
let mut expansions = vec![vec![(0, expansion)]];
189189
while let Some(invoc) = invocations.pop() {
190190
let Invocation { mark, module, depth, backtrace, .. } = invoc;
191191
self.cx.syntax_env.current_module = module;
@@ -198,13 +198,24 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
198198
self.cx.recursion_count = depth + 1;
199199
let (expansion, new_invocations) = self.collect_invocations(expansion);
200200

201-
expansions.insert(mark.as_u32(), expansion);
201+
if expansions.len() == depth {
202+
expansions.push(Vec::new());
203+
}
204+
expansions[depth].push((mark.as_u32(), expansion));
202205
if !self.single_step {
203206
invocations.extend(new_invocations.into_iter().rev());
204207
}
205208
}
206209

207-
expansion.fold_with(&mut PlaceholderExpander::new(expansions))
210+
let mut placeholder_expander = PlaceholderExpander::new();
211+
while let Some(expansions) = expansions.pop() {
212+
for (mark, expansion) in expansions.into_iter().rev() {
213+
let expansion = expansion.fold_with(&mut placeholder_expander);
214+
placeholder_expander.add(mark, expansion);
215+
}
216+
}
217+
218+
placeholder_expander.remove(0)
208219
}
209220

210221
fn collect_invocations(&mut self, expansion: Expansion) -> (Expansion, Vec<Invocation>) {

src/libsyntax/ext/placeholders.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,18 @@ pub struct PlaceholderExpander {
7474
}
7575

7676
impl PlaceholderExpander {
77-
pub fn new(expansions: HashMap<ast::NodeId, Expansion>) -> Self {
77+
pub fn new() -> Self {
7878
PlaceholderExpander {
79-
expansions: expansions,
79+
expansions: HashMap::new(),
8080
}
8181
}
8282

83+
pub fn add(&mut self, id: ast::NodeId, expansion: Expansion) {
84+
self.expansions.insert(id, expansion);
85+
}
86+
8387
pub fn remove(&mut self, id: ast::NodeId) -> Expansion {
84-
let expansion = self.expansions.remove(&id).unwrap();
85-
expansion.fold_with(self)
88+
self.expansions.remove(&id).unwrap()
8689
}
8790
}
8891

0 commit comments

Comments
 (0)