diff options
Diffstat (limited to 'src/libsyntax/ext/expand.rs')
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 63 |
1 files changed, 32 insertions, 31 deletions
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index e280e6e4491..20c8ff20b71 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -11,7 +11,8 @@ use self::Either::*; use ast::{Block, Crate, DeclLocal, ExprMac, PatMac}; use ast::{Local, Ident, MacInvocTT}; -use ast::{ItemMac, Mrk, Stmt, StmtDecl, StmtMac, StmtExpr, StmtSemi}; +use ast::{ItemMac, MacStmtWithSemicolon, Mrk, Stmt, StmtDecl, StmtMac}; +use ast::{StmtExpr, StmtSemi}; use ast::TokenTree; use ast; use ext::mtwt; @@ -354,7 +355,7 @@ fn expand_loop_block(loop_block: P<Block>, // eval $e with a new exts frame. // must be a macro so that $e isn't evaluated too early. -macro_rules! with_exts_frame ( +macro_rules! with_exts_frame { ($extsboxexpr:expr,$macros_escape:expr,$e:expr) => ({$extsboxexpr.push_frame(); $extsboxexpr.info().macros_escape = $macros_escape; @@ -362,7 +363,7 @@ macro_rules! with_exts_frame ( $extsboxexpr.pop_frame(); result }) -) +} // When we enter a module, record it, for the sake of `module!` pub fn expand_item(it: P<ast::Item>, fld: &mut MacroExpander) @@ -636,8 +637,8 @@ pub fn expand_item_mac(it: P<ast::Item>, fld: &mut MacroExpander) // I don't understand why this returns a vector... it looks like we're // half done adding machinery to allow macros to expand into multiple statements. fn expand_stmt(s: Stmt, fld: &mut MacroExpander) -> SmallVector<P<Stmt>> { - let (mac, semi) = match s.node { - StmtMac(mac, semi) => (mac, semi), + let (mac, style) = match s.node { + StmtMac(mac, style) => (mac, style), _ => return expand_non_macro_stmt(s, fld) }; let expanded_stmt = match expand_mac_invoc(mac, s.span, @@ -653,7 +654,7 @@ fn expand_stmt(s: Stmt, fld: &mut MacroExpander) -> SmallVector<P<Stmt>> { let fully_expanded = fld.fold_stmt(expanded_stmt); fld.cx.bt_pop(); - if semi { + if style == MacStmtWithSemicolon { fully_expanded.into_iter().map(|s| s.map(|Spanned {node, span}| { Spanned { node: match node { @@ -1324,7 +1325,7 @@ mod test { // make sure that macros can't escape fns #[should_fail] #[test] fn macros_cant_escape_fns_test () { - let src = "fn bogus() {macro_rules! z (() => (3+4))}\ + let src = "fn bogus() {macro_rules! z (() => (3+4));}\ fn inty() -> int { z!() }".to_string(); let sess = parse::new_parse_sess(); let crate_ast = parse::parse_crate_from_source_str( @@ -1338,7 +1339,7 @@ mod test { // make sure that macros can't escape modules #[should_fail] #[test] fn macros_cant_escape_mods_test () { - let src = "mod foo {macro_rules! z (() => (3+4))}\ + let src = "mod foo {macro_rules! z (() => (3+4));}\ fn inty() -> int { z!() }".to_string(); let sess = parse::new_parse_sess(); let crate_ast = parse::parse_crate_from_source_str( @@ -1350,7 +1351,7 @@ mod test { // macro_escape modules should allow macros to escape #[test] fn macros_can_escape_flattened_mods_test () { - let src = "#[macro_escape] mod foo {macro_rules! z (() => (3+4))}\ + let src = "#[macro_escape] mod foo {macro_rules! z (() => (3+4));}\ fn inty() -> int { z!() }".to_string(); let sess = parse::new_parse_sess(); let crate_ast = parse::parse_crate_from_source_str( @@ -1402,13 +1403,13 @@ mod test { #[test] fn macro_tokens_should_match(){ expand_crate_str( - "macro_rules! m((a)=>(13)) fn main(){m!(a);}".to_string()); + "macro_rules! m((a)=>(13)) ;fn main(){m!(a);}".to_string()); } // should be able to use a bound identifier as a literal in a macro definition: #[test] fn self_macro_parsing(){ expand_crate_str( - "macro_rules! foo ((zz) => (287u;)) + "macro_rules! foo ((zz) => (287u;)); fn f(zz : int) {foo!(zz);}".to_string() ); } @@ -1451,16 +1452,16 @@ mod test { ("fn main () {let x: int = 13;x;}", vec!(vec!(0)), false), // the use of b after the + should be renamed, the other one not: - ("macro_rules! f (($x:ident) => (b + $x)) fn a() -> int { let b = 13; f!(b)}", + ("macro_rules! f (($x:ident) => (b + $x)); fn a() -> int { let b = 13; f!(b)}", vec!(vec!(1)), false), // the b before the plus should not be renamed (requires marks) - ("macro_rules! f (($x:ident) => ({let b=9; ($x + b)})) fn a() -> int { f!(b)}", + ("macro_rules! f (($x:ident) => ({let b=9; ($x + b)})); fn a() -> int { f!(b)}", vec!(vec!(1)), false), // the marks going in and out of letty should cancel, allowing that $x to // capture the one following the semicolon. // this was an awesome test case, and caught a *lot* of bugs. - ("macro_rules! letty(($x:ident) => (let $x = 15;)) - macro_rules! user(($x:ident) => ({letty!($x); $x})) + ("macro_rules! letty(($x:ident) => (let $x = 15;)); + macro_rules! user(($x:ident) => ({letty!($x); $x})); fn main() -> int {user!(z)}", vec!(vec!(0)), false) ); @@ -1488,7 +1489,7 @@ mod test { #[test] fn issue_6994(){ run_renaming_test( &("macro_rules! g (($x:ident) => - ({macro_rules! f(($y:ident)=>({let $y=3;$x}));f!($x)})) + ({macro_rules! f(($y:ident)=>({let $y=3;$x}));f!($x)})); fn a(){g!(z)}", vec!(vec!(0)),false), 0) @@ -1498,7 +1499,7 @@ mod test { // fn z() {match 8 {x_1 => {match 9 {x_2 | x_2 if x_2 == x_1 => x_2 + x_1}}}} #[test] fn issue_9384(){ run_renaming_test( - &("macro_rules! bad_macro (($ex:expr) => ({match 9 {x | x if x == $ex => x + $ex}})) + &("macro_rules! bad_macro (($ex:expr) => ({match 9 {x | x if x == $ex => x + $ex}})); fn z() {match 8 {x => bad_macro!(x)}}", // NB: the third "binding" is the repeat of the second one. vec!(vec!(1,3),vec!(0,2),vec!(0,2)), @@ -1511,8 +1512,8 @@ mod test { // fn main(){let g1_1 = 13; g1_1}} #[test] fn pat_expand_issue_15221(){ run_renaming_test( - &("macro_rules! inner ( ($e:pat ) => ($e)) - macro_rules! outer ( ($e:pat ) => (inner!($e))) + &("macro_rules! inner ( ($e:pat ) => ($e)); + macro_rules! outer ( ($e:pat ) => (inner!($e))); fn main() { let outer!(g) = 13; g;}", vec!(vec!(0)), true), @@ -1527,8 +1528,8 @@ mod test { // method expands to fn get_x(&self_0, x_1:int) {self_0 + self_2 + x_3 + x_1} #[test] fn method_arg_hygiene(){ run_renaming_test( - &("macro_rules! inject_x (()=>(x)) - macro_rules! inject_self (()=>(self)) + &("macro_rules! inject_x (()=>(x)); + macro_rules! inject_self (()=>(self)); struct A; impl A{fn get_x(&self, x: int) {self + inject_self!() + inject_x!() + x;} }", vec!(vec!(0),vec!(3)), @@ -1542,8 +1543,8 @@ mod test { run_renaming_test( &("struct A; macro_rules! add_method (($T:ty) => - (impl $T { fn thingy(&self) {self;} })) - add_method!(A)", + (impl $T { fn thingy(&self) {self;} })); + add_method!(A);", vec!(vec!(0)), true), 0) @@ -1553,7 +1554,7 @@ mod test { // expands to fn q(x_1:int){fn g(x_2:int){x_2 + x_1};} #[test] fn issue_9383(){ run_renaming_test( - &("macro_rules! bad_macro (($ex:expr) => (fn g(x:int){ x + $ex })) + &("macro_rules! bad_macro (($ex:expr) => (fn g(x:int){ x + $ex })); fn q(x:int) { bad_macro!(x); }", vec!(vec!(1),vec!(0)),true), 0) @@ -1563,7 +1564,7 @@ mod test { // expands to fn f(){(|x_1 : int| {(x_2 + x_1)})(3);} #[test] fn closure_arg_hygiene(){ run_renaming_test( - &("macro_rules! inject_x (()=>(x)) + &("macro_rules! inject_x (()=>(x)); fn f(){(|x : int| {(inject_x!() + x)})(3);}", vec!(vec!(1)), true), @@ -1573,9 +1574,9 @@ mod test { // macro_rules in method position. Sadly, unimplemented. #[test] fn macro_in_method_posn(){ expand_crate_str( - "macro_rules! my_method (() => (fn thirteen(&self) -> int {13})) + "macro_rules! my_method (() => (fn thirteen(&self) -> int {13})); struct A; - impl A{ my_method!()} + impl A{ my_method!(); } fn f(){A.thirteen;}".to_string()); } @@ -1586,7 +1587,7 @@ mod test { &("macro_rules! item { ($i:item) => {$i}} struct Entries; macro_rules! iterator_impl { - () => { item!( impl Entries { fn size_hint(&self) { self;}})}} + () => { item!( impl Entries { fn size_hint(&self) { self;}});}} iterator_impl! { }", vec!(vec!(0)), true), 0) @@ -1666,9 +1667,9 @@ mod test { } #[test] fn fmt_in_macro_used_inside_module_macro() { - let crate_str = "macro_rules! fmt_wrap(($b:expr)=>($b.to_string())) -macro_rules! foo_module (() => (mod generated { fn a() { let xx = 147; fmt_wrap!(xx);}})) -foo_module!() + let crate_str = "macro_rules! fmt_wrap(($b:expr)=>($b.to_string())); +macro_rules! foo_module (() => (mod generated { fn a() { let xx = 147; fmt_wrap!(xx);}})); +foo_module!(); ".to_string(); let cr = expand_crate_str(crate_str); // find the xx binding |
