Skip to content

Commit b8c5e46

Browse files
committed
working on hygiene
1 parent e880c42 commit b8c5e46

File tree

2 files changed

+51
-12
lines changed

2 files changed

+51
-12
lines changed

src/libsyntax/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ pub enum Decl_ {
401401
DeclItem(Gc<Item>),
402402
}
403403

404+
/// represents one arm of a 'match'
404405
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
405406
pub struct Arm {
406407
pub attrs: Vec<Attribute>,

src/libsyntax/ext/expand.rs

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use util::small_vector::SmallVector;
3131

3232
use std::gc::{Gc, GC};
3333

34+
3435
pub fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> {
3536
match e.node {
3637
// expr_mac should really be expr_ext or something; it's the
@@ -130,8 +131,6 @@ pub fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> {
130131
// From: `['<ident>:] for <src_pat> in <src_expr> <src_loop_block>`
131132
// FIXME #6993: change type of opt_ident to Option<Name>
132133
ast::ExprForLoop(src_pat, src_expr, src_loop_block, opt_ident) => {
133-
// Expand any interior macros etc.
134-
// NB: we don't fold pats yet. Curious.
135134

136135
let span = e.span;
137136

@@ -281,7 +280,7 @@ macro_rules! with_exts_frame (
281280
)
282281

283282
// When we enter a module, record it, for the sake of `module!`
284-
pub fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)
283+
fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)
285284
-> SmallVector<Gc<ast::Item>> {
286285
let it = expand_item_modifiers(it, fld);
287286

@@ -386,13 +385,13 @@ fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
386385
}
387386

388387
// does this attribute list contain "macro_escape" ?
389-
pub fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool {
388+
fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool {
390389
attr::contains_name(attrs, "macro_escape")
391390
}
392391

393392
// Support for item-position macro invocations, exactly the same
394393
// logic as for expression-position macro invocations.
395-
pub fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
394+
fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
396395
-> SmallVector<Gc<ast::Item>> {
397396
let (pth, tts) = match it.node {
398397
ItemMac(codemap::Spanned {
@@ -498,7 +497,7 @@ pub fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
498497
}
499498

500499
// expand a stmt
501-
pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<Gc<Stmt>> {
500+
fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<Gc<Stmt>> {
502501
// why the copying here and not in expand_expr?
503502
// looks like classic changed-in-only-one-place
504503
let (pth, tts, semi) = match s.node {
@@ -659,6 +658,42 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
659658
}
660659
}
661660

661+
fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
662+
if a.pats.len() == 0 {
663+
fail!("encountered match arm with 0 patterns");
664+
}
665+
let first_pat = match a.pats.get(0) {
666+
667+
}
668+
// code duplicated from 'let', above. Perhaps this can be lifted
669+
// into a separate function:
670+
let expanded_pat = fld.fold_pat(pat);
671+
let mut name_finder = new_name_finder(Vec::new());
672+
name_finder.visit_pat(&*expanded_pat,());
673+
let mut new_pending_renames = Vec::new();
674+
for ident in name_finder.ident_accumulator.iter() {
675+
let new_name = fresh_name(ident);
676+
new_pending_renames.push((*ident,new_name));
677+
}
678+
let rewritten_pat = {
679+
let mut rename_fld =
680+
renames_to_fold(&mut new_pending_renames);
681+
// rewrite the pattern using the new names (the old
682+
// ones have already been applied):
683+
rename_fld.fold_pat(expanded_pat)
684+
};
685+
686+
let bound_names
687+
ast::Arm {
688+
attrs: a.attrs.iter().map(|x| self.fold_attribute(*x)).collect(),
689+
pats: a.pats.iter().map(|x| self.fold_pat(*x)).collect(),
690+
guard: a.guard.map(|x| self.fold_expr(x)),
691+
body: self.fold_expr(a.body),
692+
}
693+
}
694+
695+
696+
662697
// a visitor that extracts the pat_ident (binding) paths
663698
// from a given thingy and puts them in a mutable
664699
// array (passed in to the traversal).
@@ -711,14 +746,14 @@ fn new_name_finder(idents: Vec<ast::Ident> ) -> NameFinderContext {
711746
}
712747

713748
// expand a block. pushes a new exts_frame, then calls expand_block_elts
714-
pub fn expand_block(blk: &Block, fld: &mut MacroExpander) -> P<Block> {
749+
fn expand_block(blk: &Block, fld: &mut MacroExpander) -> P<Block> {
715750
// see note below about treatment of exts table
716751
with_exts_frame!(fld.extsbox,false,
717752
expand_block_elts(blk, fld))
718753
}
719754

720755
// expand the elements of a block.
721-
pub fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P<Block> {
756+
fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P<Block> {
722757
let new_view_items = b.view_items.iter().map(|x| fld.fold_view_item(x)).collect();
723758
let new_stmts =
724759
b.stmts.iter().flat_map(|x| {
@@ -747,7 +782,7 @@ pub fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P<Block> {
747782
})
748783
}
749784

750-
pub fn expand_pat(p: Gc<ast::Pat>, fld: &mut MacroExpander) -> Gc<ast::Pat> {
785+
fn expand_pat(p: Gc<ast::Pat>, fld: &mut MacroExpander) -> Gc<ast::Pat> {
751786
let (pth, tts) = match p.node {
752787
PatMac(ref mac) => {
753788
match mac.node {
@@ -842,13 +877,13 @@ impl<'a> Folder for IdentRenamer<'a> {
842877

843878
// given a mutable list of renames, return a tree-folder that applies those
844879
// renames.
845-
pub fn renames_to_fold<'a>(renames: &'a mut RenameList) -> IdentRenamer<'a> {
880+
fn renames_to_fold<'a>(renames: &'a mut RenameList) -> IdentRenamer<'a> {
846881
IdentRenamer {
847882
renames: renames,
848883
}
849884
}
850885

851-
pub fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
886+
fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
852887
/* this discards information in the case of macro-defining macros */
853888
Span {
854889
lo: sp.lo,
@@ -883,6 +918,10 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
883918
expand_block(&*block, self)
884919
}
885920

921+
fn fold_arm(&mut self, arm: &ast::Arm) -> ast::Arm {
922+
expand_arm(arm, self)
923+
}
924+
886925
fn new_span(&mut self, span: Span) -> Span {
887926
new_span(self.cx, span)
888927
}
@@ -1248,7 +1287,6 @@ mod test {
12481287

12491288
// FIXME #9384, match variable hygiene. Should expand into
12501289
// fn z() {match 8 {x_1 => {match 9 {x_2 | x_2 => x_2 + x_1}}}}
1251-
#[ignore]
12521290
#[test] fn issue_9384(){
12531291
run_renaming_test(
12541292
&("macro_rules! bad_macro (($ex:expr) => ({match 9 {x | x => x + $ex}}))

0 commit comments

Comments
 (0)