diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 2cec42b76bce3..1c6e5459659eb 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -31,6 +31,7 @@ #![feature(box_syntax)] #![feature(clone_from_slice)] #![feature(collections)] +#![feature(convert)] #![feature(const_fn)] #![feature(duration)] #![feature(duration_span)] diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 8d5357fa6e417..06dc76f396356 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -232,10 +232,10 @@ pub fn memoized(cache: &RefCell>, arg: T, f: F) -> #[cfg(unix)] pub fn path2cstr(p: &Path) -> CString { - use std::os::unix::prelude::*; use std::ffi::OsStr; let p: &OsStr = p.as_ref(); - CString::new(p.as_bytes()).unwrap() + // to_bytes() never returns None on unix + CString::new(p.to_bytes().unwrap()).unwrap() } #[cfg(windows)] pub fn path2cstr(p: &Path) -> CString { diff --git a/src/librustc_llvm/archive_ro.rs b/src/librustc_llvm/archive_ro.rs index b591e37f893e2..38304c580b309 100644 --- a/src/librustc_llvm/archive_ro.rs +++ b/src/librustc_llvm/archive_ro.rs @@ -47,16 +47,10 @@ impl ArchiveRO { } }; - #[cfg(unix)] fn path2cstr(p: &Path) -> CString { - use std::os::unix::prelude::*; use std::ffi::OsStr; let p: &OsStr = p.as_ref(); - CString::new(p.as_bytes()).unwrap() - } - #[cfg(windows)] - fn path2cstr(p: &Path) -> CString { - CString::new(p.to_str().unwrap()).unwrap() + CString::new(p.to_bytes().unwrap()).unwrap() } } diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index c4960c8d6a399..c8f3415b5d82b 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -27,6 +27,7 @@ #![feature(associated_consts)] #![feature(box_syntax)] +#![feature(convert)] #![feature(libc)] #![feature(link_args)] #![feature(staged_api)] diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 97bf33335b02a..90ac3c0f2e6f7 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -41,6 +41,7 @@ use mem; use string::String; use ops; use cmp; +use str; use hash::{Hash, Hasher}; use vec::Vec; @@ -265,6 +266,23 @@ impl OsStr { } } + /// Converts a byte slice to an `OsStr` slice. + /// + /// # Platform behavior + /// + /// On Unix systems, this is a no-op. + /// + /// On Windows systems, only UTF-8 byte sequences will successfully + /// convert; non UTF-8 data will produce `None`. + #[unstable(feature = "convert", reason = "recently added")] + pub fn from_bytes(bytes: &[u8]) -> Option<&OsStr> { + if cfg!(windows) { + str::from_utf8(bytes).ok().map(|s| s.as_ref()) + } else { + Some(unsafe { mem::transmute(bytes) }) + } + } + /// Creates a `CString` containing this `OsStr` data. /// /// Fails if the `OsStr` contains interior nulls. diff --git a/src/libstd/sys/unix/backtrace.rs b/src/libstd/sys/unix/backtrace.rs index b23a3eee1a173..1880f5a60cc04 100644 --- a/src/libstd/sys/unix/backtrace.rs +++ b/src/libstd/sys/unix/backtrace.rs @@ -251,7 +251,6 @@ fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void, fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void, symaddr: *mut libc::c_void) -> io::Result<()> { use env; - use os::unix::prelude::*; use ptr; //////////////////////////////////////////////////////////////////////// @@ -370,7 +369,8 @@ fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void, }; let filename = match selfname { Some(path) => { - let bytes = path.as_os_str().as_bytes(); + // to_bytes() never returns None on unix + let bytes = path.as_os_str().to_bytes().unwrap(); if bytes.len() < LAST_FILENAME.len() { let i = bytes.iter(); for (slot, val) in LAST_FILENAME.iter_mut().zip(i) { diff --git a/src/libstd/sys/unix/ext/ffi.rs b/src/libstd/sys/unix/ext/ffi.rs index 825e74cabdebb..dbf9a61124aaf 100644 --- a/src/libstd/sys/unix/ext/ffi.rs +++ b/src/libstd/sys/unix/ext/ffi.rs @@ -12,11 +12,10 @@ #![stable(feature = "rust1", since = "1.0.0")] -use ffi::{OsStr, OsString}; -use mem; +use ffi::OsString; use prelude::v1::*; use sys::os_str::Buf; -use sys_common::{FromInner, IntoInner, AsInner}; +use sys_common::{FromInner, IntoInner}; /// Unix-specific extensions to `OsString`. #[stable(feature = "rust1", since = "1.0.0")] @@ -39,24 +38,3 @@ impl OsStringExt for OsString { self.into_inner().inner } } - -/// Unix-specific extensions to `OsStr`. -#[stable(feature = "rust1", since = "1.0.0")] -pub trait OsStrExt { - #[stable(feature = "rust1", since = "1.0.0")] - fn from_bytes(slice: &[u8]) -> &Self; - - /// Gets the underlying byte view of the `OsStr` slice. - #[stable(feature = "rust1", since = "1.0.0")] - fn as_bytes(&self) -> &[u8]; -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl OsStrExt for OsStr { - fn from_bytes(slice: &[u8]) -> &OsStr { - unsafe { mem::transmute(slice) } - } - fn as_bytes(&self) -> &[u8] { - &self.as_inner().inner - } -} diff --git a/src/libstd/sys/unix/ext/mod.rs b/src/libstd/sys/unix/ext/mod.rs index 48c77480899f7..8da339ab8502f 100644 --- a/src/libstd/sys/unix/ext/mod.rs +++ b/src/libstd/sys/unix/ext/mod.rs @@ -43,7 +43,7 @@ pub mod prelude { #[doc(no_inline)] pub use super::io::{RawFd, AsRawFd, FromRawFd}; #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")] - pub use super::ffi::{OsStrExt, OsStringExt}; + pub use super::ffi::OsStringExt; #[doc(no_inline)] pub use super::fs::{PermissionsExt, OpenOptionsExt, MetadataExt}; #[doc(no_inline)] diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 128284834ab01..2fe66e411dac8 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -166,11 +166,13 @@ impl Drop for Dir { impl DirEntry { pub fn path(&self) -> PathBuf { - self.root.join(::from_bytes(self.name_bytes())) + // to_bytes() never returns None on unix + self.root.join(OsStr::from_bytes(self.name_bytes()).unwrap()) } pub fn file_name(&self) -> OsString { - OsStr::from_bytes(self.name_bytes()).to_os_string() + // from_bytes() never returns None on unix + OsStr::from_bytes(self.name_bytes()).unwrap().to_os_string() } pub fn metadata(&self) -> io::Result { @@ -504,7 +506,8 @@ pub fn utimes(p: &Path, atime: u64, mtime: u64) -> io::Result<()> { } pub fn canonicalize(p: &Path) -> io::Result { - let path = try!(CString::new(p.as_os_str().as_bytes())); + // from_bytes() never returns None on unix + let path = try!(CString::new(p.as_os_str().to_bytes().unwrap())); let mut buf = vec![0u8; 16 * 1024]; unsafe { let r = c::realpath(path.as_ptr(), buf.as_mut_ptr() as *mut _); diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 5178d7b8fb1a0..7e02d59ee454c 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -34,11 +34,13 @@ const BUF_BYTES: usize = 2048; const TMPBUF_SZ: usize = 128; fn bytes2path(b: &[u8]) -> PathBuf { - PathBuf::from(::from_bytes(b)) + // from_bytes() never returns None on unix + PathBuf::from(OsStr::from_bytes(b).unwrap()) } fn os2path(os: OsString) -> PathBuf { - bytes2path(os.as_bytes()) + // to_bytes() never returns None on unix + bytes2path(os.to_bytes().unwrap()) } /// Returns the platform-specific value of errno @@ -124,7 +126,8 @@ pub fn getcwd() -> io::Result { pub fn chdir(p: &path::Path) -> io::Result<()> { let p: &OsStr = p.as_ref(); - let p = try!(CString::new(p.as_bytes())); + // to_bytes() never returns None on unix + let p = try!(CString::new(p.to_bytes().unwrap())); unsafe { match libc::chdir(p.as_ptr()) == (0 as c_int) { true => Ok(()), @@ -140,7 +143,8 @@ pub struct SplitPaths<'a> { pub fn split_paths<'a>(unparsed: &'a OsStr) -> SplitPaths<'a> { fn is_colon(b: &u8) -> bool { *b == b':' } - let unparsed = unparsed.as_bytes(); + // to_bytes() never returns None on unix + let unparsed = unparsed.to_bytes().unwrap(); SplitPaths { iter: unparsed.split(is_colon as fn(&u8) -> bool) .map(bytes2path as fn(&'a [u8]) -> PathBuf) @@ -163,7 +167,8 @@ pub fn join_paths(paths: I) -> Result let sep = b':'; for (i, path) in paths.enumerate() { - let path = path.as_ref().as_bytes(); + // to_bytes() never returns None on unix + let path = path.as_ref().to_bytes().unwrap(); if i > 0 { joined.push(sep) } if path.contains(&sep) { return Err(JoinPathsError) diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs index 695d0ddfaaf61..80b903cd90fd5 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -390,9 +390,10 @@ fn make_envp(env: Option<&HashMap>) for pair in env { let mut kv = Vec::new(); - kv.push_all(pair.0.as_bytes()); + // to_bytes() never returns None on unix + kv.push_all(pair.0.to_bytes().unwrap()); kv.push('=' as u8); - kv.push_all(pair.1.as_bytes()); + kv.push_all(pair.1.to_bytes().unwrap()); kv.push(0); // terminating null tmps.push(kv); }