Skip to content

Commit ea87f12

Browse files
committed
auto merge of #14275 : kballard/rust/bytes-return-static, r=huonw
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.
2 parents 63287ee + bcabcf5 commit ea87f12

File tree

2 files changed

+48
-6
lines changed

2 files changed

+48
-6
lines changed

src/libsyntax/ext/bytes.rs

+27-6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
2525
Some(e) => e,
2626
};
2727
let mut bytes = Vec::new();
28+
let mut err = false;
2829

2930
for expr in exprs.iter() {
3031
match expr.node {
@@ -40,7 +41,8 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
4041
// u8 literal, push to vector expression
4142
ast::LitUint(v, ast::TyU8) => {
4243
if v > 0xFF {
43-
cx.span_err(expr.span, "too large u8 literal in bytes!")
44+
cx.span_err(expr.span, "too large u8 literal in bytes!");
45+
err = true;
4446
} else {
4547
bytes.push(cx.expr_u8(expr.span, v as u8));
4648
}
@@ -49,9 +51,11 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
4951
// integer literal, push to vector expression
5052
ast::LitIntUnsuffixed(v) => {
5153
if v > 0xFF {
52-
cx.span_err(expr.span, "too large integer literal in bytes!")
54+
cx.span_err(expr.span, "too large integer literal in bytes!");
55+
err = true;
5356
} else if v < 0 {
54-
cx.span_err(expr.span, "negative integer literal in bytes!")
57+
cx.span_err(expr.span, "negative integer literal in bytes!");
58+
err = true;
5559
} else {
5660
bytes.push(cx.expr_u8(expr.span, v as u8));
5761
}
@@ -62,17 +66,34 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
6266
if v.is_ascii() {
6367
bytes.push(cx.expr_u8(expr.span, v as u8));
6468
} else {
65-
cx.span_err(expr.span, "non-ascii char literal in bytes!")
69+
cx.span_err(expr.span, "non-ascii char literal in bytes!");
70+
err = true;
6671
}
6772
}
6873

69-
_ => cx.span_err(expr.span, "unsupported literal in bytes!")
74+
_ => {
75+
cx.span_err(expr.span, "unsupported literal in bytes!");
76+
err = true;
77+
}
7078
},
7179

72-
_ => cx.span_err(expr.span, "non-literal in bytes!")
80+
_ => {
81+
cx.span_err(expr.span, "non-literal in bytes!");
82+
err = true;
83+
}
7384
}
7485
}
7586

87+
// For some reason using quote_expr!() here aborts if we threw an error.
88+
// I'm assuming that the end of the recursive parse tricks the compiler
89+
// into thinking this is a good time to stop. But we'd rather keep going.
90+
if err {
91+
// Since the compiler will stop after the macro expansion phase anyway, we
92+
// don't need type info, so we can just return a DummyResult
93+
return DummyResult::expr(sp);
94+
}
95+
7696
let e = cx.expr_vec_slice(sp, bytes);
97+
let e = quote_expr!(cx, { static BYTES: &'static [u8] = $e; BYTES});
7798
MacExpr::new(e)
7899
}
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
static FOO: &'static [u8] = bytes!("hello, world");
12+
13+
pub fn main() {
14+
let b = match true {
15+
true => bytes!("test"),
16+
false => unreachable!()
17+
};
18+
19+
assert_eq!(b, "test".as_bytes());
20+
assert_eq!(FOO, "hello, world".as_bytes());
21+
}

0 commit comments

Comments
 (0)