Skip to content

Commit bccdba0

Browse files
committed
Add a b'x' byte literal of type u8.
1 parent 2fd618e commit bccdba0

File tree

16 files changed

+169
-5
lines changed

16 files changed

+169
-5
lines changed

src/librustc/middle/const_eval.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,7 @@ pub fn lit_to_const(lit: &Lit) -> const_val {
506506
LitBinary(ref data) => {
507507
const_binary(Rc::new(data.iter().map(|x| *x).collect()))
508508
}
509+
LitByte(n) => const_uint(n as u64),
509510
LitChar(n) => const_uint(n as u64),
510511
LitInt(n, _) => const_int(n),
511512
LitUint(n, _) => const_uint(n),

src/librustc/middle/lint.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,7 @@ fn check_type_limits(cx: &Context, e: &ast::Expr) {
805805
} else { t };
806806
let (min, max) = uint_ty_range(uint_type);
807807
let lit_val: u64 = match lit.node {
808+
ast::LitByte(_v) => return, // _v is u8, within range by definition
808809
ast::LitInt(v, _) => v as u64,
809810
ast::LitUint(v, _) => v,
810811
ast::LitIntUnsuffixed(v) => v as u64,

src/librustc/middle/trans/consts.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: ast::Lit)
4343
-> ValueRef {
4444
let _icx = push_ctxt("trans_lit");
4545
match lit.node {
46+
ast::LitByte(b) => C_integral(Type::uint_from_ty(cx, ast::TyU8), b as u64, false),
4647
ast::LitChar(i) => C_integral(Type::char(cx), i as u64, false),
4748
ast::LitInt(i, t) => C_integral(Type::int_from_ty(cx, t), i as u64, true),
4849
ast::LitUint(u, t) => C_integral(Type::uint_from_ty(cx, t), u, false),

src/librustc/middle/typeck/check/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,6 +1715,7 @@ pub fn check_lit(fcx: &FnCtxt, lit: &ast::Lit) -> ty::t {
17151715
ast::LitBinary(..) => {
17161716
ty::mk_slice(tcx, ty::ReStatic, ty::mt{ ty: ty::mk_u8(), mutbl: ast::MutImmutable })
17171717
}
1718+
ast::LitByte(_) => ty::mk_u8(),
17181719
ast::LitChar(_) => ty::mk_char(),
17191720
ast::LitInt(_, t) => ty::mk_mach_int(t),
17201721
ast::LitUint(_, t) => ty::mk_mach_uint(t),

src/librustdoc/clean/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1924,6 +1924,14 @@ fn lit_to_str(lit: &ast::Lit) -> String {
19241924
match lit.node {
19251925
ast::LitStr(ref st, _) => st.get().to_string(),
19261926
ast::LitBinary(ref data) => format!("{:?}", data.as_slice()),
1927+
ast::LitByte(b) => {
1928+
let mut res = String::from_str("b'");
1929+
(b as char).escape_default(|c| {
1930+
res.push_char(c);
1931+
});
1932+
res.push_char('\'');
1933+
res
1934+
},
19271935
ast::LitChar(c) => format!("'{}'", c),
19281936
ast::LitInt(i, _t) => i.to_str(),
19291937
ast::LitUint(u, _t) => u.to_str(),

src/librustdoc/html/highlight.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
140140
}
141141

142142
// text literals
143-
t::LIT_CHAR(..) | t::LIT_STR(..) | t::LIT_STR_RAW(..) => "string",
143+
t::LIT_BYTE(..) | t::LIT_CHAR(..) | t::LIT_STR(..) | t::LIT_STR_RAW(..) => "string",
144144

145145
// number literals
146146
t::LIT_INT(..) | t::LIT_UINT(..) | t::LIT_INT_UNSUFFIXED(..) |

src/libsyntax/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,7 @@ pub type Lit = Spanned<Lit_>;
616616
pub enum Lit_ {
617617
LitStr(InternedString, StrStyle),
618618
LitBinary(Rc<Vec<u8> >),
619+
LitByte(u8),
619620
LitChar(char),
620621
LitInt(i64, IntTy),
621622
LitUint(u64, UintTy),

src/libsyntax/ext/concat.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
4747
ast::LitBool(b) => {
4848
accumulator.push_str(format!("{}", b).as_slice());
4949
}
50+
ast::LitByte(..) |
5051
ast::LitBinary(..) => {
5152
cx.span_err(e.span, "cannot concatenate a binary literal");
5253
}

src/libsyntax/ext/quote.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,12 @@ fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> Gc<ast::Expr> {
436436
vec!(mk_binop(cx, sp, binop)));
437437
}
438438

439+
LIT_BYTE(i) => {
440+
let e_byte = cx.expr_lit(sp, ast::LitByte(i));
441+
442+
return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_BYTE"), vec!(e_byte));
443+
}
444+
439445
LIT_CHAR(i) => {
440446
let e_char = cx.expr_lit(sp, ast::LitChar(i));
441447

src/libsyntax/parse/lexer/mod.rs

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -650,10 +650,13 @@ impl<'a> StringReader<'a> {
650650
/// token, and updates the interner
651651
fn next_token_inner(&mut self) -> token::Token {
652652
let c = self.curr;
653-
if ident_start(c) && !self.nextch_is('"') && !self.nextch_is('#') {
653+
if ident_start(c) && match (c.unwrap(), self.nextch()) {
654654
// Note: r as in r" or r#" is part of a raw string literal,
655-
// not an identifier, and is handled further down.
656-
655+
// b as in b' is part of a byte literal.
656+
// They are not identifiers, and are handled further down.
657+
('r', Some('"')) | ('r', Some('#')) | ('b', Some('\'')) => false,
658+
_ => true
659+
} {
657660
let start = self.last_pos;
658661
while ident_continue(self.curr) {
659662
self.bump();
@@ -854,6 +857,65 @@ impl<'a> StringReader<'a> {
854857
self.bump(); // advance curr past token
855858
return token::LIT_CHAR(c2);
856859
}
860+
'b' => {
861+
self.bump();
862+
assert!(self.curr_is('\''), "Should have been a token::IDENT");
863+
self.bump();
864+
let start = self.last_pos;
865+
866+
// the eof will be picked up by the final `'` check below
867+
let mut c2 = self.curr.unwrap_or('\x00');
868+
self.bump();
869+
870+
match c2 {
871+
'\\' => {
872+
// '\X' for some X must be a character constant:
873+
let escaped = self.curr;
874+
let escaped_pos = self.last_pos;
875+
self.bump();
876+
match escaped {
877+
None => {}
878+
Some(e) => {
879+
c2 = match e {
880+
'n' => '\n',
881+
'r' => '\r',
882+
't' => '\t',
883+
'\\' => '\\',
884+
'\'' => '\'',
885+
'"' => '"',
886+
'0' => '\x00',
887+
'x' => self.scan_numeric_escape(2u, '\''),
888+
c2 => {
889+
self.err_span_char(escaped_pos, self.last_pos,
890+
"unknown byte escape", c2);
891+
c2
892+
}
893+
}
894+
}
895+
}
896+
}
897+
'\t' | '\n' | '\r' | '\'' => {
898+
self.err_span_char( start, self.last_pos,
899+
"byte constant must be escaped", c2);
900+
}
901+
_ if c2 > '\x7F' => {
902+
self.err_span_char( start, self.last_pos,
903+
"byte constant must be ASCII. \
904+
Use a \\xHH escape for a non-ASCII byte", c2);
905+
}
906+
_ => {}
907+
}
908+
if !self.curr_is('\'') {
909+
self.fatal_span_verbose(
910+
// Byte offsetting here is okay because the
911+
// character before position `start` are an
912+
// ascii single quote and ascii 'b'.
913+
start - BytePos(2), self.last_pos,
914+
"unterminated byte constant".to_string());
915+
}
916+
self.bump(); // advance curr past token
917+
return token::LIT_BYTE(c2 as u8);
918+
}
857919
'"' => {
858920
let mut accum_str = String::new();
859921
let start_bpos = self.last_pos;

0 commit comments

Comments
 (0)