about summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
authorKevin Ballard <kevin@sb.org>2014-01-17 22:30:36 -0800
committerKevin Ballard <kevin@sb.org>2014-05-18 13:03:38 -0700
commitbcabcf53cfe2a86ebf02aa762b8ab7278060ce10 (patch)
tree5a0ce4fec2100f41123572573abfde840bc1b2f3 /src/libsyntax/ext
parent134f797a6309e8f284372c745689bcde17829c30 (diff)
downloadrust-bcabcf53cfe2a86ebf02aa762b8ab7278060ce10.tar.gz
rust-bcabcf53cfe2a86ebf02aa762b8ab7278060ce10.zip
Make bytes!() return 'static
Change `bytes!()` to return

    {
        static BYTES: &'static [u8] = &[...];
        BYTES
    }

This gives it the `'static` lifetime, whereas before it had an rvalue
lifetime. Until recently this would have prevented assigning `bytes!()`
to a static, as in

    static FOO: &'static [u8] = bytes!(1,2,3);

but #14183 fixed it so blocks are now allowed in constant expressions
(with restrictions).

Fixes #11641.
Diffstat (limited to 'src/libsyntax/ext')
-rw-r--r--src/libsyntax/ext/bytes.rs33
1 files changed, 27 insertions, 6 deletions
diff --git a/src/libsyntax/ext/bytes.rs b/src/libsyntax/ext/bytes.rs
index 06b50e37cbd..b2088d2bc82 100644
--- a/src/libsyntax/ext/bytes.rs
+++ b/src/libsyntax/ext/bytes.rs
@@ -25,6 +25,7 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         Some(e) => e,
     };
     let mut bytes = Vec::new();
+    let mut err = false;
 
     for expr in exprs.iter() {
         match expr.node {
@@ -40,7 +41,8 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                 // u8 literal, push to vector expression
                 ast::LitUint(v, ast::TyU8) => {
                     if v > 0xFF {
-                        cx.span_err(expr.span, "too large u8 literal in bytes!")
+                        cx.span_err(expr.span, "too large u8 literal in bytes!");
+                        err = true;
                     } else {
                         bytes.push(cx.expr_u8(expr.span, v as u8));
                     }
@@ -49,9 +51,11 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                 // integer literal, push to vector expression
                 ast::LitIntUnsuffixed(v) => {
                     if v > 0xFF {
-                        cx.span_err(expr.span, "too large integer literal in bytes!")
+                        cx.span_err(expr.span, "too large integer literal in bytes!");
+                        err = true;
                     } else if v < 0 {
-                        cx.span_err(expr.span, "negative integer literal in bytes!")
+                        cx.span_err(expr.span, "negative integer literal in bytes!");
+                        err = true;
                     } else {
                         bytes.push(cx.expr_u8(expr.span, v as u8));
                     }
@@ -62,17 +66,34 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                     if v.is_ascii() {
                         bytes.push(cx.expr_u8(expr.span, v as u8));
                     } else {
-                        cx.span_err(expr.span, "non-ascii char literal in bytes!")
+                        cx.span_err(expr.span, "non-ascii char literal in bytes!");
+                        err = true;
                     }
                 }
 
-                _ => cx.span_err(expr.span, "unsupported literal in bytes!")
+                _ => {
+                    cx.span_err(expr.span, "unsupported literal in bytes!");
+                    err = true;
+                }
             },
 
-            _ => cx.span_err(expr.span, "non-literal in bytes!")
+            _ => {
+                cx.span_err(expr.span, "non-literal in bytes!");
+                err = true;
+            }
         }
     }
 
+    // For some reason using quote_expr!() here aborts if we threw an error.
+    // I'm assuming that the end of the recursive parse tricks the compiler
+    // into thinking this is a good time to stop. But we'd rather keep going.
+    if err {
+        // Since the compiler will stop after the macro expansion phase anyway, we
+        // don't need type info, so we can just return a DummyResult
+        return DummyResult::expr(sp);
+    }
+
     let e = cx.expr_vec_slice(sp, bytes);
+    let e = quote_expr!(cx, { static BYTES: &'static [u8] = $e; BYTES});
     MacExpr::new(e)
 }