Skip to content

Fixed-size byte string literals (RFC 339) #22838

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 18, 2015
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Fixed-size byte string literals (RFC 339)
  • Loading branch information
petrochenkov committed Mar 17, 2015
commit 1e9bef916f471e43fcd18593f95374ac42acf99e
9 changes: 1 addition & 8 deletions src/librustc_trans/trans/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,7 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit)
ast::LitBool(b) => C_bool(cx, b),
ast::LitStr(ref s, _) => C_str_slice(cx, (*s).clone()),
ast::LitBinary(ref data) => {
let g = addr_of(cx, C_bytes(cx, &data[..]), "binary", e.id);
let base = ptrcast(g, Type::i8p(cx));
let prev_const = cx.const_unsized().borrow_mut()
.insert(base, g);
assert!(prev_const.is_none() || prev_const == Some(g));
assert_eq!(abi::FAT_PTR_ADDR, 0);
assert_eq!(abi::FAT_PTR_EXTRA, 1);
C_struct(cx, &[base, C_uint(cx, data.len())], false)
addr_of(cx, C_bytes(cx, &data[..]), "binary", e.id)
}
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2505,10 +2505,11 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,

match lit.node {
ast::LitStr(..) => ty::mk_str_slice(tcx, tcx.mk_region(ty::ReStatic), ast::MutImmutable),
ast::LitBinary(..) => {
ty::mk_slice(tcx,
tcx.mk_region(ty::ReStatic),
ty::mt{ ty: tcx.types.u8, mutbl: ast::MutImmutable })
ast::LitBinary(ref v) => {
ty::mk_rptr(tcx, tcx.mk_region(ty::ReStatic), ty::mt {
ty: ty::mk_vec(tcx, tcx.types.u8, Some(v.len())),
mutbl: ast::MutImmutable,
})
}
ast::LitByte(_) => tcx.types.u8,
ast::LitChar(_) => tcx.types.char,
Expand Down
17 changes: 17 additions & 0 deletions src/libstd/ffi/c_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,23 @@ impl IntoBytes for Vec<u8> {
fn into_bytes(self) -> Vec<u8> { self }
}

macro_rules! array_impls {
($($N: expr)+) => {
$(
impl<'a> IntoBytes for &'a [u8; $N] {
fn into_bytes(self) -> Vec<u8> { self.to_vec() }
}
)+
}
}

array_impls! {
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32
}

#[cfg(test)]
mod tests {
use prelude::v1::*;
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/io/buffered.rs
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ mod tests {

#[test]
fn test_read_line() {
let in_buf = b"a\nb\nc";
let in_buf: &[u8] = b"a\nb\nc";
let mut reader = BufReader::with_capacity(2, in_buf);
let mut s = String::new();
reader.read_line(&mut s).unwrap();
Expand All @@ -640,7 +640,7 @@ mod tests {

#[test]
fn test_lines() {
let in_buf = b"a\nb\nc";
let in_buf: &[u8] = b"a\nb\nc";
let reader = BufReader::with_capacity(2, in_buf);
let mut it = reader.lines();
assert_eq!(it.next(), Some(Ok("a".to_string())));
Expand Down
17 changes: 17 additions & 0 deletions src/libstd/io/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,23 @@ impl<'a> BufRead for Cursor<&'a mut [u8]> { buffer!(); }
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> BufRead for Cursor<Vec<u8>> { buffer!(); }

macro_rules! array_impls {
($($N: expr)+) => {
$(
impl<'a> io::Seek for Cursor<&'a [u8; $N]> { seek!(); }
impl<'a> Read for Cursor<&'a [u8; $N]> { read!(); }
impl<'a> BufRead for Cursor<&'a [u8; $N]> { buffer!(); }
)+
}
}

array_impls! {
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for Cursor<&'a mut [u8]> {
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
Expand Down
3 changes: 2 additions & 1 deletion src/libstd/old_io/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,8 @@ mod test {

#[test]
fn limit_reader_buffer() {
let r = &mut b"0123456789\n0123456789\n";
let mut r: &[u8] = b"0123456789\n0123456789\n";
let r = &mut r;
{
let mut r = LimitReader::new(r.by_ref(), 3);
assert_eq!(r.read_line(), Ok("012".to_string()));
Expand Down
20 changes: 20 additions & 0 deletions src/libstd/old_path/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,26 @@ impl BytesContainer for [u8] {
}
}

macro_rules! array_impls {
($($N: expr)+) => {
$(
impl BytesContainer for [u8; $N] {
#[inline]
fn container_as_bytes(&self) -> &[u8] {
&self[..]
}
}
)+
}
}

array_impls! {
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32
}

impl BytesContainer for Vec<u8> {
#[inline]
fn container_as_bytes(&self) -> &[u8] {
Expand Down
30 changes: 15 additions & 15 deletions src/libstd/old_path/posix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -632,9 +632,9 @@ mod tests {
);
}

t!(v: b"a/b/c", filename, Some(b"c"));
t!(v: b"a/b/c\xFF", filename, Some(b"c\xFF"));
t!(v: b"a/b\xFF/c", filename, Some(b"c"));
t!(v: b"a/b/c", filename, Some(&b"c"[..]));
t!(v: b"a/b/c\xFF", filename, Some(&b"c\xFF"[..]));
t!(v: b"a/b\xFF/c", filename, Some(&b"c"[..]));
t!(s: "a/b/c", filename, Some("c"), opt);
t!(s: "/a/b/c", filename, Some("c"), opt);
t!(s: "a", filename, Some("a"), opt);
Expand All @@ -656,9 +656,9 @@ mod tests {
t!(s: "..", dirname, "..");
t!(s: "../..", dirname, "../..");

t!(v: b"hi/there.txt", filestem, Some(b"there"));
t!(v: b"hi/there\x80.txt", filestem, Some(b"there\x80"));
t!(v: b"hi/there.t\x80xt", filestem, Some(b"there"));
t!(v: b"hi/there.txt", filestem, Some(&b"there"[..]));
t!(v: b"hi/there\x80.txt", filestem, Some(&b"there\x80"[..]));
t!(v: b"hi/there.t\x80xt", filestem, Some(&b"there"[..]));
t!(s: "hi/there.txt", filestem, Some("there"), opt);
t!(s: "hi/there", filestem, Some("there"), opt);
t!(s: "there.txt", filestem, Some("there"), opt);
Expand All @@ -672,9 +672,9 @@ mod tests {
t!(s: "..", filestem, None, opt);
t!(s: "../..", filestem, None, opt);

t!(v: b"hi/there.txt", extension, Some(b"txt"));
t!(v: b"hi/there\x80.txt", extension, Some(b"txt"));
t!(v: b"hi/there.t\x80xt", extension, Some(b"t\x80xt"));
t!(v: b"hi/there.txt", extension, Some(&b"txt"[..]));
t!(v: b"hi/there\x80.txt", extension, Some(&b"txt"[..]));
t!(v: b"hi/there.t\x80xt", extension, Some(&b"t\x80xt"[..]));
t!(v: b"hi/there", extension, None);
t!(v: b"hi/there\x80", extension, None);
t!(s: "hi/there.txt", extension, Some("txt"), opt);
Expand Down Expand Up @@ -756,8 +756,8 @@ mod tests {
t!(s: "a/b/c", ["d", "/e"], "/e");
t!(s: "a/b/c", ["d", "/e", "f"], "/e/f");
t!(s: "a/b/c", ["d".to_string(), "e".to_string()], "a/b/c/d/e");
t!(v: b"a/b/c", [b"d", b"e"], b"a/b/c/d/e");
t!(v: b"a/b/c", [b"d", b"/e", b"f"], b"/e/f");
t!(v: b"a/b/c", [&b"d"[..], &b"e"[..]], b"a/b/c/d/e");
t!(v: b"a/b/c", [&b"d"[..], &b"/e"[..], &b"f"[..]], b"/e/f");
t!(v: b"a/b/c", [b"d".to_vec(), b"e".to_vec()], b"a/b/c/d/e");
}

Expand Down Expand Up @@ -983,10 +983,10 @@ mod tests {
)
}

t!(v: Path::new(b"a/b/c"), Some(b"c"), b"a/b", Some(b"c"), None);
t!(v: Path::new(b"a/b/\xFF"), Some(b"\xFF"), b"a/b", Some(b"\xFF"), None);
t!(v: Path::new(b"hi/there.\xFF"), Some(b"there.\xFF"), b"hi",
Some(b"there"), Some(b"\xFF"));
t!(v: Path::new(b"a/b/c"), Some(&b"c"[..]), b"a/b", Some(&b"c"[..]), None);
t!(v: Path::new(b"a/b/\xFF"), Some(&b"\xFF"[..]), b"a/b", Some(&b"\xFF"[..]), None);
t!(v: Path::new(b"hi/there.\xFF"), Some(&b"there.\xFF"[..]), b"hi",
Some(&b"there"[..]), Some(&b"\xFF"[..]));
t!(s: Path::new("a/b/c"), Some("c"), Some("a/b"), Some("c"), None);
t!(s: Path::new("."), None, Some("."), None, None);
t!(s: Path::new("/"), None, Some("/"), None, None);
Expand Down
12 changes: 6 additions & 6 deletions src/libstd/old_path/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1397,7 +1397,7 @@ mod tests {
)
}

t!(v: b"a\\b\\c", filename, Some(b"c"));
t!(v: b"a\\b\\c", filename, Some(&b"c"[..]));
t!(s: "a\\b\\c", filename_str, "c");
t!(s: "\\a\\b\\c", filename_str, "c");
t!(s: "a", filename_str, "a");
Expand Down Expand Up @@ -1461,7 +1461,7 @@ mod tests {
t!(s: "\\\\.\\foo", dirname_str, "\\\\.\\foo");
t!(s: "\\\\?\\a\\b\\", dirname_str, "\\\\?\\a");

t!(v: b"hi\\there.txt", filestem, Some(b"there"));
t!(v: b"hi\\there.txt", filestem, Some(&b"there"[..]));
t!(s: "hi\\there.txt", filestem_str, "there");
t!(s: "hi\\there", filestem_str, "there");
t!(s: "there.txt", filestem_str, "there");
Expand All @@ -1476,7 +1476,7 @@ mod tests {
t!(s: "..\\..", filestem_str, None, opt);
// filestem is based on filename, so we don't need the full set of prefix tests

t!(v: b"hi\\there.txt", extension, Some(b"txt"));
t!(v: b"hi\\there.txt", extension, Some(&b"txt"[..]));
t!(v: b"hi\\there", extension, None);
t!(s: "hi\\there.txt", extension_str, Some("txt"), opt);
t!(s: "hi\\there", extension_str, None, opt);
Expand Down Expand Up @@ -1603,8 +1603,8 @@ mod tests {
t!(s: "a\\b\\c", ["d", "\\e"], "\\e");
t!(s: "a\\b\\c", ["d", "\\e", "f"], "\\e\\f");
t!(s: "a\\b\\c", ["d".to_string(), "e".to_string()], "a\\b\\c\\d\\e");
t!(v: b"a\\b\\c", [b"d", b"e"], b"a\\b\\c\\d\\e");
t!(v: b"a\\b\\c", [b"d", b"\\e", b"f"], b"\\e\\f");
t!(v: b"a\\b\\c", [&b"d"[..], &b"e"[..]], b"a\\b\\c\\d\\e");
t!(v: b"a\\b\\c", [&b"d"[..], &b"\\e"[..], &b"f"[..]], b"\\e\\f");
t!(v: b"a\\b\\c", [b"d".to_vec(), b"e".to_vec()],
b"a\\b\\c\\d\\e");
}
Expand Down Expand Up @@ -1898,7 +1898,7 @@ mod tests {
)
}

t!(v: Path::new(b"a\\b\\c"), Some(b"c"), b"a\\b", Some(b"c"), None);
t!(v: Path::new(b"a\\b\\c"), Some(&b"c"[..]), b"a\\b", Some(&b"c"[..]), None);
t!(s: Path::new("a\\b\\c"), Some("c"), Some("a\\b"), Some("c"), None);
t!(s: Path::new("."), None, Some("."), None, None);
t!(s: Path::new("\\"), None, Some("\\"), None, None);
Expand Down
22 changes: 15 additions & 7 deletions src/test/run-pass/byte-literals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@

static FOO: u8 = b'\xF0';
static BAR: &'static [u8] = b"a\xF0\t";
static BAR_FIXED: &'static [u8; 3] = b"a\xF0\t";
static BAZ: &'static [u8] = br"a\n";

pub fn main() {
let bar: &'static [u8] = b"a\xF0\t";
let bar_fixed: &'static [u8; 3] = b"a\xF0\t";

assert_eq!(b'a', 97u8);
assert_eq!(b'\n', 10u8);
assert_eq!(b'\r', 13u8);
Expand Down Expand Up @@ -44,19 +48,23 @@ pub fn main() {
b", expected);
let expected: &[_] = &[97u8, 240u8, 9u8];
assert_eq!(BAR, expected);
assert_eq!(BAR_FIXED, expected);
assert_eq!(bar, expected);
assert_eq!(bar_fixed, expected);

let val: &[_] = &[97u8, 10u8];
let val = &[97u8, 10u8];
match val {
b"a\n" => {},
_ => panic!(),
}

let buf = vec!(97u8, 98, 99, 100);
assert_eq!(match &buf[0..3] {
b"def" => 1_usize,
b"abc" => 2_usize,
_ => 3_usize
}, 2);
// FIXME: There are no DST coercions &[T; N] -> &[T] in patterns
// let buf = vec!(97u8, 98, 99, 100);
// assert_eq!(match &buf[0..3] {
// b"def" => 1_usize,
// b"abc" => 2_usize,
// _ => 3_usize
// }, 2);

let expected: &[_] = &[97u8, 92u8, 110u8];
assert_eq!(BAZ, expected);
Expand Down