diff options
| author | Kevin Ballard <kevin@sb.org> | 2014-01-17 22:30:36 -0800 |
|---|---|---|
| committer | Kevin Ballard <kevin@sb.org> | 2014-05-18 13:03:38 -0700 |
| commit | bcabcf53cfe2a86ebf02aa762b8ab7278060ce10 (patch) | |
| tree | 5a0ce4fec2100f41123572573abfde840bc1b2f3 /src/libsyntax/ext | |
| parent | 134f797a6309e8f284372c745689bcde17829c30 (diff) | |
| download | rust-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.rs | 33 |
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) } |
