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.
This commit is contained in:
parent
134f797a63
commit
bcabcf53cf
@ -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)
|
||||
}
|
||||
|
21
src/test/run-pass/bytes-macro-static.rs
Normal file
21
src/test/run-pass/bytes-macro-static.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
static FOO: &'static [u8] = bytes!("hello, world");
|
||||
|
||||
pub fn main() {
|
||||
let b = match true {
|
||||
true => bytes!("test"),
|
||||
false => unreachable!()
|
||||
};
|
||||
|
||||
assert_eq!(b, "test".as_bytes());
|
||||
assert_eq!(FOO, "hello, world".as_bytes());
|
||||
}
|
Loading…
Reference in New Issue
Block a user