Skip to content

Commit f2060b6

Browse files
committed
Add an Action enum to represent how we want to change the AST
1 parent 06f0c62 commit f2060b6

File tree

2 files changed

+63
-31
lines changed

2 files changed

+63
-31
lines changed

src/librustc_allocator/expand.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use syntax::{
1616
hygiene::{self, Mark, SyntaxContext},
1717
},
1818
fold::Folder,
19-
visit_mut::{self, MutVisitor},
19+
visit_mut::{self, MutVisitor, Action},
2020
parse::ParseSess,
2121
ptr::P,
2222
symbol::Symbol
@@ -56,34 +56,34 @@ struct ExpandAllocatorDirectives<'a> {
5656
}
5757

5858
impl<'a> MutVisitor for ExpandAllocatorDirectives<'a> {
59-
fn visit_item(&mut self, item: &mut P<Item>) -> Option<Vec<P<Item>>> {
59+
fn visit_item(&mut self, item: &mut P<Item>) -> Action<P<Item>> {
6060
debug!("in submodule {}", self.in_submod);
6161

6262
let name = if attr::contains_name(&item.attrs, "global_allocator") {
6363
"global_allocator"
6464
} else {
6565
visit_mut::walk_item(self, item);
66-
return None;
66+
return Action::Reuse;
6767
};
6868
match item.node {
6969
ItemKind::Static(..) => {}
7070
_ => {
7171
self.handler
7272
.span_err(item.span, "allocators must be statics");
73-
return None;
73+
return Action::Reuse;
7474
}
7575
}
7676

7777
if self.in_submod > 0 {
7878
self.handler
7979
.span_err(item.span, "`global_allocator` cannot be used in submodules");
80-
return None;
80+
return Action::Reuse;
8181
}
8282

8383
if self.found {
8484
self.handler
8585
.span_err(item.span, "cannot define more than one #[global_allocator]");
86-
return None;
86+
return Action::Reuse;
8787
}
8888
self.found = true;
8989

@@ -144,7 +144,7 @@ impl<'a> MutVisitor for ExpandAllocatorDirectives<'a> {
144144
let module = f.cx.monotonic_expander().fold_item(module).pop().unwrap();
145145

146146
// Return the item and new submodule
147-
Some(vec![item.clone(), module])
147+
Action::Add(vec![module])
148148
}
149149

150150
// If we enter a submodule, take note.

src/libsyntax/visit_mut.rs

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,28 @@ use syntax_pos::Span;
1919
use parse::token::Token;
2020
use tokenstream::{TokenTree, TokenStream};
2121

22+
pub enum Action<T> {
23+
Reuse,
24+
Remove,
25+
Add(Vec<T>),
26+
Replace(Vec<T>),
27+
}
28+
29+
impl<T> Action<T> {
30+
pub fn map<R>(self, mut f: impl FnMut(T) -> R) -> Action<R> {
31+
match self {
32+
Action::Reuse => Action::Reuse,
33+
Action::Remove => Action::Remove,
34+
Action::Add(list) => {
35+
Action::Add(list.into_iter().map(|item| f(item)).collect())
36+
}
37+
Action::Replace(list) => {
38+
Action::Replace(list.into_iter().map(|item| f(item)).collect())
39+
}
40+
}
41+
}
42+
}
43+
2244
pub enum FnKind<'a> {
2345
/// fn foo() or extern "Abi" fn foo()
2446
ItemFn(Ident, FnHeader, &'a mut Visibility, &'a mut Block),
@@ -62,13 +84,13 @@ pub trait MutVisitor: Sized {
6284
}
6385
fn visit_foreign_item(&mut self, i: &mut ForeignItem) { walk_foreign_item(self, i) }
6486
fn visit_global_asm(&mut self, ga: &mut GlobalAsm) { walk_global_asm(self, ga) }
65-
fn visit_item(&mut self, i: &mut P<Item>) -> Option<Vec<P<Item>>> {
87+
fn visit_item(&mut self, i: &mut P<Item>) -> Action<P<Item>> {
6688
walk_item(self, i);
67-
None
89+
Action::Reuse
6890
}
6991
fn visit_local(&mut self, l: &mut Local) { walk_local(self, l) }
7092
fn visit_block(&mut self, b: &mut Block) { walk_block(self, b) }
71-
fn visit_stmt(&mut self, s: &mut Stmt) -> Option<Vec<Stmt>> {
93+
fn visit_stmt(&mut self, s: &mut Stmt) -> Action<Stmt> {
7294
walk_stmt(self, s)
7395
}
7496
fn visit_arm(&mut self, a: &mut Arm) { walk_arm(self, a) }
@@ -173,15 +195,27 @@ macro_rules! walk_list_mut {
173195
break;
174196
}
175197

176-
if let Some(replacement) = $visitor.$method(&mut $list[i], $(, $extra_args)*) {
177-
$list.remove(i);
178-
let rlen = replacement.len();
179-
for (j, r) in replacement.into_iter().enumerate() {
180-
$list.insert(i + j, r);
198+
match $visitor.$method(&mut $list[i], $(, $extra_args)*) {
199+
Action::Reuse => i += 1,
200+
Action::Remove => {
201+
$list.remove(i);
202+
}
203+
Action::Add(list) => {
204+
i += 1;
205+
let rlen = list.len();
206+
for (j, r) in list.into_iter().enumerate() {
207+
$list.insert(i + j, r);
208+
}
209+
i += rlen;
210+
}
211+
Action::Replace(list) => {
212+
$list.remove(i);
213+
let rlen = list.len();
214+
for (j, r) in list.into_iter().enumerate() {
215+
$list.insert(i + j, r);
216+
}
217+
i += rlen;
181218
}
182-
i += rlen;
183-
} else {
184-
i += 1;
185219
}
186220
}
187221
}
@@ -650,34 +684,32 @@ pub fn walk_block<V: MutVisitor>(visitor: &mut V, block: &mut Block) {
650684
walk_list_mut!(visitor, visit_stmt, &mut block.stmts);
651685
}
652686

653-
pub fn walk_stmt<V: MutVisitor>(visitor: &mut V, statement: &mut Stmt) -> Option<Vec<Stmt>> {
687+
pub fn walk_stmt<V: MutVisitor>(visitor: &mut V, statement: &mut Stmt) -> Action<Stmt> {
654688
match statement.node {
655689
StmtKind::Local(ref mut local) => {
656690
visitor.visit_local(local);
657-
None
691+
Action::Reuse
658692
},
659693
StmtKind::Item(ref mut item) => {
660-
visitor.visit_item(item).map(|replacement| {
661-
replacement.into_iter().map(|item| {
662-
Stmt {
663-
id: visitor.new_id(statement.id),
664-
node: StmtKind::Item(item),
665-
span: visitor.new_span(statement.span),
666-
}
667-
}).collect()
694+
visitor.visit_item(item).map(|item| {
695+
Stmt {
696+
id: visitor.new_id(statement.id),
697+
node: StmtKind::Item(item),
698+
span: visitor.new_span(statement.span),
699+
}
668700
})
669701
},
670702
StmtKind::Expr(ref mut expression) | StmtKind::Semi(ref mut expression) => {
671703
visitor.visit_expr(expression);
672-
None
704+
Action::Reuse
673705
}
674706
StmtKind::Mac(ref mut mac) => {
675707
let (ref mut mac, _, ref mut attrs) = **mac;
676708
visitor.visit_mac(mac);
677709
for attr in attrs.iter_mut() {
678710
visitor.visit_attribute(attr);
679711
}
680-
None
712+
Action::Reuse
681713
}
682714
}
683715
}
@@ -893,7 +925,7 @@ pub fn walk_attribute<V: MutVisitor>(visitor: &mut V, attr: &mut Attribute) {
893925
pub fn walk_tt<V: MutVisitor>(visitor: &mut V, tt: TokenTree) {
894926
match tt {
895927
TokenTree::Token(_, tok) => visitor.visit_token(tok),
896-
TokenTree::Delimited(_, _, tts) => visitor.visit_tts(tts.stream()),
928+
TokenTree::Delimited(_, _, tts) => visitor.visit_tts(tts),
897929
}
898930
}
899931

0 commit comments

Comments
 (0)