about summary refs log tree commit diff
path: root/src/libsyntax/ext/tt
diff options
context:
space:
mode:
authorPaul Stansifer <paul.stansifer@gmail.com>2012-11-07 23:13:15 -0500
committerGraydon Hoare <graydon@mozilla.com>2012-11-29 12:09:10 -0800
commit9845a4be5a4f9919fcadfb1076d2425781eab41f (patch)
tree949dd7517a8d564d3fb6f279f6b6386eb1af4161 /src/libsyntax/ext/tt
parentc946c87b6f9cd536309dfba09abdc9af32729f34 (diff)
downloadrust-9845a4be5a4f9919fcadfb1076d2425781eab41f.tar.gz
rust-9845a4be5a4f9919fcadfb1076d2425781eab41f.zip
Allow `macro_rules!` macros to expand to expressions or items.
Diffstat (limited to 'src/libsyntax/ext/tt')
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs13
1 files changed, 8 insertions, 5 deletions
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 56418989c49..7957cde8fdc 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -1,4 +1,4 @@
-use base::{ext_ctxt, mac_result, mr_expr, mr_def, expr_tt};
+use base::{ext_ctxt, mac_result, mr_expr_or_item, mr_def, expr_tt};
 use codemap::span;
 use ast::{ident, matcher_, matcher, match_tok,
              match_nonterminal, match_seq, tt_delim};
@@ -87,10 +87,13 @@ fn add_new_extension(cx: ext_ctxt, sp: span, name: ident,
                     // rhs has holes ( `$id` and `$(...)` that need filled)
                     let trncbr = new_tt_reader(s_d, itr, Some(named_matches),
                                                ~[rhs]);
-                    let p = Parser(cx.parse_sess(), cx.cfg(),
-                                   trncbr as reader);
-                    let e = p.parse_expr();
-                    return mr_expr(e);
+                    let p = @Parser(cx.parse_sess(), cx.cfg(),
+                                    trncbr as reader);
+
+                    // Let the context choose how to interpret the result.
+                    // Weird, but useful for X-macros.
+                    return mr_expr_or_item(|| p.parse_expr(),
+                                           || p.parse_item(~[/* no attrs*/]));
                   }
                   failure(sp, msg) => if sp.lo >= best_fail_spot.lo {
                     best_fail_spot = sp;