diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index de0ca4971f5..977b7dc32c5 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -292,6 +292,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts { save_metrics: config.save_metrics.clone(), test_shard: config.test_shard.clone(), nocapture: false, + color: test::AutoColor, } } diff --git a/src/compiletest/procsrv.rs b/src/compiletest/procsrv.rs index a48a9f1be75..8fa34dd6d27 100644 --- a/src/compiletest/procsrv.rs +++ b/src/compiletest/procsrv.rs @@ -11,7 +11,7 @@ use std::os; use std::str; use std::io::process::{ProcessExit, Command, Process, ProcessOutput}; -use std::unstable::dynamic_lib::DynamicLibrary; +use std::dynamic_lib::DynamicLibrary; fn target_env(lib_path: &str, prog: &str) -> Vec<(String, String)> { let prog = if cfg!(windows) {prog.slice_to(prog.len() - 4)} else {prog}; diff --git a/src/libcollections/bitv.rs b/src/libcollections/bitv.rs index 42c81779770..e100baa1e3a 100644 --- a/src/libcollections/bitv.rs +++ b/src/libcollections/bitv.rs @@ -13,6 +13,7 @@ use core::prelude::*; use core::cmp; +use core::default::Default; use core::fmt; use core::iter::{Enumerate, Repeat, Map, Zip}; use core::ops; @@ -698,6 +699,11 @@ pub struct BitvSet { bitv: BigBitv } +impl Default for BitvSet { + #[inline] + fn default() -> BitvSet { BitvSet::new() } +} + impl BitvSet { /// Creates a new bit vector set with initially no contents pub fn new() -> BitvSet { diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index 5a231245691..ac8c5c5557e 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -24,6 +24,7 @@ use core::prelude::*; use alloc::owned::Box; +use core::default::Default; use core::fmt; use core::iter; use core::mem; @@ -262,6 +263,11 @@ impl Deque for DList { } } +impl Default for DList { + #[inline] + fn default() -> DList { DList::new() } +} + impl DList { /// Create an empty DList #[inline] diff --git a/src/libcollections/priority_queue.rs b/src/libcollections/priority_queue.rs index ea3e7d17471..f25864933f2 100644 --- a/src/libcollections/priority_queue.rs +++ b/src/libcollections/priority_queue.rs @@ -14,6 +14,7 @@ use core::prelude::*; +use core::default::Default; use core::mem::{zeroed, replace, swap}; use core::ptr; @@ -37,6 +38,11 @@ impl Mutable for PriorityQueue { fn clear(&mut self) { self.data.truncate(0) } } +impl Default for PriorityQueue { + #[inline] + fn default() -> PriorityQueue { PriorityQueue::new() } +} + impl PriorityQueue { /// An iterator visiting all values in underlying vector, in /// arbitrary order. diff --git a/src/libcollections/ringbuf.rs b/src/libcollections/ringbuf.rs index addf73d67a8..ae1925126ca 100644 --- a/src/libcollections/ringbuf.rs +++ b/src/libcollections/ringbuf.rs @@ -16,6 +16,7 @@ use core::prelude::*; use core::cmp; +use core::default::Default; use core::fmt; use core::iter::RandomAccessIterator; @@ -112,6 +113,11 @@ impl Deque for RingBuf { } } +impl Default for RingBuf { + #[inline] + fn default() -> RingBuf { RingBuf::new() } +} + impl RingBuf { /// Create an empty RingBuf pub fn new() -> RingBuf { diff --git a/src/libcollections/smallintmap.rs b/src/libcollections/smallintmap.rs index cc901864ab5..6b4982de082 100644 --- a/src/libcollections/smallintmap.rs +++ b/src/libcollections/smallintmap.rs @@ -17,6 +17,7 @@ use core::prelude::*; +use core::default::Default; use core::fmt; use core::iter::{Enumerate, FilterMap}; use core::mem::replace; @@ -114,6 +115,11 @@ impl MutableMap for SmallIntMap { } } +impl Default for SmallIntMap { + #[inline] + fn default() -> SmallIntMap { SmallIntMap::new() } +} + impl SmallIntMap { /// Create an empty SmallIntMap pub fn new() -> SmallIntMap { SmallIntMap{v: vec!()} } diff --git a/src/libcollections/treemap.rs b/src/libcollections/treemap.rs index 489fe60cebf..1f4ee52008c 100644 --- a/src/libcollections/treemap.rs +++ b/src/libcollections/treemap.rs @@ -15,6 +15,7 @@ use core::prelude::*; use alloc::owned::Box; +use core::default::Default; use core::fmt; use core::fmt::Show; use core::iter::Peekable; @@ -135,6 +136,11 @@ impl MutableMap for TreeMap { } } +impl Default for TreeMap { + #[inline] + fn default() -> TreeMap { TreeMap::new() } +} + impl TreeMap { /// Create an empty TreeMap pub fn new() -> TreeMap { TreeMap{root: None, length: 0} } @@ -633,6 +639,11 @@ impl MutableSet for TreeSet { fn remove(&mut self, value: &T) -> bool { self.map.remove(value) } } +impl Default for TreeSet { + #[inline] + fn default() -> TreeSet { TreeSet::new() } +} + impl TreeSet { /// Create an empty TreeSet #[inline] diff --git a/src/libcollections/trie.rs b/src/libcollections/trie.rs index 6e99d6054a5..3f4fdd66b80 100644 --- a/src/libcollections/trie.rs +++ b/src/libcollections/trie.rs @@ -13,6 +13,7 @@ use core::prelude::*; use alloc::owned::Box; +use core::default::Default; use core::mem::zeroed; use core::mem; use core::uint; @@ -105,6 +106,11 @@ impl MutableMap for TrieMap { } } +impl Default for TrieMap { + #[inline] + fn default() -> TrieMap { TrieMap::new() } +} + impl TrieMap { /// Create an empty TrieMap #[inline] @@ -332,6 +338,11 @@ impl MutableSet for TrieSet { } } +impl Default for TrieSet { + #[inline] + fn default() -> TrieSet { TrieSet::new() } +} + impl TrieSet { /// Create an empty TrieSet #[inline] diff --git a/src/libnative/io/c_win32.rs b/src/libnative/io/c_win32.rs index 93b3ec7ccef..1ec25933eec 100644 --- a/src/libnative/io/c_win32.rs +++ b/src/libnative/io/c_win32.rs @@ -69,7 +69,6 @@ extern "system" { pub mod compat { use std::intrinsics::{atomic_store_relaxed, transmute}; use libc::types::os::arch::extra::{LPCWSTR, HMODULE, LPCSTR, LPVOID}; - use std::os::win32::as_utf16_p; extern "system" { fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE; @@ -80,12 +79,11 @@ pub mod compat { // This way, calling a function in this compatibility layer (after it's loaded) shouldn't // be any slower than a regular DLL call. unsafe fn store_func(ptr: *mut T, module: &str, symbol: &str, fallback: T) { - as_utf16_p(module, |module| { - symbol.with_c_str(|symbol| { - let handle = GetModuleHandleW(module); - let func: Option = transmute(GetProcAddress(handle, symbol)); - atomic_store_relaxed(ptr, func.unwrap_or(fallback)) - }) + let module = module.to_utf16().append_one(0); + symbol.with_c_str(|symbol| { + let handle = GetModuleHandleW(module.as_ptr()); + let func: Option = transmute(GetProcAddress(handle, symbol)); + atomic_store_relaxed(ptr, func.unwrap_or(fallback)) }) } diff --git a/src/libnative/io/file_win32.rs b/src/libnative/io/file_win32.rs index 2a5b78e5506..5ace8e347c6 100644 --- a/src/libnative/io/file_win32.rs +++ b/src/libnative/io/file_win32.rs @@ -15,10 +15,10 @@ use libc::{c_int, c_void}; use libc; use std::c_str::CString; use std::mem; -use std::os::win32::{as_utf16_p, fill_utf16_buf_and_decode}; +use std::os::win32::fill_utf16_buf_and_decode; use std::ptr; use std::rt::rtio; -use std::rt::rtio::IoResult; +use std::rt::rtio::{IoResult, IoError}; use std::str; use std::vec; @@ -253,6 +253,17 @@ impl Drop for Inner { } } +pub fn to_utf16(s: &CString) -> IoResult> { + match s.as_str() { + Some(s) => Ok(s.to_utf16().append_one(0)), + None => Err(IoError { + code: libc::ERROR_INVALID_NAME as uint, + extra: 0, + detail: Some("valid unicode input required".to_str()), + }) + } +} + pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess) -> IoResult { // Flags passed to open_osfhandle @@ -299,15 +310,16 @@ pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess) // Compat with unix, this allows opening directories (see libuv) dwFlagsAndAttributes |= libc::FILE_FLAG_BACKUP_SEMANTICS; - let handle = as_utf16_p(path.as_str().unwrap(), |buf| unsafe { - libc::CreateFileW(buf, + let path = try!(to_utf16(path)); + let handle = unsafe { + libc::CreateFileW(path.as_ptr(), dwDesiredAccess, dwShareMode, ptr::mut_null(), dwCreationDisposition, dwFlagsAndAttributes, ptr::mut_null()) - }); + }; if handle == libc::INVALID_HANDLE_VALUE as libc::HANDLE { Err(super::last_error()) } else { @@ -324,11 +336,10 @@ pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess) } pub fn mkdir(p: &CString, _mode: uint) -> IoResult<()> { + let p = try!(to_utf16(p)); super::mkerr_winbool(unsafe { // FIXME: turn mode into something useful? #2623 - as_utf16_p(p.as_str().unwrap(), |buf| { - libc::CreateDirectoryW(buf, ptr::mut_null()) - }) + libc::CreateDirectoryW(p.as_ptr(), ptr::mut_null()) }) } @@ -351,9 +362,11 @@ pub fn readdir(p: &CString) -> IoResult> { let star = Path::new(unsafe { CString::new(p.with_ref(|p| p), false) }).join("*"); - as_utf16_p(star.as_str().unwrap(), |path_ptr| unsafe { + let path = try!(to_utf16(&star.to_c_str())); + + unsafe { let wfd_ptr = malloc_raw(rust_list_dir_wfd_size() as uint); - let find_handle = libc::FindFirstFileW(path_ptr, wfd_ptr as libc::HANDLE); + let find_handle = libc::FindFirstFileW(path.as_ptr(), wfd_ptr as libc::HANDLE); if find_handle as libc::c_int != libc::INVALID_HANDLE_VALUE { let mut paths = vec!(); let mut more_files = 1 as libc::c_int; @@ -377,37 +390,35 @@ pub fn readdir(p: &CString) -> IoResult> { } else { Err(super::last_error()) } - }) + } } pub fn unlink(p: &CString) -> IoResult<()> { + let p = try!(to_utf16(p)); super::mkerr_winbool(unsafe { - as_utf16_p(p.as_str().unwrap(), |buf| { - libc::DeleteFileW(buf) - }) + libc::DeleteFileW(p.as_ptr()) }) } pub fn rename(old: &CString, new: &CString) -> IoResult<()> { + let old = try!(to_utf16(old)); + let new = try!(to_utf16(new)); super::mkerr_winbool(unsafe { - as_utf16_p(old.as_str().unwrap(), |old| { - as_utf16_p(new.as_str().unwrap(), |new| { - libc::MoveFileExW(old, new, libc::MOVEFILE_REPLACE_EXISTING) - }) - }) + libc::MoveFileExW(old.as_ptr(), new.as_ptr(), + libc::MOVEFILE_REPLACE_EXISTING) }) } pub fn chmod(p: &CString, mode: uint) -> IoResult<()> { - super::mkerr_libc(as_utf16_p(p.as_str().unwrap(), |p| unsafe { - libc::wchmod(p, mode as libc::c_int) - })) + let p = try!(to_utf16(p)); + super::mkerr_libc(unsafe { + libc::wchmod(p.as_ptr(), mode as libc::c_int) + }) } pub fn rmdir(p: &CString) -> IoResult<()> { - super::mkerr_libc(as_utf16_p(p.as_str().unwrap(), |p| unsafe { - libc::wrmdir(p) - })) + let p = try!(to_utf16(p)); + super::mkerr_libc(unsafe { libc::wrmdir(p.as_ptr()) }) } pub fn chown(_p: &CString, _uid: int, _gid: int) -> IoResult<()> { @@ -418,16 +429,15 @@ pub fn chown(_p: &CString, _uid: int, _gid: int) -> IoResult<()> { pub fn readlink(p: &CString) -> IoResult { // FIXME: I have a feeling that this reads intermediate symlinks as well. use io::c::compat::kernel32::GetFinalPathNameByHandleW; + let p = try!(to_utf16(p)); let handle = unsafe { - as_utf16_p(p.as_str().unwrap(), |p| { - libc::CreateFileW(p, - libc::GENERIC_READ, - libc::FILE_SHARE_READ, - ptr::mut_null(), - libc::OPEN_EXISTING, - libc::FILE_ATTRIBUTE_NORMAL, - ptr::mut_null()) - }) + libc::CreateFileW(p.as_ptr(), + libc::GENERIC_READ, + libc::FILE_SHARE_READ, + ptr::mut_null(), + libc::OPEN_EXISTING, + libc::FILE_ATTRIBUTE_NORMAL, + ptr::mut_null()) }; if handle as int == libc::INVALID_HANDLE_VALUE as int { return Err(super::last_error()) @@ -453,19 +463,19 @@ pub fn readlink(p: &CString) -> IoResult { pub fn symlink(src: &CString, dst: &CString) -> IoResult<()> { use io::c::compat::kernel32::CreateSymbolicLinkW; - super::mkerr_winbool(as_utf16_p(src.as_str().unwrap(), |src| { - as_utf16_p(dst.as_str().unwrap(), |dst| { - unsafe { CreateSymbolicLinkW(dst, src, 0) } - }) as libc::BOOL - })) + let src = try!(to_utf16(src)); + let dst = try!(to_utf16(dst)); + super::mkerr_winbool(unsafe { + CreateSymbolicLinkW(dst.as_ptr(), src.as_ptr(), 0) as libc::BOOL + }) } pub fn link(src: &CString, dst: &CString) -> IoResult<()> { - super::mkerr_winbool(as_utf16_p(src.as_str().unwrap(), |src| { - as_utf16_p(dst.as_str().unwrap(), |dst| { - unsafe { libc::CreateHardLinkW(dst, src, ptr::mut_null()) } - }) - })) + let src = try!(to_utf16(src)); + let dst = try!(to_utf16(dst)); + super::mkerr_winbool(unsafe { + libc::CreateHardLinkW(dst.as_ptr(), src.as_ptr(), ptr::mut_null()) + }) } fn mkstat(stat: &libc::stat) -> rtio::FileStat { @@ -491,12 +501,11 @@ fn mkstat(stat: &libc::stat) -> rtio::FileStat { pub fn stat(p: &CString) -> IoResult { let mut stat: libc::stat = unsafe { mem::zeroed() }; - as_utf16_p(p.as_str().unwrap(), |up| { - match unsafe { libc::wstat(up, &mut stat) } { - 0 => Ok(mkstat(&stat)), - _ => Err(super::last_error()), - } - }) + let p = try!(to_utf16(p)); + match unsafe { libc::wstat(p.as_ptr(), &mut stat) } { + 0 => Ok(mkstat(&stat)), + _ => Err(super::last_error()), + } } pub fn lstat(_p: &CString) -> IoResult { @@ -509,7 +518,8 @@ pub fn utime(p: &CString, atime: u64, mtime: u64) -> IoResult<()> { actime: (atime / 1000) as libc::time64_t, modtime: (mtime / 1000) as libc::time64_t, }; - super::mkerr_libc(as_utf16_p(p.as_str().unwrap(), |p| unsafe { - libc::wutime(p, &buf) - })) + let p = try!(to_utf16(p)); + super::mkerr_libc(unsafe { + libc::wutime(p.as_ptr(), &buf) + }) } diff --git a/src/libnative/io/mod.rs b/src/libnative/io/mod.rs index 3b0dbe2d0dc..4c5929ef223 100644 --- a/src/libnative/io/mod.rs +++ b/src/libnative/io/mod.rs @@ -77,7 +77,7 @@ fn unimpl() -> IoError { IoError { code: ERROR as uint, extra: 0, - detail: None, + detail: Some("not yet supported by the `native` runtime, maybe try `green`.".to_string()), } } diff --git a/src/libnative/io/pipe_win32.rs b/src/libnative/io/pipe_win32.rs index a5694436b97..45b12aa7007 100644 --- a/src/libnative/io/pipe_win32.rs +++ b/src/libnative/io/pipe_win32.rs @@ -88,7 +88,6 @@ use alloc::arc::Arc; use libc; use std::c_str::CString; use std::mem; -use std::os::win32::as_utf16_p; use std::os; use std::ptr; use std::rt::rtio; @@ -98,6 +97,7 @@ use std::rt::mutex; use super::c; use super::util; +use super::file::to_utf16; struct Event(libc::HANDLE); @@ -261,67 +261,66 @@ impl UnixStream { } pub fn connect(addr: &CString, timeout: Option) -> IoResult { - as_utf16_p(addr.as_str().unwrap(), |p| { - let start = ::io::timer::now(); - loop { - match UnixStream::try_connect(p) { - Some(handle) => { - let inner = Inner::new(handle); - let mut mode = libc::PIPE_TYPE_BYTE | - libc::PIPE_READMODE_BYTE | - libc::PIPE_WAIT; - let ret = unsafe { - libc::SetNamedPipeHandleState(inner.handle, - &mut mode, - ptr::mut_null(), - ptr::mut_null()) - }; - return if ret == 0 { - Err(super::last_error()) - } else { - Ok(UnixStream { - inner: Arc::new(inner), - read: None, - write: None, - read_deadline: 0, - write_deadline: 0, - }) - } + let addr = try!(to_utf16(addr)); + let start = ::io::timer::now(); + loop { + match UnixStream::try_connect(addr.as_ptr()) { + Some(handle) => { + let inner = Inner::new(handle); + let mut mode = libc::PIPE_TYPE_BYTE | + libc::PIPE_READMODE_BYTE | + libc::PIPE_WAIT; + let ret = unsafe { + libc::SetNamedPipeHandleState(inner.handle, + &mut mode, + ptr::mut_null(), + ptr::mut_null()) + }; + return if ret == 0 { + Err(super::last_error()) + } else { + Ok(UnixStream { + inner: Arc::new(inner), + read: None, + write: None, + read_deadline: 0, + write_deadline: 0, + }) + } + } + None => {} + } + + // On windows, if you fail to connect, you may need to call the + // `WaitNamedPipe` function, and this is indicated with an error + // code of ERROR_PIPE_BUSY. + let code = unsafe { libc::GetLastError() }; + if code as int != libc::ERROR_PIPE_BUSY as int { + return Err(super::last_error()) + } + + match timeout { + Some(timeout) => { + let now = ::io::timer::now(); + let timed_out = (now - start) >= timeout || unsafe { + let ms = (timeout - (now - start)) as libc::DWORD; + libc::WaitNamedPipeW(addr.as_ptr(), ms) == 0 + }; + if timed_out { + return Err(util::timeout("connect timed out")) } - None => {} } - // On windows, if you fail to connect, you may need to call the - // `WaitNamedPipe` function, and this is indicated with an error - // code of ERROR_PIPE_BUSY. - let code = unsafe { libc::GetLastError() }; - if code as int != libc::ERROR_PIPE_BUSY as int { - return Err(super::last_error()) - } - - match timeout { - Some(timeout) => { - let now = ::io::timer::now(); - let timed_out = (now - start) >= timeout || unsafe { - let ms = (timeout - (now - start)) as libc::DWORD; - libc::WaitNamedPipeW(p, ms) == 0 - }; - if timed_out { - return Err(util::timeout("connect timed out")) - } - } - - // An example I found on microsoft's website used 20 - // seconds, libuv uses 30 seconds, hence we make the - // obvious choice of waiting for 25 seconds. - None => { - if unsafe { libc::WaitNamedPipeW(p, 25000) } == 0 { - return Err(super::last_error()) - } + // An example I found on microsoft's website used 20 + // seconds, libuv uses 30 seconds, hence we make the + // obvious choice of waiting for 25 seconds. + None => { + if unsafe { libc::WaitNamedPipeW(addr.as_ptr(), 25000) } == 0 { + return Err(super::last_error()) } } } - }) + } } fn handle(&self) -> libc::HANDLE { self.inner.handle } @@ -564,14 +563,13 @@ impl UnixListener { // Although we technically don't need the pipe until much later, we // create the initial handle up front to test the validity of the name // and such. - as_utf16_p(addr.as_str().unwrap(), |p| { - let ret = unsafe { pipe(p, true) }; - if ret == libc::INVALID_HANDLE_VALUE as libc::HANDLE { - Err(super::last_error()) - } else { - Ok(UnixListener { handle: ret, name: addr.clone() }) - } - }) + let addr_v = try!(to_utf16(addr)); + let ret = unsafe { pipe(addr_v.as_ptr(), true) }; + if ret == libc::INVALID_HANDLE_VALUE as libc::HANDLE { + Err(super::last_error()) + } else { + Ok(UnixListener { handle: ret, name: addr.clone() }) + } } pub fn native_listen(self) -> IoResult { @@ -639,6 +637,8 @@ impl UnixAcceptor { // using the original server pipe. let handle = self.listener.handle; + let name = try!(to_utf16(&self.listener.name)); + // Once we've got a "server handle", we need to wait for a client to // connect. The ConnectNamedPipe function will block this thread until // someone on the other end connects. This function can "fail" if a @@ -678,9 +678,7 @@ impl UnixAcceptor { // Now that we've got a connected client to our handle, we need to // create a second server pipe. If this fails, we disconnect the // connected client and return an error (see comments above). - let new_handle = as_utf16_p(self.listener.name.as_str().unwrap(), |p| { - unsafe { pipe(p, false) } - }); + let new_handle = unsafe { pipe(name.as_ptr(), false) }; if new_handle == libc::INVALID_HANDLE_VALUE as libc::HANDLE { let ret = Err(super::last_error()); // If our disconnection fails, then there's not really a whole lot diff --git a/src/libnative/io/process.rs b/src/libnative/io/process.rs index 2c2b7cec1de..97b227ae1d8 100644 --- a/src/libnative/io/process.rs +++ b/src/libnative/io/process.rs @@ -296,16 +296,15 @@ fn spawn_process_os(cfg: ProcessConfig, lpSecurityDescriptor: ptr::mut_null(), bInheritHandle: 1, }; - *slot = os::win32::as_utf16_p("NUL", |filename| { - libc::CreateFileW(filename, - access, - libc::FILE_SHARE_READ | - libc::FILE_SHARE_WRITE, - &mut sa, - libc::OPEN_EXISTING, - 0, - ptr::mut_null()) - }); + let filename = "NUL".to_utf16().append_one(0); + *slot = libc::CreateFileW(filename.as_ptr(), + access, + libc::FILE_SHARE_READ | + libc::FILE_SHARE_WRITE, + &mut sa, + libc::OPEN_EXISTING, + 0, + ptr::mut_null()); if *slot == INVALID_HANDLE_VALUE as libc::HANDLE { return Err(super::last_error()) } @@ -338,18 +337,17 @@ fn spawn_process_os(cfg: ProcessConfig, with_envp(cfg.env, |envp| { with_dirp(cfg.cwd, |dirp| { - os::win32::as_mut_utf16_p(cmd_str.as_slice(), |cmdp| { - let created = CreateProcessW(ptr::null(), - cmdp, - ptr::mut_null(), - ptr::mut_null(), - TRUE, - flags, envp, dirp, - &mut si, &mut pi); - if created == FALSE { - create_err = Some(super::last_error()); - } - }) + let mut cmd_str = cmd_str.to_utf16().append_one(0); + let created = CreateProcessW(ptr::null(), + cmd_str.as_mut_ptr(), + ptr::mut_null(), + ptr::mut_null(), + TRUE, + flags, envp, dirp, + &mut si, &mut pi); + if created == FALSE { + create_err = Some(super::last_error()); + } }) }); @@ -740,7 +738,8 @@ fn with_dirp(d: Option<&CString>, cb: |*u16| -> T) -> T { Some(dir) => { let dir_str = dir.as_str() .expect("expected workingdirectory to be utf-8 encoded"); - os::win32::as_utf16_p(dir_str, cb) + let dir_str = dir_str.to_utf16().append_one(0); + cb(dir_str.as_ptr()) }, None => cb(ptr::null()) } diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index c7ad74dce57..0a88abd67d9 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -321,3 +321,8 @@ pub fn get_reachable_extern_fns(cstore: &cstore::CStore, cnum: ast::CrateNum) let cdata = cstore.get_crate_data(cnum); decoder::get_reachable_extern_fns(&*cdata) } + +pub fn is_typedef(cstore: &cstore::CStore, did: ast::DefId) -> bool { + let cdata = cstore.get_crate_data(did.krate); + decoder::is_typedef(&*cdata, did.node) +} diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 8a2c3c08d41..56d6766e1b7 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -1339,3 +1339,11 @@ pub fn get_reachable_extern_fns(cdata: Cmd) -> Vec { }); return ret; } + +pub fn is_typedef(cdata: Cmd, id: ast::NodeId) -> bool { + let item_doc = lookup_item(id, cdata.data()); + match item_family(item_doc) { + Type => true, + _ => false, + } +} diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index 9033b83d474..ec46e7f8592 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -13,7 +13,7 @@ use std::cell::RefCell; use std::os; use std::io::fs; -use std::unstable::dynamic_lib::DynamicLibrary; +use std::dynamic_lib::DynamicLibrary; use std::collections::HashSet; use myfs = util::fs; diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs index ba50a15a82b..97ffcf279ae 100644 --- a/src/librustc/plugin/load.rs +++ b/src/librustc/plugin/load.rs @@ -16,7 +16,7 @@ use plugin::registry::Registry; use std::mem; use std::os; -use std::unstable::dynamic_lib::DynamicLibrary; +use std::dynamic_lib::DynamicLibrary; use syntax::ast; use syntax::attr; use syntax::visit; diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 2a4774ffd84..d243c61ddaf 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -203,7 +203,7 @@ fn build_struct(tcx: &ty::ctxt, did: ast::DefId) -> clean::Struct { fn build_type(tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEnum { let t = ty::lookup_item_type(tcx, did); match ty::get(t.ty).sty { - ty::ty_enum(edid, _) => { + ty::ty_enum(edid, _) if !csearch::is_typedef(&tcx.sess.cstore, did) => { return clean::EnumItem(clean::Enum { generics: t.generics.clean(), variants_stripped: false, diff --git a/src/librustdoc/flock.rs b/src/librustdoc/flock.rs index fea6748660b..8ad10a686e6 100644 --- a/src/librustdoc/flock.rs +++ b/src/librustdoc/flock.rs @@ -135,7 +135,6 @@ mod imp { mod imp { use libc; use std::mem; - use std::os::win32::as_utf16_p; use std::os; use std::ptr; @@ -162,8 +161,9 @@ mod imp { impl Lock { pub fn new(p: &Path) -> Lock { - let handle = as_utf16_p(p.as_str().unwrap(), |p| unsafe { - libc::CreateFileW(p, + let p_16 = p.as_str().unwrap().to_utf16().append_one(0); + let handle = unsafe { + libc::CreateFileW(p_16.as_ptr(), libc::FILE_GENERIC_READ | libc::FILE_GENERIC_WRITE, libc::FILE_SHARE_READ | @@ -173,7 +173,7 @@ mod imp { libc::CREATE_ALWAYS, libc::FILE_ATTRIBUTE_NORMAL, ptr::mut_null()) - }); + }; if handle as uint == libc::INVALID_HANDLE_VALUE as uint { fail!("create file error: {}", os::last_os_error()); } diff --git a/src/librustdoc/plugins.rs b/src/librustdoc/plugins.rs index 7a796e97f41..fee1d63a274 100644 --- a/src/librustdoc/plugins.rs +++ b/src/librustdoc/plugins.rs @@ -10,7 +10,7 @@ use clean; -use dl = std::unstable::dynamic_lib; +use dl = std::dynamic_lib; use serialize::json; use std::string::String; diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 34363058297..0d777641274 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -15,7 +15,7 @@ use std::io::{Command, TempDir}; use std::os; use std::str; use std::string::String; -use std::unstable::dynamic_lib::DynamicLibrary; +use std::dynamic_lib::DynamicLibrary; use std::collections::{HashSet, HashMap}; use testing; diff --git a/src/libstd/unstable/dynamic_lib.rs b/src/libstd/dynamic_lib.rs similarity index 98% rename from src/libstd/unstable/dynamic_lib.rs rename to src/libstd/dynamic_lib.rs index c05cdc85cc5..fa6efc8a4b1 100644 --- a/src/libstd/unstable/dynamic_lib.rs +++ b/src/libstd/dynamic_lib.rs @@ -16,6 +16,9 @@ A simple wrapper over the platform's dynamic library facilities */ +#![experimental] +#![allow(missing_doc)] + use clone::Clone; use c_str::ToCStr; use iter::Iterator; @@ -272,21 +275,21 @@ pub mod dl { #[cfg(target_os = "win32")] pub mod dl { + use c_str::ToCStr; use libc; use os; use ptr; use result::{Ok, Err, Result}; - use string::String; + use str::StrAllocating; use str; - use c_str::ToCStr; + use string::String; pub unsafe fn open_external(filename: T) -> *u8 { // Windows expects Unicode data let filename_cstr = filename.to_c_str(); let filename_str = str::from_utf8(filename_cstr.as_bytes_no_nul()).unwrap(); - os::win32::as_utf16_p(filename_str, |raw_name| { - LoadLibraryW(raw_name as *libc::c_void) as *u8 - }) + let filename_str = filename_str.to_utf16().append_one(0); + LoadLibraryW(filename_str.as_ptr() as *libc::c_void) as *u8 } pub unsafe fn open_internal() -> *u8 { diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 6f3eec01e8e..a1e0fa88978 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -81,13 +81,18 @@ Some examples of obvious things you might want to do * Make a simple TCP client connection and request - ```rust,should_fail + ```rust # #![allow(unused_must_use)] use std::io::net::tcp::TcpStream; + # // connection doesn't fail if a server is running on 8080 + # // locally, we still want to be type checking this code, so lets + # // just stop it running (#11576) + # if false { let mut socket = TcpStream::connect("127.0.0.1", 8080).unwrap(); socket.write(bytes!("GET / HTTP/1.0\n\n")); let response = socket.read_to_end(); + # } ``` * Make a simple TCP server diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 85813c02d55..e147997334c 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -241,15 +241,12 @@ pub mod sync; /* Runtime and platform support */ pub mod c_vec; +pub mod dynamic_lib; pub mod os; pub mod io; pub mod path; pub mod fmt; -// Private APIs -#[unstable] -pub mod unstable; - // FIXME #7809: This shouldn't be pub, and it should be reexported under 'unstable' // but name resolution doesn't work without it being pub. #[unstable] @@ -279,3 +276,11 @@ mod std { // The test runner requires std::slice::Vector, so re-export std::slice just for it. #[cfg(test)] pub use slice; } + +#[deprecated] +#[allow(missing_doc)] +#[doc(hiden)] +pub mod unstable { + #[deprecated = "use std::dynamic_lib"] + pub use dynamic_lib; +} diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 90df18106f0..fa882e7d016 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -133,7 +133,7 @@ pub mod win32 { use os::TMPBUF_SZ; use slice::{MutableVector, ImmutableVector}; use string::String; - use str::{StrSlice, StrAllocating}; + use str::StrSlice; use str; use vec::Vec; @@ -171,17 +171,6 @@ pub mod win32 { return res; } } - - pub fn as_utf16_p(s: &str, f: |*u16| -> T) -> T { - as_mut_utf16_p(s, |t| { f(t as *u16) }) - } - - pub fn as_mut_utf16_p(s: &str, f: |*mut u16| -> T) -> T { - let mut t = s.to_utf16(); - // Null terminate before passing on. - t.push(0u16); - f(t.as_mut_ptr()) - } } /* @@ -356,11 +345,10 @@ pub fn getenv_as_bytes(n: &str) -> Option> { pub fn getenv(n: &str) -> Option { unsafe { with_env_lock(|| { - use os::win32::{as_utf16_p, fill_utf16_buf_and_decode}; - as_utf16_p(n, |u| { - fill_utf16_buf_and_decode(|buf, sz| { - libc::GetEnvironmentVariableW(u, buf, sz) - }) + use os::win32::{fill_utf16_buf_and_decode}; + let n = n.to_utf16().append_one(0); + fill_utf16_buf_and_decode(|buf, sz| { + libc::GetEnvironmentVariableW(n.as_ptr(), buf, sz) }) }) } @@ -398,14 +386,11 @@ pub fn setenv(n: &str, v: &str) { /// Sets the environment variable `n` to the value `v` for the currently running /// process pub fn setenv(n: &str, v: &str) { + let n = n.to_utf16().append_one(0); + let v = v.to_utf16().append_one(0); unsafe { with_env_lock(|| { - use os::win32::as_utf16_p; - as_utf16_p(n, |nbuf| { - as_utf16_p(v, |vbuf| { - libc::SetEnvironmentVariableW(nbuf, vbuf); - }) - }) + libc::SetEnvironmentVariableW(n.as_ptr(), v.as_ptr()); }) } } @@ -428,12 +413,10 @@ pub fn unsetenv(n: &str) { } #[cfg(windows)] fn _unsetenv(n: &str) { + let n = n.to_utf16().append_one(0); unsafe { with_env_lock(|| { - use os::win32::as_utf16_p; - as_utf16_p(n, |nbuf| { - libc::SetEnvironmentVariableW(nbuf, ptr::null()); - }) + libc::SetEnvironmentVariableW(n.as_ptr(), ptr::null()); }) } } @@ -732,11 +715,12 @@ pub fn change_dir(p: &Path) -> bool { #[cfg(windows)] fn chdir(p: &Path) -> bool { + let p = match p.as_str() { + Some(s) => s.to_utf16().append_one(0), + None => return false, + }; unsafe { - use os::win32::as_utf16_p; - return as_utf16_p(p.as_str().unwrap(), |buf| { - libc::SetCurrentDirectoryW(buf) != (0 as libc::BOOL) - }); + libc::SetCurrentDirectoryW(p.as_ptr()) != (0 as libc::BOOL) } } diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs index 83fc95267af..423f372f018 100644 --- a/src/libstd/rt/backtrace.rs +++ b/src/libstd/rt/backtrace.rs @@ -614,7 +614,7 @@ mod imp { use rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT}; use slice::ImmutableVector; use str::StrSlice; - use unstable::dynamic_lib::DynamicLibrary; + use dynamic_lib::DynamicLibrary; #[allow(non_snake_case_functions)] extern "system" { diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 9e562a08ff9..7d94e46a88a 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -271,6 +271,12 @@ pub fn test_main_static_x(args: &[~str], tests: &[TestDescAndFn]) { tests) } +pub enum ColorConfig { + AutoColor, + AlwaysColor, + NeverColor, +} + pub struct TestOpts { pub filter: Option, pub run_ignored: bool, @@ -282,6 +288,7 @@ pub struct TestOpts { pub test_shard: Option<(uint,uint)>, pub logfile: Option, pub nocapture: bool, + pub color: ColorConfig, } impl TestOpts { @@ -298,6 +305,7 @@ impl TestOpts { test_shard: None, logfile: None, nocapture: false, + color: AutoColor, } } } @@ -324,7 +332,11 @@ fn optgroups() -> Vec { getopts::optopt("", "test-shard", "run shard A, of B shards, worth of the testsuite", "A.B"), getopts::optflag("", "nocapture", "don't capture stdout/stderr of each \ - task, allow printing directly")) + task, allow printing directly"), + getopts::optopt("", "color", "Configure coloring of output: + auto = colorize if stdout is a tty and tests are run on serially (default); + always = always colorize output; + never = never colorize output;", "auto|always|never")) } fn usage(binary: &str) { @@ -406,6 +418,16 @@ pub fn parse_opts(args: &[String]) -> Option { nocapture = os::getenv("RUST_TEST_NOCAPTURE").is_some(); } + let color = match matches.opt_str("color").as_ref().map(|s| s.as_slice()) { + Some("auto") | None => AutoColor, + Some("always") => AlwaysColor, + Some("never") => NeverColor, + + Some(v) => return Some(Err(format!("argument for --color must be \ + auto, always, or never (was {})", + v))), + }; + let test_opts = TestOpts { filter: filter, run_ignored: run_ignored, @@ -417,6 +439,7 @@ pub fn parse_opts(args: &[String]) -> Option { test_shard: test_shard, logfile: logfile, nocapture: nocapture, + color: color, }; Some(Ok(test_opts)) @@ -492,7 +515,7 @@ impl ConsoleTestState { Ok(ConsoleTestState { out: out, log_out: log_out, - use_color: use_color(), + use_color: use_color(opts), total: 0u, passed: 0u, failed: 0u, @@ -867,8 +890,12 @@ fn should_sort_failures_before_printing_them() { assert!(apos < bpos); } -fn use_color() -> bool { - get_concurrency() == 1 && io::stdout().get_ref().isatty() +fn use_color(opts: &TestOpts) -> bool { + match opts.color { + AutoColor => get_concurrency() == 1 && io::stdout().get_ref().isatty(), + AlwaysColor => true, + NeverColor => false, + } } #[deriving(Clone)] diff --git a/src/test/auxiliary/linkage-visibility.rs b/src/test/auxiliary/linkage-visibility.rs index 4ae0b6f14f5..0b4bea49fa2 100644 --- a/src/test/auxiliary/linkage-visibility.rs +++ b/src/test/auxiliary/linkage-visibility.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::unstable::dynamic_lib::DynamicLibrary; +use std::dynamic_lib::DynamicLibrary; #[no_mangle] pub fn foo() { bar(); } diff --git a/src/libstd/unstable/mod.rs b/src/test/compile-fail/issue-13446.rs similarity index 71% rename from src/libstd/unstable/mod.rs rename to src/test/compile-fail/issue-13446.rs index 985ef2e142c..0bb6ded0012 100644 --- a/src/libstd/unstable/mod.rs +++ b/src/test/compile-fail/issue-13446.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// 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. // @@ -8,6 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![doc(hidden)] -pub mod dynamic_lib; +// Used to cause ICE + +static VEC: [u32, ..256] = vec!(); //~ ERROR mismatched types + +fn main() {} + diff --git a/src/test/run-make/extern-fn-reachable/main.rs b/src/test/run-make/extern-fn-reachable/main.rs index e05d43145d7..0f759efb025 100644 --- a/src/test/run-make/extern-fn-reachable/main.rs +++ b/src/test/run-make/extern-fn-reachable/main.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::unstable::dynamic_lib::DynamicLibrary; +use std::dynamic_lib::DynamicLibrary; use std::os; pub fn main() { diff --git a/src/test/run-pass/linkage-visibility.rs b/src/test/run-pass/linkage-visibility.rs index e263767990a..58f66314e44 100644 --- a/src/test/run-pass/linkage-visibility.rs +++ b/src/test/run-pass/linkage-visibility.rs @@ -10,7 +10,7 @@ // aux-build:linkage-visibility.rs // ignore-android: FIXME(#10379) -// ignore-win32: std::unstable::dynamic_lib does not work on win32 well +// ignore-win32: std::dynamic_lib does not work on win32 well extern crate foo = "linkage-visibility";