about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorSteven Fackler <sfackler@gmail.com>2014-03-02 13:38:44 -0800
committerSteven Fackler <sfackler@gmail.com>2014-03-02 14:12:02 -0800
commita0e54c77612faa9008f95a136ed1674dfcf494ef (patch)
tree9538bd363a1f57d13d755cf570ddeb6d55ed1513 /src/libsyntax
parent25431774a933a3b0c5212ea45150660544dec1ec (diff)
downloadrust-a0e54c77612faa9008f95a136ed1674dfcf494ef.tar.gz
rust-a0e54c77612faa9008f95a136ed1674dfcf494ef.zip
Expand string literals and exprs inside of macros
A couple of syntax extensions manually expanded expressions, but it
wasn't done universally, most noticably inside of asm!().

There's also a bit of random cleanup.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/base.rs25
-rw-r--r--src/libsyntax/ext/concat.rs1
-rw-r--r--src/libsyntax/ext/format.rs5
3 files changed, 9 insertions, 22 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index e9fe21eded6..5cb09ec8232 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -405,11 +405,13 @@ impl<'a> ExtCtxt<'a> {
     }
 }
 
-/// Extract a string literal from `expr`, emitting `err_msg` if `expr`
-/// is not a string literal. This does not stop compilation on error,
-/// merely emits a non-fatal error and returns None.
-pub fn expr_to_str(cx: &ExtCtxt, expr: @ast::Expr, err_msg: &str)
+/// Extract a string literal from the macro expanded version of `expr`,
+/// emitting `err_msg` if `expr` is not a string literal. This does not stop
+/// compilation on error, merely emits a non-fatal error and returns None.
+pub fn expr_to_str(cx: &mut ExtCtxt, expr: @ast::Expr, err_msg: &str)
                    -> Option<(InternedString, ast::StrStyle)> {
+    // we want to be able to handle e.g. concat("foo", "bar")
+    let expr = cx.expand_expr(expr);
     match expr.node {
         ast::ExprLit(l) => match l.node {
             ast::LitStr(ref s, style) => return Some(((*s).clone(), style)),
@@ -457,7 +459,7 @@ pub fn get_single_str_from_tts(cx: &ExtCtxt,
 
 /// Extract comma-separated expressions from `tts`. If there is a
 /// parsing error, emit a non-fatal error and return None.
-pub fn get_exprs_from_tts(cx: &ExtCtxt,
+pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
                           sp: Span,
                           tts: &[ast::TokenTree]) -> Option<Vec<@ast::Expr> > {
     let mut p = parse::new_parser_from_tts(cx.parse_sess(),
@@ -471,7 +473,7 @@ pub fn get_exprs_from_tts(cx: &ExtCtxt,
             cx.span_err(sp, "expected token: `,`");
             return None;
         }
-        es.push(p.parse_expr());
+        es.push(cx.expand_expr(p.parse_expr()));
     }
     Some(es)
 }
@@ -482,9 +484,6 @@ pub fn get_exprs_from_tts(cx: &ExtCtxt,
 
 // This environment maps Names to SyntaxExtensions.
 
-// Actually, the following implementation is parameterized
-// by both key and value types.
-
 //impl question: how to implement it? Initially, the
 // env will contain only macros, so it might be painful
 // to add an empty frame for every context. Let's just
@@ -500,14 +499,6 @@ struct MapChainFrame {
     map: HashMap<Name, SyntaxExtension>,
 }
 
-#[unsafe_destructor]
-impl Drop for MapChainFrame {
-    fn drop(&mut self) {
-        // make sure that syntax extension dtors run before we drop the libs
-        self.map.clear();
-    }
-}
-
 // Only generic to make it easy to test
 pub struct SyntaxEnv {
     priv chain: Vec<MapChainFrame> ,
diff --git a/src/libsyntax/ext/concat.rs b/src/libsyntax/ext/concat.rs
index 5316b8f7212..e638291ecfa 100644
--- a/src/libsyntax/ext/concat.rs
+++ b/src/libsyntax/ext/concat.rs
@@ -25,7 +25,6 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
     };
     let mut accumulator = ~"";
     for e in es.move_iter() {
-        let e = cx.expand_expr(e);
         match e.node {
             ast::ExprLit(lit) => {
                 match lit.node {
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs
index 7752d885968..b27ea3df21e 100644
--- a/src/libsyntax/ext/format.rs
+++ b/src/libsyntax/ext/format.rs
@@ -843,11 +843,8 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
         fmtsp: sp,
     };
     cx.fmtsp = efmt.span;
-    // Be sure to recursively expand macros just in case the format string uses
-    // a macro to build the format expression.
-    let expr = cx.ecx.expand_expr(efmt);
     let fmt = match expr_to_str(cx.ecx,
-                                expr,
+                                efmt,
                                 "format argument must be a string literal.") {
         Some((fmt, _)) => fmt,
         None => return MacResult::raw_dummy_expr(sp)