From b8cd7f7c6df3581df92c2dc51ca23770f468de40 Mon Sep 17 00:00:00 2001 From: John Clements Date: Wed, 2 Jul 2014 23:16:01 -0700 Subject: [PATCH] add PatIdentRenamer --- src/libsyntax/ext/expand.rs | 43 +++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 11152a6f1da8d..5fdfe5040f31c 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -21,6 +21,7 @@ use codemap; use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute}; use crateid::CrateId; use ext::base::*; +use fold; use fold::*; use parse; use parse::token::{fresh_mark, fresh_name, intern}; @@ -856,15 +857,36 @@ impl<'a> Folder for IdentRenamer<'a> { } } -fn new_span(cx: &ExtCtxt, sp: Span) -> Span { - /* this discards information in the case of macro-defining macros */ - Span { - lo: sp.lo, - hi: sp.hi, - expn_info: cx.backtrace(), +/// A tree-folder that applies every rename in its list to +/// the idents that are in PatIdent patterns. This is more narrowly +/// focused than IdentRenamer, and is needed for FnDecl, +/// where we want to rename the args but not the fn name or the generics etc. +pub struct PatIdentRenamer<'a> { + renames: &'a mtwt::RenameList, +} + +impl<'a> Folder for PatIdentRenamer<'a> { + fn fold_pat(&mut self, pat: Gc) -> Gc { + match pat.node { + ast::PatIdent(binding_mode, Spanned{span: ref sp, node: id}, ref sub) => { + let new_ident = Ident{name: id.name, + ctxt: mtwt::new_renames(self.renames, id.ctxt)}; + let new_node = + ast::PatIdent(binding_mode, + Spanned{span: self.new_span(*sp), node: new_ident}, + sub.map(|p| self.fold_pat(p))); + box(GC) ast::Pat { + id: pat.id, + span: self.new_span(pat.span), + node: new_node, + } + }, + _ => noop_fold_pat(pat, self) + } } } +/// A tree-folder that performs macro expansion pub struct MacroExpander<'a, 'b> { pub extsbox: SyntaxEnv, pub cx: &'a mut ExtCtxt<'b>, @@ -900,6 +922,15 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { } } +fn new_span(cx: &ExtCtxt, sp: Span) -> Span { + /* this discards information in the case of macro-defining macros */ + Span { + lo: sp.lo, + hi: sp.hi, + expn_info: cx.backtrace(), + } +} + pub struct ExpansionConfig { pub deriving_hash_type_parameter: bool, pub crate_id: CrateId,