From f8493447bf6d2fbac1a66c111d44f9fcf1552ac6 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 30 Oct 2014 22:36:23 -0700 Subject: [PATCH] rustc: Change byte literals to fixed-size arrays This commit alters the type of `b"foo"` from `&'static [u8]` to `&'static [u8, ..3]` and is an implementation of RFC 339. This is a breaking change because not all operations are always compatible with fixed-size arrays currently when compared with slices. As seen in the diff, if a fixed-size array is the left hand size of an equality then the operator may not resolve. Breakage may require some shuffling or explicitly converting to a slice via `.as_slice()` or `[]`. [breaking-change] Closes #18465 --- src/librustc/middle/trans/common.rs | 7 ++----- src/librustc/middle/trans/consts.rs | 2 +- src/librustc/middle/typeck/check/mod.rs | 7 +++++-- src/libstd/path/posix.rs | 14 +++++++------- src/libsyntax/ast.rs | 2 +- src/test/run-pass/issue-18465.rs | 17 +++++++++++++++++ 6 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 src/test/run-pass/issue-18465.rs diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 60b107c049f41..e4c90be05c41b 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -677,9 +677,8 @@ pub fn C_str_slice(cx: &CrateContext, s: InternedString) -> ValueRef { } } -pub fn C_binary_slice(cx: &CrateContext, data: &[u8]) -> ValueRef { +pub fn C_binary_array(cx: &CrateContext, data: &[u8]) -> ValueRef { unsafe { - let len = data.len(); let lldata = C_bytes(cx, data); let gsym = token::gensym("binary"); @@ -689,9 +688,7 @@ pub fn C_binary_slice(cx: &CrateContext, data: &[u8]) -> ValueRef { llvm::LLVMSetInitializer(g, lldata); llvm::LLVMSetGlobalConstant(g, True); llvm::SetLinkage(g, llvm::InternalLinkage); - - let cs = llvm::LLVMConstPointerCast(g, Type::i8p(cx).to_ref()); - C_struct(cx, [cs, C_uint(cx, len)], false) + g } } diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 2f193754c1a50..ed8dab428bf78 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -83,7 +83,7 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit) ast::LitBool(b) => C_bool(cx, b), ast::LitNil => C_nil(cx), ast::LitStr(ref s, _) => C_str_slice(cx, (*s).clone()), - ast::LitBinary(ref data) => C_binary_slice(cx, data.as_slice()), + ast::LitBinary(ref data) => C_binary_array(cx, data.as_slice()), } } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 13ffc1f4fcbaa..155ba7b4b6ff5 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -2690,8 +2690,11 @@ fn check_lit(fcx: &FnCtxt, match lit.node { ast::LitStr(..) => ty::mk_str_slice(tcx, ty::ReStatic, ast::MutImmutable), - ast::LitBinary(..) => { - ty::mk_slice(tcx, ty::ReStatic, ty::mt{ ty: ty::mk_u8(), mutbl: ast::MutImmutable }) + ast::LitBinary(ref v) => { + ty::mk_rptr(tcx, ty::ReStatic, ty::mt { + ty: ty::mk_vec(tcx, ty::mk_u8(), Some(v.len())), + mutbl: ast::MutImmutable, + }) } ast::LitByte(_) => ty::mk_u8(), ast::LitChar(_) => ty::mk_char(), diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index 0d7a467b313f2..2b93ede917e6e 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -154,7 +154,7 @@ impl GenericPathUnsafe for Path { unsafe fn set_filename_unchecked(&mut self, filename: T) { let filename = filename.container_as_bytes(); match self.sepidx { - None if b".." == self.repr.as_slice() => { + None if self.repr.as_slice() == b".." => { let mut v = Vec::with_capacity(3 + filename.len()); v.push_all(dot_dot_static); v.push(SEP_BYTE); @@ -214,7 +214,7 @@ impl GenericPath for Path { fn dirname<'a>(&'a self) -> &'a [u8] { match self.sepidx { - None if b".." == self.repr.as_slice() => self.repr.as_slice(), + None if self.repr.as_slice() == b".." => self.repr.as_slice(), None => dot_static, Some(0) => self.repr[..1], Some(idx) if self.repr[idx+1..] == b".." => self.repr.as_slice(), @@ -224,8 +224,8 @@ impl GenericPath for Path { fn filename<'a>(&'a self) -> Option<&'a [u8]> { match self.sepidx { - None if b"." == self.repr.as_slice() || - b".." == self.repr.as_slice() => None, + None if self.repr.as_slice() == b"." || + self.repr.as_slice() == b".." => None, None => Some(self.repr.as_slice()), Some(idx) if self.repr[idx+1..] == b".." => None, Some(0) if self.repr[1..].is_empty() => None, @@ -235,13 +235,13 @@ impl GenericPath for Path { fn pop(&mut self) -> bool { match self.sepidx { - None if b"." == self.repr.as_slice() => false, + None if self.repr.as_slice() == b"." => false, None => { self.repr = vec![b'.']; self.sepidx = None; true } - Some(0) if b"/" == self.repr.as_slice() => false, + Some(0) if self.repr.as_slice() == b"/" => false, Some(idx) => { if idx == 0 { self.repr.truncate(idx+1); @@ -273,7 +273,7 @@ impl GenericPath for Path { } else { let mut ita = self.components(); let mut itb = other.components(); - if b"." == self.repr.as_slice() { + if self.repr.as_slice() == b"." { return match itb.next() { None => true, Some(b) => b != b".." diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a2c859cf9fd3c..214acf4b7b536 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -801,7 +801,7 @@ impl LitIntType { #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum Lit_ { LitStr(InternedString, StrStyle), - LitBinary(Rc >), + LitBinary(Rc>), LitByte(u8), LitChar(char), LitInt(u64, LitIntType), diff --git a/src/test/run-pass/issue-18465.rs b/src/test/run-pass/issue-18465.rs new file mode 100644 index 0000000000000..2c2ee42f736ed --- /dev/null +++ b/src/test/run-pass/issue-18465.rs @@ -0,0 +1,17 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const FOO: &'static [u8, ..3] = b"foo"; +const BAR: &'static [u8] = b"foo"; + +fn main() { + let foo: &'static [u8, ..3] = b"foo"; + let bar: &'static [u8] = b"foo"; +}