From efd2a1780b2ee1909e84df0c3b398adb024ee375 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Mon, 16 Feb 2015 16:33:55 -0800 Subject: [PATCH 01/39] Deprecate std::sync::TaskPool Rather than stabilize on the current API, we're going to punt this concern to crates.io, to allow for faster iteration. If you need this functionality, you might look at https://github.com/carllerche/syncbox [breaking-change] --- src/libstd/sync/task_pool.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libstd/sync/task_pool.rs b/src/libstd/sync/task_pool.rs index 684a46fd6ff5f..2bc51e340c034 100644 --- a/src/libstd/sync/task_pool.rs +++ b/src/libstd/sync/task_pool.rs @@ -10,11 +10,11 @@ //! Abstraction of a thread pool for basic parallelism. -#![unstable(feature = "std_misc", - reason = "the semantics of a failing task and whether a thread is \ - re-attached to a thread pool are somewhat unclear, and the \ - utility of this type in `std::sync` is questionable with \ - respect to the jobs of other primitives")] +#![deprecated(since = "1.0.0", + reason = "This kind of API needs some time to bake in \ + crates.io. Consider trying \ + https://github.com/carllerche/syncbox")] +#![unstable(feature = "std_misc")] use core::prelude::*; From 64fe93e49dc0c6a552c5f08507064f2ce12800ca Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 20 Feb 2015 12:00:26 -0800 Subject: [PATCH 02/39] std: Tidy up some `unsafe impl`s for `sync` This commit removes many unnecessary `unsafe impl` blocks as well as pushing the needed implementations to the lowest level possible. I noticed that the bounds for `RwLock` are a little off when reviewing #22574 and wanted to ensure that we had our story straight on these implementations. --- src/libstd/sync/condvar.rs | 6 ----- src/libstd/sync/mutex.rs | 2 -- src/libstd/sync/once.rs | 7 ++--- src/libstd/sync/poison.rs | 6 +++++ src/libstd/sync/rwlock.rs | 3 --- src/libstd/sys/unix/condvar.rs | 6 ++++- src/libstd/sys/unix/mutex.rs | 4 ++- src/libstd/sys/unix/rwlock.rs | 5 ++++ src/libstd/sys/windows/condvar.rs | 5 ++++ src/libstd/sys/windows/mutex.rs | 17 +++++++----- src/libstd/sys/windows/rwlock.rs | 5 ++++ .../run-pass/std-sync-right-kind-impls.rs | 27 +++++++++++++++++++ 12 files changed, 68 insertions(+), 25 deletions(-) create mode 100644 src/test/run-pass/std-sync-right-kind-impls.rs diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index 52561d482c39d..fa45f72b3a1f3 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -61,9 +61,6 @@ use sync::{mutex, MutexGuard, PoisonError}; #[stable(feature = "rust1", since = "1.0.0")] pub struct Condvar { inner: Box } -unsafe impl Send for Condvar {} -unsafe impl Sync for Condvar {} - /// Statically allocated condition variables. /// /// This structure is identical to `Condvar` except that it is suitable for use @@ -83,9 +80,6 @@ pub struct StaticCondvar { mutex: AtomicUsize, } -unsafe impl Send for StaticCondvar {} -unsafe impl Sync for StaticCondvar {} - /// Constant initializer for a statically allocated condition variable. #[unstable(feature = "std_misc", reason = "may be merged with Condvar in the future")] diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index e77c4d2e5ebd4..a4129e315ffa6 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -152,8 +152,6 @@ pub struct StaticMutex { poison: poison::Flag, } -unsafe impl Sync for StaticMutex {} - /// An RAII implementation of a "scoped lock" of a mutex. When this structure is /// dropped (falls out of scope), the lock will be unlocked. /// diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 97f985e21e8ab..d2054a1e819ab 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -13,10 +13,9 @@ //! This primitive is meant to be used to run one-time initialization. An //! example use case would be for initializing an FFI library. +use prelude::v1::*; + use isize; -use marker::Sync; -use mem::drop; -use ops::FnOnce; use sync::atomic::{AtomicIsize, Ordering, ATOMIC_ISIZE_INIT}; use sync::{StaticMutex, MUTEX_INIT}; @@ -43,8 +42,6 @@ pub struct Once { lock_cnt: AtomicIsize, } -unsafe impl Sync for Once {} - /// Initialization value for static `Once` values. #[stable(feature = "rust1", since = "1.0.0")] pub const ONCE_INIT: Once = Once { diff --git a/src/libstd/sync/poison.rs b/src/libstd/sync/poison.rs index 32c8150ba4070..2587ff5238ea7 100644 --- a/src/libstd/sync/poison.rs +++ b/src/libstd/sync/poison.rs @@ -16,6 +16,12 @@ use fmt; use thread; pub struct Flag { failed: UnsafeCell } + +// This flag is only ever accessed with a lock previously held. Note that this +// a totally private structure. +unsafe impl Send for Flag {} +unsafe impl Sync for Flag {} + pub const FLAG_INIT: Flag = Flag { failed: UnsafeCell { value: false } }; impl Flag { diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index cd833b1786710..c32fd88ab2452 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -97,9 +97,6 @@ pub struct StaticRwLock { poison: poison::Flag, } -unsafe impl Send for StaticRwLock {} -unsafe impl Sync for StaticRwLock {} - /// Constant initialization for a statically-initialized rwlock. #[unstable(feature = "std_misc", reason = "may be merged with RwLock in the future")] diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs index 3bc4147315263..90dfebc4c454c 100644 --- a/src/libstd/sys/unix/condvar.rs +++ b/src/libstd/sys/unix/condvar.rs @@ -8,10 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use prelude::v1::*; + use cell::UnsafeCell; use libc; use ptr; -use std::option::Option::{Some, None}; use sys::mutex::{self, Mutex}; use sys::time; use sys::sync as ffi; @@ -20,6 +21,9 @@ use num::{Int, NumCast}; pub struct Condvar { inner: UnsafeCell } +unsafe impl Send for Condvar {} +unsafe impl Sync for Condvar {} + pub const CONDVAR_INIT: Condvar = Condvar { inner: UnsafeCell { value: ffi::PTHREAD_COND_INITIALIZER }, }; diff --git a/src/libstd/sys/unix/mutex.rs b/src/libstd/sys/unix/mutex.rs index 9e1527aef201a..f87c0339533df 100644 --- a/src/libstd/sys/unix/mutex.rs +++ b/src/libstd/sys/unix/mutex.rs @@ -8,8 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use prelude::v1::*; + use cell::UnsafeCell; -use marker::Sync; use sys::sync as ffi; use sys_common::mutex; @@ -24,6 +25,7 @@ pub const MUTEX_INIT: Mutex = Mutex { inner: UnsafeCell { value: ffi::PTHREAD_MUTEX_INITIALIZER }, }; +unsafe impl Send for Mutex {} unsafe impl Sync for Mutex {} impl Mutex { diff --git a/src/libstd/sys/unix/rwlock.rs b/src/libstd/sys/unix/rwlock.rs index 54523e0076dc3..b857f4ab75fed 100644 --- a/src/libstd/sys/unix/rwlock.rs +++ b/src/libstd/sys/unix/rwlock.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use prelude::v1::*; + use cell::UnsafeCell; use sys::sync as ffi; @@ -17,6 +19,9 @@ pub const RWLOCK_INIT: RWLock = RWLock { inner: UnsafeCell { value: ffi::PTHREAD_RWLOCK_INITIALIZER }, }; +unsafe impl Send for RWLock {} +unsafe impl Sync for RWLock {} + impl RWLock { #[inline] pub unsafe fn new() -> RWLock { diff --git a/src/libstd/sys/windows/condvar.rs b/src/libstd/sys/windows/condvar.rs index db8038006fd6a..071637e3a939f 100644 --- a/src/libstd/sys/windows/condvar.rs +++ b/src/libstd/sys/windows/condvar.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use prelude::v1::*; + use cell::UnsafeCell; use libc::{self, DWORD}; use os; @@ -17,6 +19,9 @@ use time::Duration; pub struct Condvar { inner: UnsafeCell } +unsafe impl Send for Condvar {} +unsafe impl Sync for Condvar {} + pub const CONDVAR_INIT: Condvar = Condvar { inner: UnsafeCell { value: ffi::CONDITION_VARIABLE_INIT } }; diff --git a/src/libstd/sys/windows/mutex.rs b/src/libstd/sys/windows/mutex.rs index 75495efc7cbb6..0847f3b52bfab 100644 --- a/src/libstd/sys/windows/mutex.rs +++ b/src/libstd/sys/windows/mutex.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use marker::Sync; +use prelude::v1::*; + use cell::UnsafeCell; use sys::sync as ffi; @@ -18,6 +19,7 @@ pub const MUTEX_INIT: Mutex = Mutex { inner: UnsafeCell { value: ffi::SRWLOCK_INIT } }; +unsafe impl Send for Mutex {} unsafe impl Sync for Mutex {} #[inline] @@ -27,14 +29,15 @@ pub unsafe fn raw(m: &Mutex) -> ffi::PSRWLOCK { // So you might be asking why we're using SRWLock instead of CriticalSection? // -// 1. SRWLock is several times faster than CriticalSection according to benchmarks performed on both -// Windows 8 and Windows 7. +// 1. SRWLock is several times faster than CriticalSection according to +// benchmarks performed on both Windows 8 and Windows 7. // -// 2. CriticalSection allows recursive locking while SRWLock deadlocks. The Unix implementation -// deadlocks so consistency is preferred. See #19962 for more details. +// 2. CriticalSection allows recursive locking while SRWLock deadlocks. The Unix +// implementation deadlocks so consistency is preferred. See #19962 for more +// details. // -// 3. While CriticalSection is fair and SRWLock is not, the current Rust policy is there there are -// no guarantees of fairness. +// 3. While CriticalSection is fair and SRWLock is not, the current Rust policy +// is there there are no guarantees of fairness. impl Mutex { #[inline] diff --git a/src/libstd/sys/windows/rwlock.rs b/src/libstd/sys/windows/rwlock.rs index 76fe352ed7717..009605535a023 100644 --- a/src/libstd/sys/windows/rwlock.rs +++ b/src/libstd/sys/windows/rwlock.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use prelude::v1::*; + use cell::UnsafeCell; use sys::sync as ffi; @@ -17,6 +19,9 @@ pub const RWLOCK_INIT: RWLock = RWLock { inner: UnsafeCell { value: ffi::SRWLOCK_INIT } }; +unsafe impl Send for RWLock {} +unsafe impl Sync for RWLock {} + impl RWLock { #[inline] pub unsafe fn read(&self) { diff --git a/src/test/run-pass/std-sync-right-kind-impls.rs b/src/test/run-pass/std-sync-right-kind-impls.rs new file mode 100644 index 0000000000000..d2d72ed16618d --- /dev/null +++ b/src/test/run-pass/std-sync-right-kind-impls.rs @@ -0,0 +1,27 @@ +// Copyright 2015 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. + +use std::sync; + +fn assert_both() {} + +fn main() { + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::>(); + assert_both::(); + assert_both::>(); + assert_both::(); + assert_both::(); + assert_both::>(); + assert_both::>(); + assert_both::(); +} From d443f98f22a886a1c93908e842d999e28b07ec9f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 23 Feb 2015 17:21:54 -0500 Subject: [PATCH 03/39] Apply borrowck to fns that appear in const declarations. Fixes #22382. --- src/librustc_borrowck/borrowck/mod.rs | 6 ++-- .../compile-fail/borrowck-fn-in-const-a.rs | 22 +++++++++++++ .../compile-fail/borrowck-fn-in-const-b.rs | 24 ++++++++++++++ .../compile-fail/borrowck-fn-in-const-c.rs | 33 +++++++++++++++++++ 4 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 src/test/compile-fail/borrowck-fn-in-const-a.rs create mode 100644 src/test/compile-fail/borrowck-fn-in-const-b.rs create mode 100644 src/test/compile-fail/borrowck-fn-in-const-c.rs diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index dfd98881ace86..ff92ee5b64e26 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -105,10 +105,10 @@ fn borrowck_item(this: &mut BorrowckCtxt, item: &ast::Item) { ast::ItemConst(_, ref ex) => { gather_loans::gather_loans_in_static_initializer(this, &**ex); } - _ => { - visit::walk_item(this, item); - } + _ => { } } + + visit::walk_item(this, item); } /// Collection of conclusions determined via borrow checker analyses. diff --git a/src/test/compile-fail/borrowck-fn-in-const-a.rs b/src/test/compile-fail/borrowck-fn-in-const-a.rs new file mode 100644 index 0000000000000..3098807f272f3 --- /dev/null +++ b/src/test/compile-fail/borrowck-fn-in-const-a.rs @@ -0,0 +1,22 @@ +// 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. + +// Check that we check fns appearing in constant declarations. +// Issue #22382. + +const MOVE: fn(&String) -> String = { + fn broken(x: &String) -> String { + return *x //~ ERROR cannot move + } + broken +}; + +fn main() { +} diff --git a/src/test/compile-fail/borrowck-fn-in-const-b.rs b/src/test/compile-fail/borrowck-fn-in-const-b.rs new file mode 100644 index 0000000000000..7e29b2ee0fd4e --- /dev/null +++ b/src/test/compile-fail/borrowck-fn-in-const-b.rs @@ -0,0 +1,24 @@ +// 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. + +// Check that we check fns appearing in constant declarations. +// Issue #22382. + +// How about mutating an immutable vector? +const MUTATE: fn(&Vec) = { + fn broken(x: &Vec) { + x.push(format!("this is broken")); + //~^ ERROR cannot borrow + } + broken +}; + +fn main() { +} diff --git a/src/test/compile-fail/borrowck-fn-in-const-c.rs b/src/test/compile-fail/borrowck-fn-in-const-c.rs new file mode 100644 index 0000000000000..e607397e920e2 --- /dev/null +++ b/src/test/compile-fail/borrowck-fn-in-const-c.rs @@ -0,0 +1,33 @@ +// 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. + +// Check that we check fns appearing in constant declarations. +// Issue #22382. + +// Returning local references? +struct DropString { + inner: String +} +impl Drop for DropString { + fn drop(&mut self) { + self.inner.clear(); + self.inner.push_str("dropped"); + } +} +const LOCAL_REF: fn() -> &'static str = { + fn broken() -> &'static str { + let local = DropString { inner: format!("Some local string") }; + return &local.inner; //~ ERROR does not live long enough + } + broken +}; + +fn main() { +} From d0c589d5ced5006f72d766af2ccecf699ff76176 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Mon, 23 Feb 2015 23:50:32 +0100 Subject: [PATCH 04/39] Hide unnecessary error checking from the user This affects the `set_non_blocking` function which cannot fail for Unix or Windows, given correct parameters. Additionally, the short UDP write error case has been removed as there is no such thing as "short UDP writes", instead, the operating system will error out if the application tries to send a packet larger than the MTU of the network path. --- src/libstd/sys/common/net.rs | 21 ++++++++------------- src/libstd/sys/unix/mod.rs | 4 ++-- src/libstd/sys/unix/pipe.rs | 6 +++--- src/libstd/sys/unix/process.rs | 6 +++--- src/libstd/sys/unix/tcp.rs | 6 +++--- src/libstd/sys/windows/mod.rs | 6 +++--- src/libstd/sys/windows/net.rs | 13 ++++++++++++- src/libstd/sys/windows/tcp.rs | 2 +- 8 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index b5cd42219e128..228362e3d62ae 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -503,7 +503,7 @@ pub fn connect_timeout(fd: sock_t, #[cfg(windows)] use libc::WSAEWOULDBLOCK as WOULDBLOCK; // Make sure the call to connect() doesn't block - try!(set_nonblocking(fd, true)); + set_nonblocking(fd, true); let ret = match unsafe { libc::connect(fd, addrp, len) } { // If the connection is in progress, then we need to wait for it to @@ -533,7 +533,7 @@ pub fn connect_timeout(fd: sock_t, }; // be sure to turn blocking I/O back on - try!(set_nonblocking(fd, false)); + set_nonblocking(fd, false); return ret; #[cfg(unix)] @@ -626,7 +626,7 @@ pub struct Guard<'a> { #[unsafe_destructor] impl<'a> Drop for Guard<'a> { fn drop(&mut self) { - assert!(set_nonblocking(self.fd, false).is_ok()); + set_nonblocking(self.fd, false); } } @@ -723,7 +723,7 @@ impl TcpStream { fd: self.fd(), guard: self.inner.lock.lock().unwrap(), }; - assert!(set_nonblocking(self.fd(), true).is_ok()); + set_nonblocking(self.fd(), true); ret } @@ -862,7 +862,7 @@ impl UdpSocket { fd: self.fd(), guard: self.inner.lock.lock().unwrap(), }; - assert!(set_nonblocking(self.fd(), true).is_ok()); + set_nonblocking(self.fd(), true); ret } @@ -887,9 +887,7 @@ impl UdpSocket { storagep, &mut addrlen) as libc::c_int })); - sockaddr_to_addr(&storage, addrlen as uint).and_then(|addr| { - Ok((n as uint, addr)) - }) + Ok((n as uint, sockaddr_to_addr(&storage, addrlen as uint).unwrap())) } pub fn send_to(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()> { @@ -910,11 +908,8 @@ impl UdpSocket { }; let n = try!(write(fd, self.write_deadline, buf, false, dolock, dowrite)); - if n != buf.len() { - Err(short_write(n, "couldn't send entire packet at once")) - } else { - Ok(()) - } + assert!(n == buf.len(), "UDP packet not completely written."); + Ok(()) } pub fn join_multicast(&mut self, multi: IpAddr) -> IoResult<()> { diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index b79ad7031fa48..632270bc5ccbf 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -214,9 +214,9 @@ pub fn wouldblock() -> bool { err == libc::EWOULDBLOCK as i32 || err == libc::EAGAIN as i32 } -pub fn set_nonblocking(fd: sock_t, nb: bool) -> IoResult<()> { +pub fn set_nonblocking(fd: sock_t, nb: bool) { let set = nb as libc::c_int; - mkerr_libc(retry(|| unsafe { c::ioctl(fd, c::FIONBIO, &set) })) + mkerr_libc(retry(|| unsafe { c::ioctl(fd, c::FIONBIO, &set) })).unwrap(); } // nothing needed on unix platforms diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index 3c9cdc65975f6..1446600a77ed7 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -235,9 +235,9 @@ impl UnixListener { _ => { let (reader, writer) = try!(unsafe { sys::os::pipe() }); - try!(set_nonblocking(reader.fd(), true)); - try!(set_nonblocking(writer.fd(), true)); - try!(set_nonblocking(self.fd(), true)); + set_nonblocking(reader.fd(), true); + set_nonblocking(writer.fd(), true); + set_nonblocking(self.fd(), true); Ok(UnixAcceptor { inner: Arc::new(AcceptorInner { listener: self, diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs index 2be841989e6b3..dc067e7e0c5ba 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -345,8 +345,8 @@ impl Process { unsafe { let mut pipes = [0; 2]; assert_eq!(libc::pipe(pipes.as_mut_ptr()), 0); - set_nonblocking(pipes[0], true).ok().unwrap(); - set_nonblocking(pipes[1], true).ok().unwrap(); + set_nonblocking(pipes[0], true); + set_nonblocking(pipes[1], true); WRITE_FD = pipes[1]; let mut old: c::sigaction = mem::zeroed(); @@ -362,7 +362,7 @@ impl Process { fn waitpid_helper(input: libc::c_int, messages: Receiver, (read_fd, old): (libc::c_int, c::sigaction)) { - set_nonblocking(input, true).ok().unwrap(); + set_nonblocking(input, true); let mut set: c::fd_set = unsafe { mem::zeroed() }; let mut tv: libc::timeval; let mut active = Vec::<(libc::pid_t, Sender, u64)>::new(); diff --git a/src/libstd/sys/unix/tcp.rs b/src/libstd/sys/unix/tcp.rs index c8f9d318482b0..b08f6ef9b9032 100644 --- a/src/libstd/sys/unix/tcp.rs +++ b/src/libstd/sys/unix/tcp.rs @@ -67,9 +67,9 @@ impl TcpListener { -1 => Err(last_net_error()), _ => { let (reader, writer) = try!(unsafe { sys::os::pipe() }); - try!(set_nonblocking(reader.fd(), true)); - try!(set_nonblocking(writer.fd(), true)); - try!(set_nonblocking(self.fd(), true)); + set_nonblocking(reader.fd(), true); + set_nonblocking(writer.fd(), true); + set_nonblocking(self.fd(), true); Ok(TcpAcceptor { inner: Arc::new(AcceptorInner { listener: self, diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index a756fb29f81ae..a13c03c7448cb 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -192,13 +192,13 @@ pub fn wouldblock() -> bool { err == libc::WSAEWOULDBLOCK as i32 } -pub fn set_nonblocking(fd: sock_t, nb: bool) -> IoResult<()> { +pub fn set_nonblocking(fd: sock_t, nb: bool) { let mut set = nb as libc::c_ulong; - if unsafe { c::ioctlsocket(fd, c::FIONBIO, &mut set) != 0 } { + (if unsafe { c::ioctlsocket(fd, c::FIONBIO, &mut set) } != 0 { Err(last_error()) } else { Ok(()) - } + }).unwrap(); } pub fn init_net() { diff --git a/src/libstd/sys/windows/net.rs b/src/libstd/sys/windows/net.rs index 3451232f40ab8..6caa4df5dfe62 100644 --- a/src/libstd/sys/windows/net.rs +++ b/src/libstd/sys/windows/net.rs @@ -25,6 +25,8 @@ pub type wrlen_t = i32; pub struct Socket(libc::SOCKET); +/// Checks whether the Windows socket interface has been started already, and +/// if not, starts it. pub fn init() { static START: Once = ONCE_INIT; @@ -38,10 +40,16 @@ pub fn init() { }); } +/// Returns the last error from the Windows socket interface. fn last_error() -> io::Error { io::Error::from_os_error(unsafe { c::WSAGetLastError() }) } +/// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1) +/// and if so, returns the last error from the Windows socket interface. . This +/// function must be called before another call to the socket API is made. +/// +/// FIXME: generics needed? pub fn cvt(t: T) -> io::Result { let one: T = Int::one(); if t == -one { @@ -51,11 +59,14 @@ pub fn cvt(t: T) -> io::Result { } } +/// Provides the functionality of `cvt` for the return values of `getaddrinfo` +/// and similar, meaning that they return an error if the return value is 0. pub fn cvt_gai(err: c_int) -> io::Result<()> { if err == 0 { return Ok(()) } cvt(err).map(|_| ()) } +/// Provides the functionality of `cvt` for a closure. pub fn cvt_r(mut f: F) -> io::Result where F: FnMut() -> T { cvt(f()) } @@ -112,7 +123,7 @@ impl Socket { impl Drop for Socket { fn drop(&mut self) { - unsafe { let _ = libc::closesocket(self.0); } + unsafe { cvt(libc::closesocket(self.0)).unwrap(); } } } diff --git a/src/libstd/sys/windows/tcp.rs b/src/libstd/sys/windows/tcp.rs index 4804ca510cb0b..25b70918591d0 100644 --- a/src/libstd/sys/windows/tcp.rs +++ b/src/libstd/sys/windows/tcp.rs @@ -192,7 +192,7 @@ impl TcpAcceptor { c::WSAEventSelect(socket, events[1], 0) }; if ret != 0 { return Err(last_net_error()) } - try!(set_nonblocking(socket, false)); + set_nonblocking(socket, false); return Ok(stream) } } From 79bf783ebf41c756641e90f4295fbf98cd8a11ba Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 23 Feb 2015 15:07:10 -0800 Subject: [PATCH 05/39] std: Handle a trailing slash in create_dir_all If the filename for a path is `None` then we know that the creation of the parent directory created the whole path so there's no need to retry the call to `create_dir`. Closes #22737 --- src/libstd/fs.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 98c1b50a9bf14..1f41d715c4e35 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -540,7 +540,14 @@ pub fn create_dir_all(path: &P) -> io::Result<()> { Some(p) if p != path => try!(create_dir_all(p)), _ => {} } - create_dir(path) + // If the file name of the given `path` is blank then the creation of the + // parent directory will have taken care of the whole path for us, so we're + // good to go. + if path.file_name().is_none() { + Ok(()) + } else { + create_dir(path) + } } /// Remove an existing, empty directory @@ -1500,4 +1507,11 @@ mod tests { check!(fs::set_permissions(&path, perm)); check!(fs::remove_file(&path)); } + + #[test] + fn mkdir_trailing_slash() { + let tmpdir = tmpdir(); + let path = tmpdir.join("file"); + check!(fs::create_dir_all(&path.join("a/"))); + } } From 537d6946e4570a9425aa5c881454e67bedf210b0 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 23 Feb 2015 15:26:18 -0800 Subject: [PATCH 06/39] std: Expose a `mode` accessor for Permissions on unix Currently we have a `set_mode` mutator, so this just adds the pairing of a `mode` accessor to read the value. Closes #22738 --- src/libstd/fs.rs | 4 ++++ src/libstd/sys/unix/ext.rs | 3 +++ src/libstd/sys/unix/fs2.rs | 1 + 3 files changed, 8 insertions(+) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 98c1b50a9bf14..c6ceced4598db 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -325,6 +325,10 @@ impl FromInner for Permissions { } } +impl AsInner for Permissions { + fn as_inner(&self) -> &fs_imp::FilePermissions { &self.0 } +} + impl Iterator for ReadDir { type Item = io::Result; diff --git a/src/libstd/sys/unix/ext.rs b/src/libstd/sys/unix/ext.rs index b8b9dcfb3c689..3f9da6e3c51bb 100644 --- a/src/libstd/sys/unix/ext.rs +++ b/src/libstd/sys/unix/ext.rs @@ -173,10 +173,13 @@ impl OsStrExt for OsStr { // Unix-specific extensions to `Permissions` pub trait PermissionsExt { + fn mode(&self) -> i32; fn set_mode(&mut self, mode: i32); } impl PermissionsExt for Permissions { + fn mode(&self) -> i32 { self.as_inner().mode() } + fn set_mode(&mut self, mode: i32) { *self = FromInner::from_inner(FromInner::from_inner(mode)); } diff --git a/src/libstd/sys/unix/fs2.rs b/src/libstd/sys/unix/fs2.rs index 92a47c6c3850d..d77e76241cca2 100644 --- a/src/libstd/sys/unix/fs2.rs +++ b/src/libstd/sys/unix/fs2.rs @@ -86,6 +86,7 @@ impl FilePermissions { self.mode |= 0o222; } } + pub fn mode(&self) -> i32 { self.mode as i32 } } impl FromInner for FilePermissions { From 948a17ed1d61de822a7d06527ca88b1ff709f945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Krasnoborski?= Date: Tue, 24 Feb 2015 02:40:32 +0100 Subject: [PATCH 07/39] Stop parsing "-" as integer, fixes #22745 --- src/libcore/num/mod.rs | 1 + src/libcoretest/num/mod.rs | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 7612469c8088b..b1039f79f23de 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1672,6 +1672,7 @@ macro_rules! from_str_radix_int_impl { let is_signed_ty = (0 as $T) > Int::min_value(); match src.slice_shift_char() { + Some(('-', "")) => Err(PIE { kind: Empty }), Some(('-', src)) if is_signed_ty => { // The number is negative let mut result = 0; diff --git a/src/libcoretest/num/mod.rs b/src/libcoretest/num/mod.rs index 2c6efc0040fae..1199fd0106850 100644 --- a/src/libcoretest/num/mod.rs +++ b/src/libcoretest/num/mod.rs @@ -122,4 +122,9 @@ mod test { assert_eq!("-9223372036854775808".parse::().ok(), Some(i64_val)); assert_eq!("-9223372036854775809".parse::().ok(), None); } + + #[test] + test_int_from_minus_sign() { + assert_eq!("-".parse::().ok(), None); + } } From fcf70230eb4d0ce6840c6455eb8af95a9650f8b2 Mon Sep 17 00:00:00 2001 From: Ivan Petkov Date: Mon, 23 Feb 2015 22:27:27 -0800 Subject: [PATCH 08/39] Properly reimplement `unsafe-code` lint to honor changing lint attributes --- src/librustc/lint/builtin.rs | 54 +++++++++-------------- src/test/compile-fail/lint-unsafe-code.rs | 49 ++++++++++++++++++++ 2 files changed, 71 insertions(+), 32 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 3c06bae177cef..36c812f440fda 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -1292,46 +1292,36 @@ impl LintPass for UnsafeCode { } fn check_item(&mut self, cx: &Context, it: &ast::Item) { - use syntax::ast::Unsafety::Unsafe; - - fn check_method(cx: &Context, meth: &P) { - if let ast::Method_::MethDecl(_, _, _, _, Unsafe, _, _, _) = meth.node { - cx.span_lint(UNSAFE_CODE, meth.span, "implementation of an `unsafe` method"); - } - } - match it.node { - ast::ItemFn(_, Unsafe, _, _, _) => - cx.span_lint(UNSAFE_CODE, it.span, "declaration of an `unsafe` function"), + ast::ItemTrait(ast::Unsafety::Unsafe, _, _, _) => + cx.span_lint(UNSAFE_CODE, it.span, "declaration of an `unsafe` trait"), - ast::ItemTrait(trait_safety, _, _, ref items) => { - if trait_safety == Unsafe { - cx.span_lint(UNSAFE_CODE, it.span, "declaration of an `unsafe` trait"); - } + ast::ItemImpl(ast::Unsafety::Unsafe, _, _, _, _, _) => + cx.span_lint(UNSAFE_CODE, it.span, "implementation of an `unsafe` trait"), - for it in items { - match *it { - ast::RequiredMethod(ast::TypeMethod { unsafety: Unsafe, span, ..}) => - cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` method"), - ast::ProvidedMethod(ref meth) => check_method(cx, meth), - _ => (), - } - } - }, + _ => return, + } + } - ast::ItemImpl(impl_safety, _, _, _, _, ref impls) => { - if impl_safety == Unsafe { - cx.span_lint(UNSAFE_CODE, it.span, "implementation of an `unsafe` trait"); - } + fn check_fn(&mut self, cx: &Context, fk: visit::FnKind, _: &ast::FnDecl, + _: &ast::Block, span: Span, _: ast::NodeId) { + match fk { + visit::FkItemFn(_, _, ast::Unsafety::Unsafe, _) => + cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"), - for item in impls { - if let ast::ImplItem::MethodImplItem(ref meth) = *item { - check_method(cx, meth); - } + visit::FkMethod(_, _, m) => { + if let ast::Method_::MethDecl(_, _, _, _, ast::Unsafety::Unsafe, _, _, _) = m.node { + cx.span_lint(UNSAFE_CODE, m.span, "implementation of an `unsafe` method") } }, - _ => return, + _ => (), + } + } + + fn check_ty_method(&mut self, cx: &Context, ty_method: &ast::TypeMethod) { + if let ast::TypeMethod { unsafety: ast::Unsafety::Unsafe, span, ..} = *ty_method { + cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` method") } } } diff --git a/src/test/compile-fail/lint-unsafe-code.rs b/src/test/compile-fail/lint-unsafe-code.rs index 7b17d8877572f..8440cf3a88e10 100644 --- a/src/test/compile-fail/lint-unsafe-code.rs +++ b/src/test/compile-fail/lint-unsafe-code.rs @@ -15,6 +15,8 @@ use std::marker::PhantomFn; struct Bar; +struct Bar2; +struct Bar3; #[allow(unsafe_code)] mod allowed_unsafe { @@ -46,6 +48,53 @@ impl Baz for Bar { unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method } + +#[allow(unsafe_code)] +trait A { + unsafe fn allowed_unsafe(&self); + unsafe fn allowed_unsafe_provided(&self) {} +} + +#[allow(unsafe_code)] +impl Baz for Bar2 { + unsafe fn baz(&self) {} + unsafe fn provided_override(&self) {} +} + +impl Baz for Bar3 { + #[allow(unsafe_code)] + unsafe fn baz(&self) {} + unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method +} + +#[allow(unsafe_code)] +unsafe trait B { + fn dummy(&self) {} +} + +trait C { + #[allow(unsafe_code)] + unsafe fn baz(&self); + unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method +} + +impl C for Bar { + #[allow(unsafe_code)] + unsafe fn baz(&self) {} + unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method +} + +impl C for Bar2 { + unsafe fn baz(&self) {} //~ ERROR: implementation of an `unsafe` method +} + +trait D { + #[allow(unsafe_code)] + unsafe fn unsafe_provided(&self) {} +} + +impl D for Bar {} + fn main() { unsafe {} //~ ERROR: usage of an `unsafe` block From 23f5a8f82de85a82a8551b51c2526e34d229ba10 Mon Sep 17 00:00:00 2001 From: Mikhail Zabaluev Date: Tue, 24 Feb 2015 09:13:08 +0200 Subject: [PATCH 09/39] std::io::BufReader: remove leftover lifetime parameter on get_ref() --- src/libstd/io/buffered.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 9ef319782369d..9317f647d4fa6 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -48,7 +48,7 @@ impl BufReader { } /// Gets a reference to the underlying reader. - pub fn get_ref<'a>(&self) -> &R { &self.inner } + pub fn get_ref(&self) -> &R { &self.inner } /// Gets a mutable reference to the underlying reader. /// From a9f6f4b73e838e83538d4544141d8354b4633aed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Krasnoborski?= Date: Tue, 24 Feb 2015 08:24:42 +0100 Subject: [PATCH 10/39] Add missing `fn` --- src/libcoretest/num/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcoretest/num/mod.rs b/src/libcoretest/num/mod.rs index 1199fd0106850..03f6e51a3498a 100644 --- a/src/libcoretest/num/mod.rs +++ b/src/libcoretest/num/mod.rs @@ -124,7 +124,7 @@ mod test { } #[test] - test_int_from_minus_sign() { + fn test_int_from_minus_sign() { assert_eq!("-".parse::().ok(), None); } } From 0afebe63dd0b8e01cac824e86de7df6d6fd29bbd Mon Sep 17 00:00:00 2001 From: Eunji Jeong Date: Tue, 24 Feb 2015 18:15:03 +0900 Subject: [PATCH 11/39] Replace deprecated getdtablesize() with sysconf(_SC_OPEN_MAX) for android aarch64 --- src/libstd/sys/unix/process.rs | 10 +++++++++- src/libstd/sys/unix/process2.rs | 11 ++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs index 2be841989e6b3..02e6d7dadb115 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -69,7 +69,6 @@ impl Process { K: BytesContainer + Eq + Hash, V: BytesContainer { use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp}; - use libc::funcs::bsd44::getdtablesize; mod rustrt { extern { @@ -82,6 +81,15 @@ impl Process { assert_eq!(ret, 0); } + #[cfg(all(target_os = "android", target_arch = "aarch64"))] + unsafe fn getdtablesize() -> c_int { + libc::sysconf(libc::consts::os::sysconf::_SC_OPEN_MAX) as c_int + } + #[cfg(not(all(target_os = "android", target_arch = "aarch64")))] + unsafe fn getdtablesize() -> c_int { + libc::funcs::bsd44::getdtablesize() + } + let dirp = cfg.cwd().map(|c| c.as_ptr()).unwrap_or(ptr::null()); // temporary until unboxed closures land diff --git a/src/libstd/sys/unix/process2.rs b/src/libstd/sys/unix/process2.rs index 06fa5c4bba725..b7a1b002f5598 100644 --- a/src/libstd/sys/unix/process2.rs +++ b/src/libstd/sys/unix/process2.rs @@ -141,7 +141,6 @@ impl Process { -> io::Result { use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp}; - use libc::funcs::bsd44::getdtablesize; mod rustrt { extern { @@ -154,6 +153,16 @@ impl Process { assert_eq!(ret, 0); } + #[cfg(all(target_os = "android", target_arch = "aarch64"))] + unsafe fn getdtablesize() -> c_int { + libc::sysconf(libc::consts::os::sysconf::_SC_OPEN_MAX) as c_int + } + + #[cfg(not(all(target_os = "android", target_arch = "aarch64")))] + unsafe fn getdtablesize() -> c_int { + libc::funcs::bsd44::getdtablesize() + } + let dirp = cfg.cwd.as_ref().map(|c| c.as_ptr()).unwrap_or(ptr::null()); with_envp(cfg.env.as_ref(), |envp: *const c_void| { From 0bea550a2a78eba05533f333cc2a0e7f9b5b44e8 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 24 Feb 2015 09:50:36 +0100 Subject: [PATCH 12/39] style nitpicks --- src/libcollections/btree/map.rs | 8 +- src/librustc/metadata/loader.rs | 12 +- src/librustc/middle/infer/combine.rs | 352 +++++++++--------- .../middle/infer/region_inference/mod.rs | 16 +- src/librustc/middle/traits/select.rs | 160 +++----- src/librustc_trans/trans/consts.rs | 24 +- 6 files changed, 251 insertions(+), 321 deletions(-) diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 1b456eec830b1..64d9d99d88d8d 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -347,7 +347,7 @@ impl BTreeMap { let result = stack.with(move |pusher, node| { // Same basic logic as found in `find`, but with PartialSearchStack mediating the // actual nodes for us - return match Node::search(node, &key) { + match Node::search(node, &key) { Found(mut handle) => { // Perfect match, swap the values and return the old one mem::swap(handle.val_mut(), &mut value); @@ -372,7 +372,7 @@ impl BTreeMap { } }); match result { - Finished(ret) => { return ret; }, + Finished(ret) => return ret, Continue((new_stack, renewed_key, renewed_val)) => { stack = new_stack; key = renewed_key; @@ -439,7 +439,7 @@ impl BTreeMap { let mut stack = stack::PartialSearchStack::new(self); loop { let result = stack.with(move |pusher, node| { - return match Node::search(node, key) { + match Node::search(node, key) { Found(handle) => { // Perfect match. Terminate the stack here, and remove the entry Finished(Some(pusher.seal(handle).remove())) @@ -1560,7 +1560,7 @@ impl BTreeMap { let mut stack = stack::PartialSearchStack::new(self); loop { let result = stack.with(move |pusher, node| { - return match Node::search(node, &key) { + match Node::search(node, &key) { Found(handle) => { // Perfect match Finished(Occupied(OccupiedEntry { diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index fbc3e76cf934b..07082d818769c 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -736,12 +736,10 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result { - return Err((format!("failed to read rlib metadata: '{}'", - filename.display()))) - } - Some(blob) => return Ok(blob) - } + None => Err(format!("failed to read rlib metadata: '{}'", + filename.display())), + Some(blob) => Ok(blob) + }; } unsafe { let buf = CString::new(filename.as_vec()).unwrap(); @@ -791,7 +789,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result : Sized { variadic: a.variadic}); - fn argvecs<'tcx, C: Combine<'tcx>>(combiner: &C, - a_args: &[Ty<'tcx>], - b_args: &[Ty<'tcx>]) - -> cres<'tcx, Vec>> - { + fn argvecs<'tcx, C>(combiner: &C, + a_args: &[Ty<'tcx>], + b_args: &[Ty<'tcx>]) + -> cres<'tcx, Vec>> + where C: Combine<'tcx> { if a_args.len() == b_args.len() { a_args.iter().zip(b_args.iter()) .map(|(a, b)| combiner.args(*a, *b)).collect() @@ -351,51 +351,51 @@ pub trait Combineable<'tcx> : Repr<'tcx> + TypeFoldable<'tcx> { impl<'tcx,T> Combineable<'tcx> for Rc where T : Combineable<'tcx> { - fn combine>(combiner: &C, - a: &Rc, - b: &Rc) - -> cres<'tcx, Rc> - { + fn combine(combiner: &C, + a: &Rc, + b: &Rc) + -> cres<'tcx, Rc> + where C: Combine<'tcx> { Ok(Rc::new(try!(Combineable::combine(combiner, &**a, &**b)))) } } impl<'tcx> Combineable<'tcx> for ty::TraitRef<'tcx> { - fn combine>(combiner: &C, - a: &ty::TraitRef<'tcx>, - b: &ty::TraitRef<'tcx>) - -> cres<'tcx, ty::TraitRef<'tcx>> - { + fn combine(combiner: &C, + a: &ty::TraitRef<'tcx>, + b: &ty::TraitRef<'tcx>) + -> cres<'tcx, ty::TraitRef<'tcx>> + where C: Combine<'tcx> { combiner.trait_refs(a, b) } } impl<'tcx> Combineable<'tcx> for Ty<'tcx> { - fn combine>(combiner: &C, - a: &Ty<'tcx>, - b: &Ty<'tcx>) - -> cres<'tcx, Ty<'tcx>> - { + fn combine(combiner: &C, + a: &Ty<'tcx>, + b: &Ty<'tcx>) + -> cres<'tcx, Ty<'tcx>> + where C: Combine<'tcx> { combiner.tys(*a, *b) } } impl<'tcx> Combineable<'tcx> for ty::ProjectionPredicate<'tcx> { - fn combine>(combiner: &C, - a: &ty::ProjectionPredicate<'tcx>, - b: &ty::ProjectionPredicate<'tcx>) - -> cres<'tcx, ty::ProjectionPredicate<'tcx>> - { + fn combine(combiner: &C, + a: &ty::ProjectionPredicate<'tcx>, + b: &ty::ProjectionPredicate<'tcx>) + -> cres<'tcx, ty::ProjectionPredicate<'tcx>> + where C: Combine<'tcx> { combiner.projection_predicates(a, b) } } impl<'tcx> Combineable<'tcx> for ty::FnSig<'tcx> { - fn combine>(combiner: &C, - a: &ty::FnSig<'tcx>, - b: &ty::FnSig<'tcx>) - -> cres<'tcx, ty::FnSig<'tcx>> - { + fn combine(combiner: &C, + a: &ty::FnSig<'tcx>, + b: &ty::FnSig<'tcx>) + -> cres<'tcx, ty::FnSig<'tcx>> + where C: Combine<'tcx> { combiner.fn_sigs(a, b) } } @@ -407,8 +407,11 @@ pub struct CombineFields<'a, 'tcx: 'a> { pub trace: TypeTrace<'tcx>, } -pub fn expected_found<'tcx, C: Combine<'tcx>, T>( - this: &C, a: T, b: T) -> ty::expected_found { +pub fn expected_found<'tcx, C, T>(this: &C, + a: T, + b: T) + -> ty::expected_found + where C: Combine<'tcx> { if this.a_is_expected() { ty::expected_found {expected: a, found: b} } else { @@ -416,29 +419,26 @@ pub fn expected_found<'tcx, C: Combine<'tcx>, T>( } } -pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, - a: Ty<'tcx>, - b: Ty<'tcx>) - -> cres<'tcx, Ty<'tcx>> -{ +pub fn super_tys<'tcx, C>(this: &C, + a: Ty<'tcx>, + b: Ty<'tcx>) + -> cres<'tcx, Ty<'tcx>> + where C: Combine<'tcx> { let tcx = this.infcx().tcx; let a_sty = &a.sty; let b_sty = &b.sty; debug!("super_tys: a_sty={:?} b_sty={:?}", a_sty, b_sty); return match (a_sty, b_sty) { - // The "subtype" ought to be handling cases involving var: - (&ty::ty_infer(TyVar(_)), _) | - (_, &ty::ty_infer(TyVar(_))) => { - tcx.sess.bug( - &format!("{}: bot and var types should have been handled ({},{})", - this.tag(), - a.repr(this.infcx().tcx), - b.repr(this.infcx().tcx))); - } - - (&ty::ty_err, _) | (_, &ty::ty_err) => { - Ok(tcx.types.err) - } + // The "subtype" ought to be handling cases involving var: + (&ty::ty_infer(TyVar(_)), _) + | (_, &ty::ty_infer(TyVar(_))) => + tcx.sess.bug( + &format!("{}: bot and var types should have been handled ({},{})", + this.tag(), + a.repr(this.infcx().tcx), + b.repr(this.infcx().tcx))), + + (&ty::ty_err, _) | (_, &ty::ty_err) => Ok(tcx.types.err), // Relate integral variables to other types (&ty::ty_infer(IntVar(a_id)), &ty::ty_infer(IntVar(b_id))) => { @@ -475,68 +475,62 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, unify_float_variable(this, !this.a_is_expected(), v_id, v) } - (&ty::ty_char, _) | - (&ty::ty_bool, _) | - (&ty::ty_int(_), _) | - (&ty::ty_uint(_), _) | - (&ty::ty_float(_), _) => { - if a == b { - Ok(a) - } else { - Err(ty::terr_sorts(expected_found(this, a, b))) - } - } - - (&ty::ty_param(ref a_p), &ty::ty_param(ref b_p)) if - a_p.idx == b_p.idx && a_p.space == b_p.space => { - Ok(a) - } - - (&ty::ty_enum(a_id, a_substs), - &ty::ty_enum(b_id, b_substs)) - if a_id == b_id => { - let substs = try!(this.substs(a_id, - a_substs, - b_substs)); - Ok(ty::mk_enum(tcx, a_id, tcx.mk_substs(substs))) - } - - (&ty::ty_trait(ref a_), - &ty::ty_trait(ref b_)) => { - debug!("Trying to match traits {:?} and {:?}", a, b); - let principal = try!(this.binders(&a_.principal, &b_.principal)); - let bounds = try!(this.existential_bounds(&a_.bounds, &b_.bounds)); - Ok(ty::mk_trait(tcx, principal, bounds)) - } - - (&ty::ty_struct(a_id, a_substs), &ty::ty_struct(b_id, b_substs)) - if a_id == b_id => { + (&ty::ty_char, _) + | (&ty::ty_bool, _) + | (&ty::ty_int(_), _) + | (&ty::ty_uint(_), _) + | (&ty::ty_float(_), _) => { + if a == b { + Ok(a) + } else { + Err(ty::terr_sorts(expected_found(this, a, b))) + } + } + + (&ty::ty_param(ref a_p), &ty::ty_param(ref b_p)) if + a_p.idx == b_p.idx && a_p.space == b_p.space => Ok(a), + + (&ty::ty_enum(a_id, a_substs), &ty::ty_enum(b_id, b_substs)) + if a_id == b_id => { + let substs = try!(this.substs(a_id, a_substs, b_substs)); + Ok(ty::mk_enum(tcx, a_id, tcx.mk_substs(substs))) + } + + (&ty::ty_trait(ref a_), &ty::ty_trait(ref b_)) => { + debug!("Trying to match traits {:?} and {:?}", a, b); + let principal = try!(this.binders(&a_.principal, &b_.principal)); + let bounds = try!(this.existential_bounds(&a_.bounds, &b_.bounds)); + Ok(ty::mk_trait(tcx, principal, bounds)) + } + + (&ty::ty_struct(a_id, a_substs), &ty::ty_struct(b_id, b_substs)) + if a_id == b_id => { let substs = try!(this.substs(a_id, a_substs, b_substs)); Ok(ty::mk_struct(tcx, a_id, tcx.mk_substs(substs))) - } - - (&ty::ty_closure(a_id, a_region, a_substs), - &ty::ty_closure(b_id, b_region, b_substs)) - if a_id == b_id => { - // All ty_closure types with the same id represent - // the (anonymous) type of the same closure expression. So - // all of their regions should be equated. - let region = try!(this.equate().regions(*a_region, *b_region)); - let substs = try!(this.substs_variances(None, a_substs, b_substs)); - Ok(ty::mk_closure(tcx, a_id, tcx.mk_region(region), tcx.mk_substs(substs))) - } - - (&ty::ty_uniq(a_inner), &ty::ty_uniq(b_inner)) => { - let typ = try!(this.tys(a_inner, b_inner)); - Ok(ty::mk_uniq(tcx, typ)) - } - - (&ty::ty_ptr(ref a_mt), &ty::ty_ptr(ref b_mt)) => { - let mt = try!(this.mts(a_mt, b_mt)); - Ok(ty::mk_ptr(tcx, mt)) - } - - (&ty::ty_rptr(a_r, ref a_mt), &ty::ty_rptr(b_r, ref b_mt)) => { + } + + (&ty::ty_closure(a_id, a_region, a_substs), + &ty::ty_closure(b_id, b_region, b_substs)) + if a_id == b_id => { + // All ty_closure types with the same id represent + // the (anonymous) type of the same closure expression. So + // all of their regions should be equated. + let region = try!(this.equate().regions(*a_region, *b_region)); + let substs = try!(this.substs_variances(None, a_substs, b_substs)); + Ok(ty::mk_closure(tcx, a_id, tcx.mk_region(region), tcx.mk_substs(substs))) + } + + (&ty::ty_uniq(a_inner), &ty::ty_uniq(b_inner)) => { + let typ = try!(this.tys(a_inner, b_inner)); + Ok(ty::mk_uniq(tcx, typ)) + } + + (&ty::ty_ptr(ref a_mt), &ty::ty_ptr(ref b_mt)) => { + let mt = try!(this.mts(a_mt, b_mt)); + Ok(ty::mk_ptr(tcx, mt)) + } + + (&ty::ty_rptr(a_r, ref a_mt), &ty::ty_rptr(b_r, ref b_mt)) => { let r = try!(this.regions_with_variance(ty::Contravariant, *a_r, *b_r)); // FIXME(14985) If we have mutable references to trait objects, we @@ -551,45 +545,43 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, _ => try!(this.mts(a_mt, b_mt)) }; Ok(ty::mk_rptr(tcx, tcx.mk_region(r), mt)) - } + } - (&ty::ty_vec(a_t, Some(sz_a)), &ty::ty_vec(b_t, Some(sz_b))) => { - this.tys(a_t, b_t).and_then(|t| { - if sz_a == sz_b { - Ok(ty::mk_vec(tcx, t, Some(sz_a))) - } else { - Err(ty::terr_fixed_array_size(expected_found(this, sz_a, sz_b))) - } - }) - } + (&ty::ty_vec(a_t, Some(sz_a)), &ty::ty_vec(b_t, Some(sz_b))) => { + this.tys(a_t, b_t).and_then(|t| { + if sz_a == sz_b { + Ok(ty::mk_vec(tcx, t, Some(sz_a))) + } else { + Err(ty::terr_fixed_array_size(expected_found(this, sz_a, sz_b))) + } + }) + } - (&ty::ty_vec(a_t, sz_a), &ty::ty_vec(b_t, sz_b)) => { - this.tys(a_t, b_t).and_then(|t| { - if sz_a == sz_b { - Ok(ty::mk_vec(tcx, t, sz_a)) + (&ty::ty_vec(a_t, sz_a), &ty::ty_vec(b_t, sz_b)) => { + this.tys(a_t, b_t).and_then(|t| { + if sz_a == sz_b { + Ok(ty::mk_vec(tcx, t, sz_a)) + } else { + Err(ty::terr_sorts(expected_found(this, a, b))) + } + }) + } + + (&ty::ty_str, &ty::ty_str) => Ok(ty::mk_str(tcx)), + + (&ty::ty_tup(ref as_), &ty::ty_tup(ref bs)) => { + if as_.len() == bs.len() { + as_.iter().zip(bs.iter()) + .map(|(a, b)| this.tys(*a, *b)) + .collect::>() + .map(|ts| ty::mk_tup(tcx, ts)) + } else if as_.len() != 0 && bs.len() != 0 { + Err(ty::terr_tuple_size( + expected_found(this, as_.len(), bs.len()))) } else { Err(ty::terr_sorts(expected_found(this, a, b))) } - }) - } - - (&ty::ty_str, &ty::ty_str) => { - Ok(ty::mk_str(tcx)) - } - - (&ty::ty_tup(ref as_), &ty::ty_tup(ref bs)) => { - if as_.len() == bs.len() { - as_.iter().zip(bs.iter()) - .map(|(a, b)| this.tys(*a, *b)) - .collect::>() - .map(|ts| ty::mk_tup(tcx, ts)) - } else if as_.len() != 0 && bs.len() != 0 { - Err(ty::terr_tuple_size( - expected_found(this, as_.len(), bs.len()))) - } else { - Err(ty::terr_sorts(expected_found(this, a, b))) } - } (&ty::ty_bare_fn(a_opt_def_id, a_fty), &ty::ty_bare_fn(b_opt_def_id, b_fty)) if a_opt_def_id == b_opt_def_id => @@ -598,33 +590,33 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, Ok(ty::mk_bare_fn(tcx, a_opt_def_id, tcx.mk_bare_fn(fty))) } - (&ty::ty_projection(ref a_data), &ty::ty_projection(ref b_data)) => { - let projection_ty = try!(this.projection_tys(a_data, b_data)); - Ok(ty::mk_projection(tcx, projection_ty.trait_ref, projection_ty.item_name)) - } + (&ty::ty_projection(ref a_data), &ty::ty_projection(ref b_data)) => { + let projection_ty = try!(this.projection_tys(a_data, b_data)); + Ok(ty::mk_projection(tcx, projection_ty.trait_ref, projection_ty.item_name)) + } - _ => Err(ty::terr_sorts(expected_found(this, a, b))) + _ => Err(ty::terr_sorts(expected_found(this, a, b))), }; - fn unify_integral_variable<'tcx, C: Combine<'tcx>>( - this: &C, - vid_is_expected: bool, - vid: ty::IntVid, - val: ty::IntVarValue) -> cres<'tcx, Ty<'tcx>> - { + fn unify_integral_variable<'tcx, C>(this: &C, + vid_is_expected: bool, + vid: ty::IntVid, + val: ty::IntVarValue) + -> cres<'tcx, Ty<'tcx>> + where C: Combine<'tcx> { try!(this.infcx().simple_var_t(vid_is_expected, vid, val)); match val { IntType(v) => Ok(ty::mk_mach_int(this.tcx(), v)), - UintType(v) => Ok(ty::mk_mach_uint(this.tcx(), v)) + UintType(v) => Ok(ty::mk_mach_uint(this.tcx(), v)), } } - fn unify_float_variable<'tcx, C: Combine<'tcx>>( - this: &C, - vid_is_expected: bool, - vid: ty::FloatVid, - val: ast::FloatTy) -> cres<'tcx, Ty<'tcx>> - { + fn unify_float_variable<'tcx, C>(this: &C, + vid_is_expected: bool, + vid: ty::FloatVid, + val: ast::FloatTy) + -> cres<'tcx, Ty<'tcx>> + where C: Combine<'tcx> { try!(this.infcx().simple_var_t(vid_is_expected, vid, val)); Ok(ty::mk_mach_float(this.tcx(), val)) } @@ -696,12 +688,8 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> { None => { // ...not yet instantiated: // Generalize type if necessary. let generalized_ty = try!(match dir { - EqTo => { - self.generalize(a_ty, b_vid, false) - } - BiTo | SupertypeOf | SubtypeOf => { - self.generalize(a_ty, b_vid, true) - } + EqTo => self.generalize(a_ty, b_vid, false), + BiTo | SupertypeOf | SubtypeOf => self.generalize(a_ty, b_vid, true), }); debug!("instantiate(a_ty={}, dir={:?}, \ b_vid={}, generalized_ty={})", @@ -723,22 +711,14 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> { // to associate causes/spans with each of the relations in // the stack to get this right. match dir { - BiTo => { - try!(self.bivariate().tys(a_ty, b_ty)); - } + BiTo => try!(self.bivariate().tys(a_ty, b_ty)), - EqTo => { - try!(self.equate().tys(a_ty, b_ty)); - } + EqTo => try!(self.equate().tys(a_ty, b_ty)), - SubtypeOf => { - try!(self.sub().tys(a_ty, b_ty)); - } + SubtypeOf => try!(self.sub().tys(a_ty, b_ty)), - SupertypeOf => { - try!(self.sub().tys_with_variance(ty::Contravariant, a_ty, b_ty)); - } - } + SupertypeOf => try!(self.sub().tys_with_variance(ty::Contravariant, a_ty, b_ty)), + }; } Ok(()) @@ -754,11 +734,13 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> { make_region_vars: bool) -> cres<'tcx, Ty<'tcx>> { - let mut generalize = Generalizer { infcx: self.infcx, - span: self.trace.origin.span(), - for_vid: for_vid, - make_region_vars: make_region_vars, - cycle_detected: false }; + let mut generalize = Generalizer { + infcx: self.infcx, + span: self.trace.origin.span(), + for_vid: for_vid, + make_region_vars: make_region_vars, + cycle_detected: false + }; let u = ty.fold_with(&mut generalize); if generalize.cycle_detected { Err(ty::terr_cyclic_ty) diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs index 7800d99f8ed4c..759d7357df193 100644 --- a/src/librustc/middle/infer/region_inference/mod.rs +++ b/src/librustc/middle/infer/region_inference/mod.rs @@ -1133,18 +1133,12 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { true // changed } - ErrorValue => { - false // no change - } + ErrorValue => false, // no change Value(a_region) => { match a_data.classification { - Expanding => { - check_node(self, a_vid, a_data, a_region, b_region) - } - Contracting => { - adjust_node(self, a_vid, a_data, a_region, b_region) - } + Expanding => check_node(self, a_vid, a_data, a_region, b_region), + Contracting => adjust_node(self, a_vid, a_data, a_region, b_region), } } }; @@ -1154,7 +1148,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { a_data: &mut VarData, a_region: Region, b_region: Region) - -> bool { + -> bool { if !this.is_subregion_of(a_region, b_region) { debug!("Setting {:?} to ErrorValue: {} not subregion of {}", a_vid, @@ -1170,7 +1164,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { a_data: &mut VarData, a_region: Region, b_region: Region) - -> bool { + -> bool { match this.glb_concrete_regions(a_region, b_region) { Ok(glb) => { if glb == a_region { diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 8086ca71e019e..9ec89f55b8f32 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -1409,27 +1409,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let self_ty = self.infcx.shallow_resolve(obligation.predicate.0.self_ty()); return match self_ty.sty { - ty::ty_infer(ty::IntVar(_)) | - ty::ty_infer(ty::FloatVar(_)) | - ty::ty_uint(_) | - ty::ty_int(_) | - ty::ty_bool | - ty::ty_float(_) | - ty::ty_bare_fn(..) | - ty::ty_char => { + ty::ty_infer(ty::IntVar(_)) + | ty::ty_infer(ty::FloatVar(_)) + | ty::ty_uint(_) + | ty::ty_int(_) + | ty::ty_bool + | ty::ty_float(_) + | ty::ty_bare_fn(..) + | ty::ty_char => { // safe for everything Ok(If(Vec::new())) } ty::ty_uniq(_) => { // Box match bound { - ty::BoundCopy => { - Err(Unimplemented) - } + ty::BoundCopy => Err(Unimplemented), - ty::BoundSized => { - Ok(If(Vec::new())) - } + ty::BoundSized => Ok(If(Vec::new())), ty::BoundSync | ty::BoundSend => { self.tcx().sess.bug("Send/Sync shouldn't occur in builtin_bounds()"); @@ -1439,9 +1435,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::ty_ptr(..) => { // *const T, *mut T match bound { - ty::BoundCopy | ty::BoundSized => { - Ok(If(Vec::new())) - } + ty::BoundCopy | ty::BoundSized => Ok(If(Vec::new())), ty::BoundSync | ty::BoundSend => { self.tcx().sess.bug("Send/Sync shouldn't occur in builtin_bounds()"); @@ -1451,9 +1445,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::ty_trait(ref data) => { match bound { - ty::BoundSized => { - Err(Unimplemented) - } + ty::BoundSized => Err(Unimplemented), ty::BoundCopy => { if data.bounds.builtin_bounds.contains(&bound) { Ok(If(Vec::new())) @@ -1485,20 +1477,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::BoundCopy => { match mutbl { // &mut T is affine and hence never `Copy` - ast::MutMutable => { - Err(Unimplemented) - } + ast::MutMutable => Err(Unimplemented), // &T is always copyable - ast::MutImmutable => { - Ok(If(Vec::new())) - } + ast::MutImmutable => Ok(If(Vec::new())), } } - ty::BoundSized => { - Ok(If(Vec::new())) - } + ty::BoundSized => Ok(If(Vec::new())), ty::BoundSync | ty::BoundSend => { self.tcx().sess.bug("Send/Sync shouldn't occur in builtin_bounds()"); @@ -1511,14 +1497,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match bound { ty::BoundCopy => { match *len { - Some(_) => { - // [T, ..n] is copy iff T is copy - Ok(If(vec![element_ty])) - } - None => { - // [T] is unsized and hence affine - Err(Unimplemented) - } + // [T, ..n] is copy iff T is copy + Some(_) => Ok(If(vec![element_ty])), + + // [T] is unsized and hence affine + None => Err(Unimplemented), } } @@ -1543,16 +1526,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.tcx().sess.bug("Send/Sync shouldn't occur in builtin_bounds()"); } - ty::BoundCopy | ty::BoundSized => { - Err(Unimplemented) - } + ty::BoundCopy | ty::BoundSized => Err(Unimplemented), } } - ty::ty_tup(ref tys) => { - // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet - Ok(If(tys.clone())) - } + // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet + ty::ty_tup(ref tys) => Ok(If(tys.clone())), ty::ty_closure(def_id, _, substs) => { // FIXME -- This case is tricky. In the case of by-ref @@ -1581,9 +1560,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } match self.closure_typer.closure_upvars(def_id, substs) { - Some(upvars) => { - Ok(If(upvars.iter().map(|c| c.ty).collect())) - } + Some(upvars) => Ok(If(upvars.iter().map(|c| c.ty).collect())), None => { debug!("assemble_builtin_bound_candidates: no upvar types available yet"); Ok(AmbiguousBuiltin) @@ -1609,8 +1586,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { nominal(bound, types) } - ty::ty_projection(_) | - ty::ty_param(_) => { + ty::ty_projection(_) | ty::ty_param(_) => { // Note: A type parameter is only considered to meet a // particular bound if there is a where clause telling // us that it does, and that case is handled by @@ -1626,12 +1602,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Ok(AmbiguousBuiltin) } - ty::ty_err => { - Ok(If(Vec::new())) - } + ty::ty_err => Ok(If(Vec::new())), - ty::ty_infer(ty::FreshTy(_)) | - ty::ty_infer(ty::FreshIntTy(_)) => { + ty::ty_infer(ty::FreshTy(_)) + | ty::ty_infer(ty::FreshIntTy(_)) => { self.tcx().sess.bug( &format!( "asked to assemble builtin bounds of unexpected type: {}", @@ -1641,7 +1615,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn nominal<'cx, 'tcx>(bound: ty::BuiltinBound, types: Vec>) - -> Result,SelectionError<'tcx>> + -> Result, SelectionError<'tcx>> { // First check for markers and other nonsense. match bound { @@ -1692,7 +1666,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.tcx().sess.bug( &format!( "asked to assemble constituent types of unexpected type: {}", - t.repr(self.tcx()))[]); + t.repr(self.tcx()))); } ty::ty_uniq(referent_ty) => { // Box @@ -1909,7 +1883,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }).collect::>(); let obligations = match obligations { Ok(o) => o, - Err(ErrorReported) => Vec::new() + Err(ErrorReported) => Vec::new(), }; let obligations = VecPerParamSpace::new(obligations, Vec::new(), Vec::new()); @@ -1937,14 +1911,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let self_ty = self.infcx.shallow_resolve(obligation.predicate.0.self_ty()); match self.constituent_types_for_ty(self_ty) { - Some(types) => { - Ok(self.vtable_default_impl(obligation, impl_def_id, types)) - } + Some(types) => Ok(self.vtable_default_impl(obligation, impl_def_id, types)), None => { self.tcx().sess.bug( &format!( "asked to confirm default implementation for ambiguous type: {}", - self_ty.repr(self.tcx()))[]); + self_ty.repr(self.tcx()))); } } } @@ -2223,9 +2195,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { { match self.match_impl(impl_def_id, obligation, snapshot, skol_map, skol_obligation_trait_ref) { - Ok(substs) => { - substs - } + Ok(substs) => substs, Err(()) => { self.tcx().sess.bug( &format!("Impl {} was matchable against {} but now is not", @@ -2273,30 +2243,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { skol_obligation_trait_ref.repr(self.tcx())); let origin = infer::RelateOutputImplTypes(obligation.cause.span); - match self.infcx.sub_trait_refs(false, - origin, - impl_trait_ref.value.clone(), - skol_obligation_trait_ref) { - Ok(()) => { } - Err(e) => { - debug!("match_impl: failed sub_trait_refs due to `{}`", - ty::type_err_to_str(self.tcx(), &e)); - return Err(()); - } + if let Err(e) = self.infcx.sub_trait_refs(false, + origin, + impl_trait_ref.value.clone(), + skol_obligation_trait_ref) { + debug!("match_impl: failed sub_trait_refs due to `{}`", + ty::type_err_to_str(self.tcx(), &e)); + return Err(()); } - match self.infcx.leak_check(skol_map, snapshot) { - Ok(()) => { } - Err(e) => { - debug!("match_impl: failed leak check due to `{}`", - ty::type_err_to_str(self.tcx(), &e)); - return Err(()); - } + if let Err(e) = self.infcx.leak_check(skol_map, snapshot) { + debug!("match_impl: failed leak check due to `{}`", + ty::type_err_to_str(self.tcx(), &e)); + return Err(()); } debug!("match_impl: success impl_substs={}", impl_substs.repr(self.tcx())); - Ok(Normalized { value: impl_substs, - obligations: impl_trait_ref.obligations }) + Ok(Normalized { + value: impl_substs, + obligations: impl_trait_ref.obligations + }) } fn fast_reject_trait_refs(&mut self, @@ -2332,9 +2298,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { where_clause_trait_ref: ty::PolyTraitRef<'tcx>) -> Result>,()> { - let () = - try!(self.match_poly_trait_ref(obligation, where_clause_trait_ref)); - + try!(self.match_poly_trait_ref(obligation, where_clause_trait_ref)); Ok(Vec::new()) } @@ -2451,7 +2415,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match self.tcx().trait_impls.borrow().get(&trait_def_id) { None => Vec::new(), - Some(impls) => impls.borrow().clone() + Some(impls) => impls.borrow().clone(), } } @@ -2549,9 +2513,7 @@ impl<'tcx> Repr<'tcx> for SelectionCandidate<'tcx> { DefaultImplCandidate(t) => format!("DefaultImplCandidate({:?})", t), ProjectionCandidate => format!("ProjectionCandidate"), FnPointerCandidate => format!("FnPointerCandidate"), - ObjectCandidate => { - format!("ObjectCandidate") - } + ObjectCandidate => format!("ObjectCandidate"), ClosureCandidate(c, ref s) => { format!("ClosureCandidate({:?},{})", c, s.repr(tcx)) } @@ -2582,9 +2544,7 @@ impl<'o, 'tcx> Iterator for Option<&'o TraitObligationStack<'o, 'tcx>> { *self = o.previous; Some(o) } - None => { - None - } + None => None } } } @@ -2599,15 +2559,11 @@ impl<'o, 'tcx> Repr<'tcx> for TraitObligationStack<'o, 'tcx> { impl<'tcx> EvaluationResult<'tcx> { fn may_apply(&self) -> bool { match *self { - EvaluatedToOk | - EvaluatedToAmbig | - EvaluatedToErr(Overflow) | - EvaluatedToErr(OutputTypeParameterMismatch(..)) => { - true - } - EvaluatedToErr(Unimplemented) => { - false - } + EvaluatedToOk + | EvaluatedToAmbig + | EvaluatedToErr(Overflow) + | EvaluatedToErr(OutputTypeParameterMismatch(..)) => true, + EvaluatedToErr(Unimplemented) => false, } } } diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 19046d84d6972..5cbe9dd71fb24 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -359,7 +359,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, }; unsafe { let _icx = push_ctxt("const_expr"); - return match e.node { + match e.node { ast::ExprLit(ref lit) => { const_lit(cx, e, &**lit) } @@ -379,7 +379,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let (te2, _) = const_expr(cx, &**e2, param_substs); let te2 = base::cast_shift_const_rhs(b, te1, te2); - return match b.node { + match b.node { ast::BiAdd => { if is_float { llvm::LLVMConstFAdd(te1, te2) } else { llvm::LLVMConstAdd(te1, te2) } @@ -433,7 +433,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ast::ExprUnary(u, ref e) => { let (te, ty) = const_expr(cx, &**e, param_substs); let is_float = ty::type_is_fp(ty); - return match u { + match u { ast::UnUniq | ast::UnDeref => { const_deref(cx, te, ty).0 } @@ -514,8 +514,8 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, if expr::cast_is_noop(basety, ety) { return v; } - return match (expr::cast_type_kind(cx.tcx(), basety), - expr::cast_type_kind(cx.tcx(), ety)) { + match (expr::cast_type_kind(cx.tcx(), basety), + expr::cast_type_kind(cx.tcx(), ety)) { (expr::cast_integral, expr::cast_integral) => { let s = ty::type_is_signed(basety) as Bool; @@ -584,13 +584,13 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } let opt_def = cx.tcx().def_map.borrow().get(&cur.id).cloned(); if let Some(def::DefStatic(def_id, _)) = opt_def { - return get_static_val(cx, def_id, ety); + get_static_val(cx, def_id, ety) + } else { + // If this isn't the address of a static, then keep going through + // normal constant evaluation. + let (v, _) = const_expr(cx, &**sub, param_substs); + addr_of(cx, v, "ref", e.id) } - - // If this isn't the address of a static, then keep going through - // normal constant evaluation. - let (v, _) = const_expr(cx, &**sub, param_substs); - addr_of(cx, v, "ref", e.id) } ast::ExprAddrOf(ast::MutMutable, ref sub) => { let (v, _) = const_expr(cx, &**sub, param_substs); @@ -740,7 +740,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } _ => cx.sess().span_bug(e.span, "bad constant expression type in consts::const_expr") - }; + } } } From 01385a237fb6f4d80fbeb0f469caeb32075e22f9 Mon Sep 17 00:00:00 2001 From: Valerii Hiora Date: Tue, 24 Feb 2015 16:44:30 +0200 Subject: [PATCH 13/39] iOS: Sync/Send fallout --- src/libstd/rand/os.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs index 0e2766f388944..1a13405633d2e 100644 --- a/src/libstd/rand/os.rs +++ b/src/libstd/rand/os.rs @@ -188,7 +188,6 @@ mod imp { extern crate libc; use old_io::{IoResult}; - use marker::Sync; use mem; use os; use rand::Rng; @@ -214,10 +213,8 @@ mod imp { #[repr(C)] struct SecRandom; - unsafe impl Sync for *const SecRandom {} - #[allow(non_upper_case_globals)] - static kSecRandomDefault: *const SecRandom = 0 as *const SecRandom; + const kSecRandomDefault: *const SecRandom = 0 as *const SecRandom; #[link(name = "Security", kind = "framework")] extern "C" { From 54b11066bb9af585f161164000c43fdfe21c646f Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Tue, 24 Feb 2015 17:01:50 +0100 Subject: [PATCH 14/39] Revert a wrong replace of "fail" to "panic" --- src/libstd/sys/windows/tty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/windows/tty.rs b/src/libstd/sys/windows/tty.rs index 8a8b53090570c..c9bac69c434c3 100644 --- a/src/libstd/sys/windows/tty.rs +++ b/src/libstd/sys/windows/tty.rs @@ -52,7 +52,7 @@ fn invalid_encoding() -> IoError { pub fn is_tty(fd: c_int) -> bool { let mut out: DWORD = 0; - // If this function doesn't panic then fd is a TTY + // If this function doesn't return an error, then fd is a TTY match unsafe { GetConsoleMode(get_osfhandle(fd) as HANDLE, &mut out as LPDWORD) } { 0 => false, From 0fc1a7da93e5d431f5cd54a3f1263e2a5f9e5748 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Tue, 24 Feb 2015 17:07:13 +0100 Subject: [PATCH 15/39] Improve readability of an error check in `set_non_blocking` --- src/libstd/sys/windows/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index a13c03c7448cb..3acb372f658c5 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -194,11 +194,11 @@ pub fn wouldblock() -> bool { pub fn set_nonblocking(fd: sock_t, nb: bool) { let mut set = nb as libc::c_ulong; - (if unsafe { c::ioctlsocket(fd, c::FIONBIO, &mut set) } != 0 { - Err(last_error()) - } else { - Ok(()) - }).unwrap(); + if unsafe { c::ioctlsocket(fd, c::FIONBIO, &mut set) } != 0 { + // The above function should not return an error unless we passed it + // invalid parameters. Panic on errors. + Err(last_error()).unwrap(); + } } pub fn init_net() { From f31ea22bffa025b53cf6d26bbf8c48030de13183 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 17 Feb 2015 14:05:12 -0500 Subject: [PATCH 16/39] Mention try macro in error chapter Fixes #22342 --- src/doc/trpl/error-handling.md | 72 ++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/src/doc/trpl/error-handling.md b/src/doc/trpl/error-handling.md index 68b36e7a4b7ca..cf60bd88c542b 100644 --- a/src/doc/trpl/error-handling.md +++ b/src/doc/trpl/error-handling.md @@ -223,6 +223,78 @@ let input = io::stdin().read_line() .ok() .expect("Failed to read line"); ``` + `ok()` converts the `IoResult` into an `Option`, and `expect()` does the same thing as `unwrap()`, but takes a message. This message is passed along to the underlying `panic!`, providing a better error message if the code errors. + +# Using `try!` + +When writing code that calls many functions that return the `Result` type, the +error handling can be tedious. The `try!` macro hides some of the boilerplate +of propagating errors up the call stack. + +It replaces this: + +```rust +use std::fs::File; +use std::io; +use std::io::prelude::*; + +struct Info { + name: String, + age: i32, + rating: i32, +} + +fn write_info(info: &Info) -> io::Result<()> { + let mut file = File::open("my_best_friends.txt").unwrap(); + + if let Err(e) = writeln!(&mut file, "name: {}", info.name) { + return Err(e) + } + if let Err(e) = writeln!(&mut file, "age: {}", info.age) { + return Err(e) + } + if let Err(e) = writeln!(&mut file, "rating: {}", info.rating) { + return Err(e) + } + + return Ok(()); +} +``` + +With this: + +```rust +use std::fs::File; +use std::io; +use std::io::prelude::*; + +struct Info { + name: String, + age: i32, + rating: i32, +} + +fn write_info(info: &Info) -> io::Result<()> { + let mut file = try!(File::open("my_best_friends.txt")); + + try!(writeln!(&mut file, "name: {}", info.name)); + try!(writeln!(&mut file, "age: {}", info.age)); + try!(writeln!(&mut file, "rating: {}", info.rating)); + + return Ok(()); +} +``` + +Wrapping an expression in `try!` will result in the unwrapped success (`Ok`) +value, unless the result is `Err`, in which case `Err` is returned early from +the enclosing function. + +It's worth noting that you can only use `try!` from a function that returns a +`Result`, which means that you cannot use `try!` inside of `main()`, because +`main()` doesn't return anything. + +`try!` makes use of [`FromError`](../std/error/#the-fromerror-trait) to determine +what to return in the error case. From 2807a1ce0255ce98415ebe6f65eb589d0f2f894b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 24 Feb 2015 21:15:45 +0300 Subject: [PATCH 17/39] Use arrays instead of vectors in tests --- src/doc/trpl/macros.md | 2 +- src/libcollections/binary_heap.rs | 2 +- src/libcollections/bit.rs | 12 ++-- src/libcollections/btree/map.rs | 4 +- src/libcollections/btree/set.rs | 20 +++--- src/libcollections/enum_set.rs | 22 +++--- src/libcollections/linked_list.rs | 4 +- src/libcollections/macros.rs | 2 +- src/libcollections/slice.rs | 40 +++++------ src/libcollections/str.rs | 70 +++++++++---------- src/libcollections/string.rs | 6 +- src/libcollections/vec.rs | 62 ++++++++-------- src/libcollections/vec_deque.rs | 14 ++-- src/libcollections/vec_map.rs | 6 +- src/libcore/iter.rs | 4 +- src/libcore/option.rs | 2 +- src/libcore/result.rs | 4 +- src/libcoretest/iter.rs | 53 ++++++-------- src/libcoretest/mem.rs | 2 +- src/libcoretest/nonzero.rs | 2 +- src/libcoretest/ptr.rs | 2 +- src/libcoretest/str.rs | 32 ++++----- src/librbml/io.rs | 2 +- src/librustc_driver/test.rs | 10 +-- src/libserialize/json.rs | 10 +-- src/libstd/old_io/extensions.rs | 16 ++--- src/libstd/old_io/mem.rs | 18 ++--- src/libstd/old_io/result.rs | 2 +- src/libstd/old_io/util.rs | 20 +++--- src/libstd/sys/common/wtf8.rs | 6 +- src/libsyntax/ext/expand.rs | 6 +- src/libsyntax/ext/mtwt.rs | 24 +++---- src/libsyntax/util/small_vector.rs | 4 +- src/libterm/terminfo/parm.rs | 6 +- src/test/run-pass/auto-ref-sliceable.rs | 2 +- .../run-pass/coerce-reborrow-mut-vec-arg.rs | 2 +- .../run-pass/coerce-reborrow-mut-vec-rcvr.rs | 2 +- src/test/run-pass/generic-static-methods.rs | 2 +- src/test/run-pass/monad.rs | 12 ++-- src/test/run-pass/trait-generic.rs | 8 +-- .../run-pass/unboxed-closures-infer-upvar.rs | 2 +- 41 files changed, 254 insertions(+), 267 deletions(-) diff --git a/src/doc/trpl/macros.md b/src/doc/trpl/macros.md index ce6fa3ce949cd..49da298bb3fcb 100644 --- a/src/doc/trpl/macros.md +++ b/src/doc/trpl/macros.md @@ -73,7 +73,7 @@ macro_rules! vec { }; } # fn main() { -# assert_eq!(&[1,2,3], &vec![1,2,3]); +# assert_eq!([1,2,3], vec![1,2,3]); # } ``` diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index 9f549fd723771..36c76dbad14ae 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -480,7 +480,7 @@ impl BinaryHeap { /// heap.push(3); /// /// let vec = heap.into_sorted_vec(); - /// assert_eq!(vec, vec![1, 2, 3, 4, 5, 6, 7]); + /// assert_eq!(vec, [1, 2, 3, 4, 5, 6, 7]); /// ``` pub fn into_sorted_vec(mut self) -> Vec { let mut end = self.len(); diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index f28f9976f0c5d..61bb204a443ed 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -640,13 +640,13 @@ impl BitVec { /// let mut bv = BitVec::from_elem(3, true); /// bv.set(1, false); /// - /// assert_eq!(bv.to_bytes(), vec!(0b10100000)); + /// assert_eq!(bv.to_bytes(), [0b10100000]); /// /// let mut bv = BitVec::from_elem(9, false); /// bv.set(2, true); /// bv.set(8, true); /// - /// assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000)); + /// assert_eq!(bv.to_bytes(), [0b00100000, 0b10000000]); /// ``` pub fn to_bytes(&self) -> Vec { fn bit(bit_vec: &BitVec, byte: usize, bit: usize) -> u8 { @@ -806,7 +806,7 @@ impl BitVec { /// let mut bv = BitVec::from_bytes(&[0b01001011]); /// bv.grow(2, true); /// assert_eq!(bv.len(), 10); - /// assert_eq!(bv.to_bytes(), vec!(0b01001011, 0b11000000)); + /// assert_eq!(bv.to_bytes(), [0b01001011, 0b11000000]); /// ``` pub fn grow(&mut self, n: usize, value: bool) { // Note: we just bulk set all the bits in the last word in this fn in multiple places @@ -2285,12 +2285,12 @@ mod tests { fn test_to_bytes() { let mut bv = BitVec::from_elem(3, true); bv.set(1, false); - assert_eq!(bv.to_bytes(), vec!(0b10100000)); + assert_eq!(bv.to_bytes(), [0b10100000]); let mut bv = BitVec::from_elem(9, false); bv.set(2, true); bv.set(8, true); - assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000)); + assert_eq!(bv.to_bytes(), [0b00100000, 0b10000000]); } #[test] @@ -2675,7 +2675,7 @@ mod bit_set_test { let bit_vec: BitSet = usizes.into_iter().collect(); let idxs: Vec<_> = bit_vec.iter().collect(); - assert_eq!(idxs, vec![0, 2, 3]); + assert_eq!(idxs, [0, 2, 3]); let long: BitSet = (0..10000).filter(|&n| n % 2 == 0).collect(); let real: Vec<_> = range_step(0, 10000, 2).collect(); diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 1b456eec830b1..6b83253faed82 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -1281,7 +1281,7 @@ impl BTreeMap { /// a.insert(2, "b"); /// /// let keys: Vec = a.keys().cloned().collect(); - /// assert_eq!(keys, vec![1,2,]); + /// assert_eq!(keys, [1, 2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn keys<'a>(&'a self) -> Keys<'a, K, V> { @@ -1303,7 +1303,7 @@ impl BTreeMap { /// a.insert(2, "b"); /// /// let values: Vec<&str> = a.values().cloned().collect(); - /// assert_eq!(values, vec!["a","b"]); + /// assert_eq!(values, ["a", "b"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn values<'a>(&'a self) -> Values<'a, K, V> { diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index 929b2f5804303..8a668a23dbbe7 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -121,7 +121,7 @@ impl BTreeSet { /// } /// /// let v: Vec = set.iter().cloned().collect(); - /// assert_eq!(v, vec![1,2,3,4]); + /// assert_eq!(v, [1, 2, 3, 4]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn iter(&self) -> Iter { @@ -138,7 +138,7 @@ impl BTreeSet { /// let set: BTreeSet = [1, 2, 3, 4].iter().cloned().collect(); /// /// let v: Vec = set.into_iter().collect(); - /// assert_eq!(v, vec![1,2,3,4]); + /// assert_eq!(v, [1, 2, 3, 4]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn into_iter(self) -> IntoIter { @@ -197,7 +197,7 @@ impl BTreeSet { /// b.insert(3); /// /// let diff: Vec = a.difference(&b).cloned().collect(); - /// assert_eq!(diff, vec![1]); + /// assert_eq!(diff, [1]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn difference<'a>(&'a self, other: &'a BTreeSet) -> Difference<'a, T> { @@ -220,7 +220,7 @@ impl BTreeSet { /// b.insert(3); /// /// let sym_diff: Vec = a.symmetric_difference(&b).cloned().collect(); - /// assert_eq!(sym_diff, vec![1,3]); + /// assert_eq!(sym_diff, [1, 3]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn symmetric_difference<'a>(&'a self, other: &'a BTreeSet) @@ -244,7 +244,7 @@ impl BTreeSet { /// b.insert(3); /// /// let intersection: Vec = a.intersection(&b).cloned().collect(); - /// assert_eq!(intersection, vec![2]); + /// assert_eq!(intersection, [2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn intersection<'a>(&'a self, other: &'a BTreeSet) @@ -266,7 +266,7 @@ impl BTreeSet { /// b.insert(2); /// /// let union: Vec = a.union(&b).cloned().collect(); - /// assert_eq!(union, vec![1,2]); + /// assert_eq!(union, [1, 2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn union<'a>(&'a self, other: &'a BTreeSet) -> Union<'a, T> { @@ -534,7 +534,7 @@ impl<'a, 'b, T: Ord + Clone> Sub<&'b BTreeSet> for &'a BTreeSet { /// /// let result = &a - &b; /// let result_vec: Vec<_> = result.into_iter().collect(); - /// assert_eq!(result_vec, vec![1, 2]); + /// assert_eq!(result_vec, [1, 2]); /// ``` fn sub(self, rhs: &BTreeSet) -> BTreeSet { self.difference(rhs).cloned().collect() @@ -557,7 +557,7 @@ impl<'a, 'b, T: Ord + Clone> BitXor<&'b BTreeSet> for &'a BTreeSet { /// /// let result = &a ^ &b; /// let result_vec: Vec<_> = result.into_iter().collect(); - /// assert_eq!(result_vec, vec![1, 4]); + /// assert_eq!(result_vec, [1, 4]); /// ``` fn bitxor(self, rhs: &BTreeSet) -> BTreeSet { self.symmetric_difference(rhs).cloned().collect() @@ -580,7 +580,7 @@ impl<'a, 'b, T: Ord + Clone> BitAnd<&'b BTreeSet> for &'a BTreeSet { /// /// let result = &a & &b; /// let result_vec: Vec<_> = result.into_iter().collect(); - /// assert_eq!(result_vec, vec![2, 3]); + /// assert_eq!(result_vec, [2, 3]); /// ``` fn bitand(self, rhs: &BTreeSet) -> BTreeSet { self.intersection(rhs).cloned().collect() @@ -603,7 +603,7 @@ impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet> for &'a BTreeSet { /// /// let result = &a | &b; /// let result_vec: Vec<_> = result.into_iter().collect(); - /// assert_eq!(result_vec, vec![1, 2, 3, 4, 5]); + /// assert_eq!(result_vec, [1, 2, 3, 4, 5]); /// ``` fn bitor(self, rhs: &BTreeSet) -> BTreeSet { self.union(rhs).cloned().collect() diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index 0c95742606083..12c5d7a9cc61d 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -428,19 +428,19 @@ mod test { e1.insert(A); let elems: ::vec::Vec<_> = e1.iter().collect(); - assert_eq!(vec![A], elems); + assert_eq!([A], elems); e1.insert(C); let elems: ::vec::Vec<_> = e1.iter().collect(); - assert_eq!(vec![A,C], elems); + assert_eq!([A,C], elems); e1.insert(C); let elems: ::vec::Vec<_> = e1.iter().collect(); - assert_eq!(vec![A,C], elems); + assert_eq!([A,C], elems); e1.insert(B); let elems: ::vec::Vec<_> = e1.iter().collect(); - assert_eq!(vec![A,B,C], elems); + assert_eq!([A,B,C], elems); } /////////////////////////////////////////////////////////////////////////// @@ -458,35 +458,35 @@ mod test { let e_union = e1 | e2; let elems: ::vec::Vec<_> = e_union.iter().collect(); - assert_eq!(vec![A,B,C], elems); + assert_eq!([A,B,C], elems); let e_intersection = e1 & e2; let elems: ::vec::Vec<_> = e_intersection.iter().collect(); - assert_eq!(vec![C], elems); + assert_eq!([C], elems); // Another way to express intersection let e_intersection = e1 - (e1 - e2); let elems: ::vec::Vec<_> = e_intersection.iter().collect(); - assert_eq!(vec![C], elems); + assert_eq!([C], elems); let e_subtract = e1 - e2; let elems: ::vec::Vec<_> = e_subtract.iter().collect(); - assert_eq!(vec![A], elems); + assert_eq!([A], elems); // Bitwise XOR of two sets, aka symmetric difference let e_symmetric_diff = e1 ^ e2; let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect(); - assert_eq!(vec![A,B], elems); + assert_eq!([A,B], elems); // Another way to express symmetric difference let e_symmetric_diff = (e1 - e2) | (e2 - e1); let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect(); - assert_eq!(vec![A,B], elems); + assert_eq!([A,B], elems); // Yet another way to express symmetric difference let e_symmetric_diff = (e1 | e2) - (e1 & e2); let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect(); - assert_eq!(vec![A,B], elems); + assert_eq!([A,B], elems); } #[test] diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index 3c61fc3da90e3..aa9bd5b0fedab 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -777,7 +777,7 @@ impl<'a, A> IterMut<'a, A> { /// } /// { /// let vec: Vec<_> = list.into_iter().collect(); - /// assert_eq!(vec, vec![1, 2, 3, 4]); + /// assert_eq!(vec, [1, 2, 3, 4]); /// } /// ``` #[inline] @@ -1273,7 +1273,7 @@ mod tests { } check_links(&m); assert_eq!(m.len(), 3 + len * 2); - assert_eq!(m.into_iter().collect::>(), vec![-2,0,1,2,3,4,5,6,7,8,9,0,1]); + assert_eq!(m.into_iter().collect::>(), [-2,0,1,2,3,4,5,6,7,8,9,0,1]); } #[test] diff --git a/src/libcollections/macros.rs b/src/libcollections/macros.rs index ebcfb8d1cf84e..e9764547628c0 100644 --- a/src/libcollections/macros.rs +++ b/src/libcollections/macros.rs @@ -26,7 +26,7 @@ /// /// ``` /// let v = vec![1; 3]; -/// assert_eq!(v, vec![1, 1, 1]); +/// assert_eq!(v, [1, 1, 1]); /// ``` /// /// Note that unlike array expressions this syntax supports all elements diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 776b8b3af147c..6850e8c0f8ee7 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -1779,10 +1779,10 @@ mod tests { let mut v = vec![1, 2, 3, 4, 5]; let mut e = v.swap_remove(0); assert_eq!(e, 1); - assert_eq!(v, vec![5, 2, 3, 4]); + assert_eq!(v, [5, 2, 3, 4]); e = v.swap_remove(3); assert_eq!(e, 4); - assert_eq!(v, vec![5, 2, 3]); + assert_eq!(v, [5, 2, 3]); } #[test] @@ -1890,7 +1890,7 @@ mod tests { fn test_retain() { let mut v = vec![1, 2, 3, 4, 5]; v.retain(is_odd); - assert_eq!(v, vec![1, 3, 5]); + assert_eq!(v, [1, 3, 5]); } #[test] @@ -2159,45 +2159,45 @@ mod tests { let v: [Vec; 0] = []; let c = v.concat(); assert_eq!(c, []); - let d = [vec![1], vec![2,3]].concat(); - assert_eq!(d, vec![1, 2, 3]); + let d = [vec![1], vec![2, 3]].concat(); + assert_eq!(d, [1, 2, 3]); let v: &[&[_]] = &[&[1], &[2, 3]]; - assert_eq!(v.connect(&0), vec![1, 0, 2, 3]); + assert_eq!(v.connect(&0), [1, 0, 2, 3]); let v: &[&[_]] = &[&[1], &[2], &[3]]; - assert_eq!(v.connect(&0), vec![1, 0, 2, 0, 3]); + assert_eq!(v.connect(&0), [1, 0, 2, 0, 3]); } #[test] fn test_connect() { let v: [Vec; 0] = []; - assert_eq!(v.connect(&0), vec![]); - assert_eq!([vec![1], vec![2, 3]].connect(&0), vec![1, 0, 2, 3]); - assert_eq!([vec![1], vec![2], vec![3]].connect(&0), vec![1, 0, 2, 0, 3]); + assert_eq!(v.connect(&0), []); + assert_eq!([vec![1i], vec![2, 3]].connect(&0), [1, 0, 2, 3]); + assert_eq!([vec![1i], vec![2], vec![3]].connect(&0), [1, 0, 2, 0, 3]); let v: [&[_]; 2] = [&[1], &[2, 3]]; - assert_eq!(v.connect(&0), vec![1, 0, 2, 3]); + assert_eq!(v.connect(&0), [1, 0, 2, 3]); let v: [&[_]; 3] = [&[1], &[2], &[3]]; - assert_eq!(v.connect(&0), vec![1, 0, 2, 0, 3]); + assert_eq!(v.connect(&0), [1, 0, 2, 0, 3]); } #[test] fn test_insert() { let mut a = vec![1, 2, 4]; a.insert(2, 3); - assert_eq!(a, vec![1, 2, 3, 4]); + assert_eq!(a, [1, 2, 3, 4]); let mut a = vec![1, 2, 3]; a.insert(0, 0); - assert_eq!(a, vec![0, 1, 2, 3]); + assert_eq!(a, [0, 1, 2, 3]); let mut a = vec![1, 2, 3]; a.insert(3, 4); - assert_eq!(a, vec![1, 2, 3, 4]); + assert_eq!(a, [1, 2, 3, 4]); let mut a = vec![]; a.insert(0, 1); - assert_eq!(a, vec![1]); + assert_eq!(a, [1]); } #[test] @@ -2212,16 +2212,16 @@ mod tests { let mut a = vec![1, 2, 3, 4]; assert_eq!(a.remove(2), 3); - assert_eq!(a, vec![1, 2, 4]); + assert_eq!(a, [1, 2, 4]); assert_eq!(a.remove(2), 4); - assert_eq!(a, vec![1, 2]); + assert_eq!(a, [1, 2]); assert_eq!(a.remove(0), 1); - assert_eq!(a, vec![2]); + assert_eq!(a, [2]); assert_eq!(a.remove(0), 2); - assert_eq!(a, vec![]); + assert_eq!(a, []); } #[test] diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index f3b2e9738979c..c58cca828d8c3 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -552,7 +552,7 @@ pub trait StrExt: Index { /// ``` /// let v: Vec = "abc åäö".chars().collect(); /// - /// assert_eq!(v, vec!['a', 'b', 'c', ' ', 'Ã¥', 'ä', 'ö']); + /// assert_eq!(v, ['a', 'b', 'c', ' ', 'Ã¥', 'ä', 'ö']); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn chars(&self) -> Chars { @@ -600,20 +600,20 @@ pub trait StrExt: Index { /// /// ``` /// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect(); - /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]); + /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]); /// /// let v: Vec<&str> = "".split('X').collect(); - /// assert_eq!(v, vec![""]); + /// assert_eq!(v, [""]); /// ``` /// /// More complex patterns with a lambda: /// /// ``` /// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect(); - /// assert_eq!(v, vec!["abc", "def", "ghi"]); + /// assert_eq!(v, ["abc", "def", "ghi"]); /// /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect(); - /// assert_eq!(v, vec!["lion", "", "tiger", "leopard"]); + /// assert_eq!(v, ["lion", "", "tiger", "leopard"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> { @@ -632,23 +632,23 @@ pub trait StrExt: Index { /// /// ``` /// let v: Vec<&str> = "Mary had a little lambda".splitn(2, ' ').collect(); - /// assert_eq!(v, vec!["Mary", "had", "a little lambda"]); + /// assert_eq!(v, ["Mary", "had", "a little lambda"]); /// /// let v: Vec<&str> = "lionXXtigerXleopard".splitn(2, 'X').collect(); - /// assert_eq!(v, vec!["lion", "", "tigerXleopard"]); + /// assert_eq!(v, ["lion", "", "tigerXleopard"]); /// /// let v: Vec<&str> = "abcXdef".splitn(0, 'X').collect(); - /// assert_eq!(v, vec!["abcXdef"]); + /// assert_eq!(v, ["abcXdef"]); /// /// let v: Vec<&str> = "".splitn(1, 'X').collect(); - /// assert_eq!(v, vec![""]); + /// assert_eq!(v, [""]); /// ``` /// /// More complex patterns with a lambda: /// /// ``` /// let v: Vec<&str> = "abc1def2ghi".splitn(1, |c: char| c.is_numeric()).collect(); - /// assert_eq!(v, vec!["abc", "def2ghi"]); + /// assert_eq!(v, ["abc", "def2ghi"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P> { @@ -669,17 +669,17 @@ pub trait StrExt: Index { /// /// ``` /// let v: Vec<&str> = "A.B.".split_terminator('.').collect(); - /// assert_eq!(v, vec!["A", "B"]); + /// assert_eq!(v, ["A", "B"]); /// /// let v: Vec<&str> = "A..B..".split_terminator('.').collect(); - /// assert_eq!(v, vec!["A", "", "B", ""]); + /// assert_eq!(v, ["A", "", "B", ""]); /// ``` /// /// More complex patterns with a lambda: /// /// ``` /// let v: Vec<&str> = "abc1def2ghi3".split_terminator(|c: char| c.is_numeric()).collect(); - /// assert_eq!(v, vec!["abc", "def", "ghi"]); + /// assert_eq!(v, ["abc", "def", "ghi"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> { @@ -699,17 +699,17 @@ pub trait StrExt: Index { /// /// ``` /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(2, ' ').collect(); - /// assert_eq!(v, vec!["lamb", "little", "Mary had a"]); + /// assert_eq!(v, ["lamb", "little", "Mary had a"]); /// /// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(2, 'X').collect(); - /// assert_eq!(v, vec!["leopard", "tiger", "lionX"]); + /// assert_eq!(v, ["leopard", "tiger", "lionX"]); /// ``` /// /// More complex patterns with a lambda: /// /// ``` /// let v: Vec<&str> = "abc1def2ghi".rsplitn(1, |c: char| c.is_numeric()).collect(); - /// assert_eq!(v, vec!["ghi", "abc1def"]); + /// assert_eq!(v, ["ghi", "abc1def"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P> { @@ -727,13 +727,13 @@ pub trait StrExt: Index { /// /// ``` /// let v: Vec<(usize, usize)> = "abcXXXabcYYYabc".match_indices("abc").collect(); - /// assert_eq!(v, vec![(0,3), (6,9), (12,15)]); + /// assert_eq!(v, [(0,3), (6,9), (12,15)]); /// /// let v: Vec<(usize, usize)> = "1abcabc2".match_indices("abc").collect(); - /// assert_eq!(v, vec![(1,4), (4,7)]); + /// assert_eq!(v, [(1,4), (4,7)]); /// /// let v: Vec<(usize, usize)> = "ababa".match_indices("aba").collect(); - /// assert_eq!(v, vec![(0, 3)]); // only the first `aba` + /// assert_eq!(v, [(0, 3)]); // only the first `aba` /// ``` #[unstable(feature = "collections", reason = "might have its iterator type changed")] @@ -749,10 +749,10 @@ pub trait StrExt: Index { /// /// ``` /// let v: Vec<&str> = "abcXXXabcYYYabc".split_str("abc").collect(); - /// assert_eq!(v, vec!["", "XXX", "YYY", ""]); + /// assert_eq!(v, ["", "XXX", "YYY", ""]); /// /// let v: Vec<&str> = "1abcabc2".split_str("abc").collect(); - /// assert_eq!(v, vec!["1", "", "2"]); + /// assert_eq!(v, ["1", "", "2"]); /// ``` #[unstable(feature = "collections")] #[deprecated(since = "1.0.0", reason = "use `split()` with a `&str`")] @@ -770,7 +770,7 @@ pub trait StrExt: Index { /// let four_lines = "foo\nbar\n\nbaz"; /// let v: Vec<&str> = four_lines.lines().collect(); /// - /// assert_eq!(v, vec!["foo", "bar", "", "baz"]); + /// assert_eq!(v, ["foo", "bar", "", "baz"]); /// ``` /// /// Leaving off the trailing character: @@ -779,7 +779,7 @@ pub trait StrExt: Index { /// let four_lines = "foo\nbar\n\nbaz\n"; /// let v: Vec<&str> = four_lines.lines().collect(); /// - /// assert_eq!(v, vec!["foo", "bar", "", "baz"]); + /// assert_eq!(v, ["foo", "bar", "", "baz"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn lines(&self) -> Lines { @@ -796,7 +796,7 @@ pub trait StrExt: Index { /// let four_lines = "foo\r\nbar\n\r\nbaz"; /// let v: Vec<&str> = four_lines.lines_any().collect(); /// - /// assert_eq!(v, vec!["foo", "bar", "", "baz"]); + /// assert_eq!(v, ["foo", "bar", "", "baz"]); /// ``` /// /// Leaving off the trailing character: @@ -805,7 +805,7 @@ pub trait StrExt: Index { /// let four_lines = "foo\r\nbar\n\r\nbaz\n"; /// let v: Vec<&str> = four_lines.lines_any().collect(); /// - /// assert_eq!(v, vec!["foo", "bar", "", "baz"]); + /// assert_eq!(v, ["foo", "bar", "", "baz"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn lines_any(&self) -> LinesAny { @@ -1441,7 +1441,7 @@ pub trait StrExt: Index { /// let some_words = " Mary had\ta little \n\t lamb"; /// let v: Vec<&str> = some_words.words().collect(); /// - /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]); + /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]); /// ``` #[unstable(feature = "str_words", reason = "the precise algorithm to use is unclear")] @@ -2400,17 +2400,17 @@ mod tests { let data = "\nMäry häd ä little lämb\nLittle lämb\n"; let split: Vec<&str> = data.splitn(3, ' ').collect(); - assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]); + assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]); let split: Vec<&str> = data.splitn(3, |c: char| c == ' ').collect(); - assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]); + assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]); // Unicode let split: Vec<&str> = data.splitn(3, 'ä').collect(); - assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]); + assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]); let split: Vec<&str> = data.splitn(3, |c: char| c == 'ä').collect(); - assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]); + assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]); } #[test] @@ -2418,17 +2418,17 @@ mod tests { let data = "\nMäry häd ä little lämb\nLittle lämb\n"; let split: Vec<&str> = data.split('\n').collect(); - assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb", ""]); + assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]); let split: Vec<&str> = data.split_terminator('\n').collect(); - assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb"]); + assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]); } #[test] fn test_words() { let data = "\n \tMäry häd\tä little lämb\nLittle lämb\n"; let words: Vec<&str> = data.words().collect(); - assert_eq!(words, vec!["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"]) + assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"]) } #[test] @@ -2513,11 +2513,11 @@ mod tests { fn test_lines() { let data = "\nMäry häd ä little lämb\n\nLittle lämb\n"; let lines: Vec<&str> = data.lines().collect(); - assert_eq!(lines, vec!["", "Märy häd ä little lämb", "", "Little lämb"]); + assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]); let data = "\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n let lines: Vec<&str> = data.lines().collect(); - assert_eq!(lines, vec!["", "Märy häd ä little lämb", "", "Little lämb"]); + assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]); } #[test] diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 6c2624cd204de..e9070cff20758 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -120,7 +120,7 @@ impl String { /// let invalid_vec = vec![240, 144, 128]; /// let s = String::from_utf8(invalid_vec).err().unwrap(); /// assert_eq!(s.utf8_error(), Utf8Error::TooShort); - /// assert_eq!(s.into_bytes(), vec![240, 144, 128]); + /// assert_eq!(s.into_bytes(), [240, 144, 128]); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -340,7 +340,7 @@ impl String { /// ``` /// let s = String::from_str("hello"); /// let bytes = s.into_bytes(); - /// assert_eq!(bytes, vec![104, 101, 108, 108, 111]); + /// assert_eq!(bytes, [104, 101, 108, 108, 111]); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -619,7 +619,7 @@ impl String { /// let mut s = String::from_str("hello"); /// unsafe { /// let vec = s.as_mut_vec(); - /// assert!(vec == &mut vec![104, 101, 108, 108, 111]); + /// assert!(vec == &[104, 101, 108, 108, 111]); /// vec.reverse(); /// } /// assert_eq!(s.as_slice(), "olleh"); diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 3f5f92889166f..c446618649d7d 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -93,7 +93,7 @@ use borrow::{Cow, IntoCow}; /// for x in vec.iter() { /// println!("{}", x); /// } -/// assert_eq!(vec, vec![7, 1, 2, 3]); +/// assert_eq!(vec, [7, 1, 2, 3]); /// ``` /// /// The `vec!` macro is provided to make initialization more convenient: @@ -101,7 +101,7 @@ use borrow::{Cow, IntoCow}; /// ``` /// let mut vec = vec![1, 2, 3]; /// vec.push(4); -/// assert_eq!(vec, vec![1, 2, 3, 4]); +/// assert_eq!(vec, [1, 2, 3, 4]); /// ``` /// /// Use a `Vec` as an efficient stack: @@ -242,7 +242,7 @@ impl Vec { /// /// // Put everything back together into a Vec /// let rebuilt = Vec::from_raw_parts(p, len, cap); - /// assert_eq!(rebuilt, vec![4, 5, 6]); + /// assert_eq!(rebuilt, [4, 5, 6]); /// } /// } /// ``` @@ -404,7 +404,7 @@ impl Vec { /// ``` /// let mut vec = vec![1, 2, 3, 4]; /// vec.truncate(2); - /// assert_eq!(vec, vec![1, 2]); + /// assert_eq!(vec, [1, 2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn truncate(&mut self, len: usize) { @@ -505,10 +505,10 @@ impl Vec { /// let mut v = vec!["foo", "bar", "baz", "qux"]; /// /// assert_eq!(v.swap_remove(1), "bar"); - /// assert_eq!(v, vec!["foo", "qux", "baz"]); + /// assert_eq!(v, ["foo", "qux", "baz"]); /// /// assert_eq!(v.swap_remove(0), "foo"); - /// assert_eq!(v, vec!["baz", "qux"]); + /// assert_eq!(v, ["baz", "qux"]); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -531,9 +531,9 @@ impl Vec { /// ``` /// let mut vec = vec![1, 2, 3]; /// vec.insert(1, 4); - /// assert_eq!(vec, vec![1, 4, 2, 3]); + /// assert_eq!(vec, [1, 4, 2, 3]); /// vec.insert(4, 5); - /// assert_eq!(vec, vec![1, 4, 2, 3, 5]); + /// assert_eq!(vec, [1, 4, 2, 3, 5]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn insert(&mut self, index: usize, element: T) { @@ -569,7 +569,7 @@ impl Vec { /// ``` /// let mut v = vec![1, 2, 3]; /// assert_eq!(v.remove(1), 2); - /// assert_eq!(v, vec![1, 3]); + /// assert_eq!(v, [1, 3]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, index: usize) -> T { @@ -603,7 +603,7 @@ impl Vec { /// ``` /// let mut vec = vec![1, 2, 3, 4]; /// vec.retain(|&x| x%2 == 0); - /// assert_eq!(vec, vec![2, 4]); + /// assert_eq!(vec, [2, 4]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn retain(&mut self, mut f: F) where F: FnMut(&T) -> bool { @@ -636,7 +636,7 @@ impl Vec { /// ```rust /// let mut vec = vec!(1, 2); /// vec.push(3); - /// assert_eq!(vec, vec!(1, 2, 3)); + /// assert_eq!(vec, [1, 2, 3]); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -674,7 +674,7 @@ impl Vec { /// ```rust /// let mut vec = vec![1, 2, 3]; /// assert_eq!(vec.pop(), Some(3)); - /// assert_eq!(vec, vec![1, 2]); + /// assert_eq!(vec, [1, 2]); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -701,8 +701,8 @@ impl Vec { /// let mut vec = vec![1, 2, 3]; /// let mut vec2 = vec![4, 5, 6]; /// vec.append(&mut vec2); - /// assert_eq!(vec, vec![1, 2, 3, 4, 5, 6]); - /// assert_eq!(vec2, vec![]); + /// assert_eq!(vec, [1, 2, 3, 4, 5, 6]); + /// assert_eq!(vec2, []); /// ``` #[inline] #[unstable(feature = "collections", @@ -1019,8 +1019,8 @@ impl Vec { /// ``` /// let mut vec = vec![1,2,3]; /// let vec2 = vec.split_off(1); - /// assert_eq!(vec, vec![1]); - /// assert_eq!(vec2, vec![2, 3]); + /// assert_eq!(vec, [1]); + /// assert_eq!(vec2, [2, 3]); /// ``` #[inline] #[unstable(feature = "collections", @@ -1057,11 +1057,11 @@ impl Vec { /// ``` /// let mut vec = vec!["hello"]; /// vec.resize(3, "world"); - /// assert_eq!(vec, vec!["hello", "world", "world"]); + /// assert_eq!(vec, ["hello", "world", "world"]); /// /// let mut vec = vec![1, 2, 3, 4]; /// vec.resize(2, 0); - /// assert_eq!(vec, vec![1, 2]); + /// assert_eq!(vec, [1, 2]); /// ``` #[unstable(feature = "collections", reason = "matches collection reform specification; waiting for dust to settle")] @@ -1085,7 +1085,7 @@ impl Vec { /// ``` /// let mut vec = vec![1]; /// vec.push_all(&[2, 3, 4]); - /// assert_eq!(vec, vec![1, 2, 3, 4]); + /// assert_eq!(vec, [1, 2, 3, 4]); /// ``` #[inline] #[unstable(feature = "collections", @@ -1121,7 +1121,7 @@ impl Vec { /// /// vec.dedup(); /// - /// assert_eq!(vec, vec![1, 2, 3, 2]); + /// assert_eq!(vec, [1, 2, 3, 2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn dedup(&mut self) { @@ -2105,7 +2105,7 @@ mod tests { } } - assert!(values == vec![2, 3, 5, 6, 7]); + assert_eq!(values, [2, 3, 5, 6, 7]); } #[test] @@ -2147,7 +2147,7 @@ mod tests { fn test_retain() { let mut vec = vec![1, 2, 3, 4]; vec.retain(|&x| x % 2 == 0); - assert!(vec == vec![2, 4]); + assert_eq!(vec, [2, 4]); } #[test] @@ -2207,13 +2207,13 @@ mod tests { let a = [1, 2, 3]; let ptr = a.as_ptr(); let b = Vec::from_raw_buf(ptr, 3); - assert_eq!(b, vec![1, 2, 3]); + assert_eq!(b, [1, 2, 3]); // Test on-heap copy-from-buf. let c = vec![1, 2, 3, 4, 5]; let ptr = c.as_ptr(); let d = Vec::from_raw_buf(ptr, 5); - assert_eq!(d, vec![1, 2, 3, 4, 5]); + assert_eq!(d, [1, 2, 3, 4, 5]); } } @@ -2375,7 +2375,7 @@ mod tests { for i in vec { vec2.push(i); } - assert!(vec2 == vec![1, 2, 3]); + assert_eq!(vec2, [1, 2, 3]); } #[test] @@ -2385,7 +2385,7 @@ mod tests { for i in vec.into_iter().rev() { vec2.push(i); } - assert!(vec2 == vec![3, 2, 1]); + assert_eq!(vec2, [3, 2, 1]); } #[test] @@ -2395,7 +2395,7 @@ mod tests { for i in vec { vec2.push(i); } - assert!(vec2 == vec![(), (), ()]); + assert_eq!(vec2, [(), (), ()]); } #[test] @@ -2443,16 +2443,16 @@ mod tests { let mut vec = vec![1, 2, 3]; let mut vec2 = vec![4, 5, 6]; vec.append(&mut vec2); - assert_eq!(vec, vec![1, 2, 3, 4, 5, 6]); - assert_eq!(vec2, vec![]); + assert_eq!(vec, [1, 2, 3, 4, 5, 6]); + assert_eq!(vec2, []); } #[test] fn test_split_off() { let mut vec = vec![1, 2, 3, 4, 5, 6]; let vec2 = vec.split_off(4); - assert_eq!(vec, vec![1, 2, 3, 4]); - assert_eq!(vec2, vec![5, 6]); + assert_eq!(vec, [1, 2, 3, 4]); + assert_eq!(vec2, [5, 6]); } #[bench] diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index f65e644fa5284..9476b98eb82c6 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -2105,7 +2105,7 @@ mod tests { let mut d: VecDeque<_> = (0..5).collect(); d.pop_front(); d.swap(0, 3); - assert_eq!(d.iter().cloned().collect::>(), vec!(4, 2, 3, 1)); + assert_eq!(d.iter().cloned().collect::>(), [4, 2, 3, 1]); } #[test] @@ -2868,17 +2868,17 @@ mod tests { // normal append a.append(&mut b); - assert_eq!(a.iter().cloned().collect(), vec![1, 2, 3, 4, 5, 6]); - assert_eq!(b.iter().cloned().collect(), vec![]); + assert_eq!(a.iter().cloned().collect(), [1, 2, 3, 4, 5, 6]); + assert_eq!(b.iter().cloned().collect(), []); // append nothing to something a.append(&mut b); - assert_eq!(a.iter().cloned().collect(), vec![1, 2, 3, 4, 5, 6]); - assert_eq!(b.iter().cloned().collect(), vec![]); + assert_eq!(a.iter().cloned().collect(), [1, 2, 3, 4, 5, 6]); + assert_eq!(b.iter().cloned().collect(), []); // append something to nothing b.append(&mut a); - assert_eq!(b.iter().cloned().collect(), vec![1, 2, 3, 4, 5, 6]); - assert_eq!(a.iter().cloned().collect(), vec![]); + assert_eq!(b.iter().cloned().collect(), [1, 2, 3, 4, 5, 6]); + assert_eq!(a.iter().cloned().collect(), []); } } diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index d92249379fa8f..1c497c86dfdde 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -308,7 +308,7 @@ impl VecMap { /// /// let vec: Vec<(usize, &str)> = map.into_iter().collect(); /// - /// assert_eq!(vec, vec![(1, "a"), (2, "b"), (3, "c")]); + /// assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn into_iter(self) -> IntoIter { @@ -425,7 +425,7 @@ impl VecMap { /// /// let vec: Vec<(usize, &str)> = map.drain().collect(); /// - /// assert_eq!(vec, vec![(1, "a"), (2, "b"), (3, "c")]); + /// assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]); /// ``` #[unstable(feature = "collections", reason = "matches collection reform specification, waiting for dust to settle")] @@ -1226,7 +1226,7 @@ mod test_map { let vec: Vec<_> = map.drain().collect(); - assert_eq!(vec, vec![(1, "a"), (2, "b"), (3, "c")]); + assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]); assert_eq!(map.len(), 0); } diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 09089f2d04c5f..6d8e04d97dd03 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -582,8 +582,8 @@ pub trait IteratorExt: Iterator + Sized { /// ``` /// let vec = vec![1, 2, 3, 4]; /// let (even, odd): (Vec<_>, Vec<_>) = vec.into_iter().partition(|&n| n % 2 == 0); - /// assert_eq!(even, vec![2, 4]); - /// assert_eq!(odd, vec![1, 3]); + /// assert_eq!(even, [2, 4]); + /// assert_eq!(odd, [1, 3]); /// ``` #[unstable(feature = "core", reason = "recently added as part of collections reform")] diff --git a/src/libcore/option.rs b/src/libcore/option.rs index abfef72a5dbc3..1ecbd8fae8cdb 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -556,7 +556,7 @@ impl Option { /// ``` /// let x = Some("string"); /// let v: Vec<&str> = x.into_iter().collect(); - /// assert_eq!(v, vec!["string"]); + /// assert_eq!(v, ["string"]); /// /// let x = None; /// let v: Vec<&str> = x.into_iter().collect(); diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 23e936a75d709..bca73782491bf 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -548,11 +548,11 @@ impl Result { /// ``` /// let x: Result = Ok(5); /// let v: Vec = x.into_iter().collect(); - /// assert_eq!(v, vec![5]); + /// assert_eq!(v, [5]); /// /// let x: Result = Err("nothing!"); /// let v: Vec = x.into_iter().collect(); - /// assert_eq!(v, vec![]); + /// assert_eq!(v, []); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index 6cbc7bf1bbc51..8a27400389f4a 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -74,7 +74,7 @@ fn test_multi_iter() { fn test_counter_from_iter() { let it = count(0, 5).take(10); let xs: Vec = FromIterator::from_iter(it); - assert!(xs == vec![0, 5, 10, 15, 20, 25, 30, 35, 40, 45]); + assert_eq!(xs, [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]); } #[test] @@ -104,7 +104,7 @@ fn test_iterator_chain() { fn test_filter_map() { let it = count(0, 1).take(10) .filter_map(|x| if x % 2 == 0 { Some(x*x) } else { None }); - assert!(it.collect::>() == vec![0*0, 2*2, 4*4, 6*6, 8*8]); + assert_eq!(it.collect::>(), [0*0, 2*2, 4*4, 6*6, 8*8]); } #[test] @@ -730,12 +730,12 @@ fn test_random_access_cycle() { #[test] fn test_double_ended_range() { - assert!((11..14).rev().collect::>() == vec![13, 12, 11]); + assert_eq!((11..14).rev().collect::>(), [13, 12, 11]); for _ in (10..0).rev() { panic!("unreachable"); } - assert!((11..14).rev().collect::>() == vec![13, 12, 11]); + assert_eq!((11..14).rev().collect::>(), [13, 12, 11]); for _ in (10..0).rev() { panic!("unreachable"); } @@ -743,10 +743,9 @@ fn test_double_ended_range() { #[test] fn test_range() { - assert!((0..5).collect::>() == vec![0, 1, 2, 3, 4]); - assert!((-10..-1).collect::>() == - vec![-10, -9, -8, -7, -6, -5, -4, -3, -2]); - assert!((0..5).rev().collect::>() == vec![4, 3, 2, 1, 0]); + assert_eq!((0..5).collect::>(), [0, 1, 2, 3, 4]); + assert_eq!((-10..-1).collect::>(), [-10, -9, -8, -7, -6, -5, -4, -3, -2]); + assert_eq!((0..5).rev().collect::>(), [4, 3, 2, 1, 0]); assert_eq!((200..-5).count(), 0); assert_eq!((200..-5).rev().count(), 0); assert_eq!((200..200).count(), 0); @@ -767,38 +766,28 @@ fn test_range_inclusive() { vec![5, 4, 3, 2, 1, 0]); assert_eq!(range_inclusive(200, -5).count(), 0); assert_eq!(range_inclusive(200, -5).rev().count(), 0); - assert!(range_inclusive(200, 200).collect::>() == vec![200]); - assert!(range_inclusive(200, 200).rev().collect::>() == vec![200]); + assert_eq!(range_inclusive(200, 200).collect::>(), [200]); + assert_eq!(range_inclusive(200, 200).rev().collect::>(), [200]); } #[test] fn test_range_step() { - assert!(range_step(0, 20, 5).collect::>() == - vec![0, 5, 10, 15]); - assert!(range_step(20, 0, -5).collect::>() == - vec![20, 15, 10, 5]); - assert!(range_step(20, 0, -6).collect::>() == - vec![20, 14, 8, 2]); - assert!(range_step(200u8, 255, 50).collect::>() == - vec![200u8, 250]); - assert!(range_step(200, -5, 1).collect::>() == vec![]); - assert!(range_step(200, 200, 1).collect::>() == vec![]); + assert_eq!(range_step(0, 20, 5).collect::>(), [0, 5, 10, 15]); + assert_eq!(range_step(20, 0, -5).collect::>(), [20, 15, 10, 5]); + assert_eq!(range_step(20, 0, -6).collect::>(), [20, 14, 8, 2]); + assert_eq!(range_step(200u8, 255, 50).collect::>(), [200u8, 250]); + assert_eq!(range_step(200i, -5, 1).collect::>(), []); + assert_eq!(range_step(200i, 200, 1).collect::>(), []); } #[test] fn test_range_step_inclusive() { - assert!(range_step_inclusive(0, 20, 5).collect::>() == - vec![0, 5, 10, 15, 20]); - assert!(range_step_inclusive(20, 0, -5).collect::>() == - vec![20, 15, 10, 5, 0]); - assert!(range_step_inclusive(20, 0, -6).collect::>() == - vec![20, 14, 8, 2]); - assert!(range_step_inclusive(200u8, 255, 50).collect::>() == - vec![200u8, 250]); - assert!(range_step_inclusive(200, -5, 1).collect::>() == - vec![]); - assert!(range_step_inclusive(200, 200, 1).collect::>() == - vec![200]); + assert_eq!(range_step_inclusive(0, 20, 5).collect::>(), [0, 5, 10, 15, 20]); + assert_eq!(range_step_inclusive(20, 0, -5).collect::>(), [20, 15, 10, 5, 0]); + assert_eq!(range_step_inclusive(20, 0, -6).collect::>(), [20, 14, 8, 2]); + assert_eq!(range_step_inclusive(200u8, 255, 50).collect::>(), [200u8, 250]); + assert_eq!(range_step_inclusive(200, -5, 1).collect::>(), []); + assert_eq!(range_step_inclusive(200, 200, 1).collect::>(), [200]); } #[test] diff --git a/src/libcoretest/mem.rs b/src/libcoretest/mem.rs index 5aeb330b78b54..73000670c61aa 100644 --- a/src/libcoretest/mem.rs +++ b/src/libcoretest/mem.rs @@ -103,7 +103,7 @@ fn test_transmute() { } unsafe { - assert!(vec![76u8] == transmute::<_, Vec>("L".to_string())); + assert_eq!([76u8], transmute::<_, Vec>("L".to_string())); } } diff --git a/src/libcoretest/nonzero.rs b/src/libcoretest/nonzero.rs index be4c83d23e8b3..f60570eaaf417 100644 --- a/src/libcoretest/nonzero.rs +++ b/src/libcoretest/nonzero.rs @@ -54,7 +54,7 @@ fn test_match_option_empty_vec() { fn test_match_option_vec() { let a = Some(vec![1, 2, 3, 4]); match a { - Some(v) => assert_eq!(v, vec![1, 2, 3, 4]), + Some(v) => assert_eq!(v, [1, 2, 3, 4]), None => panic!("unexpected None while matching on Some(vec![1, 2, 3, 4])") } } diff --git a/src/libcoretest/ptr.rs b/src/libcoretest/ptr.rs index 57456bfb1a79b..c8a54ef59abda 100644 --- a/src/libcoretest/ptr.rs +++ b/src/libcoretest/ptr.rs @@ -156,7 +156,7 @@ fn test_ptr_subtraction() { m_ptr = m_ptr.offset(-1); } - assert!(xs_mut == vec![0,2,4,6,8,10,12,14,16,18]); + assert_eq!(xs_mut, [0,2,4,6,8,10,12,14,16,18]); } } diff --git a/src/libcoretest/str.rs b/src/libcoretest/str.rs index beb746d25b61c..019f935911f7a 100644 --- a/src/libcoretest/str.rs +++ b/src/libcoretest/str.rs @@ -22,7 +22,7 @@ fn test_pattern_deref_forward() { fn test_empty_match_indices() { let data = "aä中!"; let vec: Vec<_> = data.match_indices("").collect(); - assert_eq!(vec, vec![(0, 0), (1, 1), (3, 3), (6, 6), (7, 7)]); + assert_eq!(vec, [(0, 0), (1, 1), (3, 3), (6, 6), (7, 7)]); } #[test] @@ -69,20 +69,20 @@ fn test_rsplitn_char_iterator() { let mut split: Vec<&str> = data.rsplitn(3, ' ').collect(); split.reverse(); - assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); + assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == ' ').collect(); split.reverse(); - assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); + assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); // Unicode let mut split: Vec<&str> = data.rsplitn(3, 'ä').collect(); split.reverse(); - assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); + assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == 'ä').collect(); split.reverse(); - assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); + assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); } #[test] @@ -90,33 +90,33 @@ fn test_split_char_iterator() { let data = "\nMäry häd ä little lämb\nLittle lämb\n"; let split: Vec<&str> = data.split(' ').collect(); - assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); + assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); let mut rsplit: Vec<&str> = data.split(' ').rev().collect(); rsplit.reverse(); - assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); + assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); let split: Vec<&str> = data.split(|c: char| c == ' ').collect(); - assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); + assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect(); rsplit.reverse(); - assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); + assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); // Unicode let split: Vec<&str> = data.split('ä').collect(); - assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); + assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); let mut rsplit: Vec<&str> = data.split('ä').rev().collect(); rsplit.reverse(); - assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); + assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); let split: Vec<&str> = data.split(|c: char| c == 'ä').collect(); - assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); + assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect(); rsplit.reverse(); - assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); + assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); } #[test] @@ -125,18 +125,18 @@ fn test_rev_split_char_iterator_no_trailing() { let mut split: Vec<&str> = data.split('\n').rev().collect(); split.reverse(); - assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb", ""]); + assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]); let mut split: Vec<&str> = data.split_terminator('\n').rev().collect(); split.reverse(); - assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb"]); + assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]); } #[test] fn test_utf16_code_units() { use unicode::str::Utf16Encoder; assert_eq!(Utf16Encoder::new(vec!['é', '\u{1F4A9}'].into_iter()).collect::>(), - vec![0xE9, 0xD83D, 0xDCA9]) + [0xE9, 0xD83D, 0xDCA9]) } #[test] diff --git a/src/librbml/io.rs b/src/librbml/io.rs index 230fda11ab5ac..c52465a889907 100644 --- a/src/librbml/io.rs +++ b/src/librbml/io.rs @@ -45,7 +45,7 @@ fn combine(seek: SeekStyle, cur: uint, end: uint, offset: i64) -> IoResult /// let mut w = SeekableMemWriter::new(); /// w.write(&[0, 1, 2]); /// -/// assert_eq!(w.unwrap(), vec!(0, 1, 2)); +/// assert_eq!(w.unwrap(), [0, 1, 2]); /// ``` pub struct SeekableMemWriter { buf: Vec, diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index cdcc9850e423e..d9cedc4829851 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -806,11 +806,11 @@ fn walk_ty() { let tup2_ty = ty::mk_tup(tcx, vec!(tup1_ty, tup1_ty, uint_ty)); let uniq_ty = ty::mk_uniq(tcx, tup2_ty); let walked: Vec<_> = uniq_ty.walk().collect(); - assert_eq!(vec!(uniq_ty, - tup2_ty, - tup1_ty, int_ty, uint_ty, int_ty, uint_ty, - tup1_ty, int_ty, uint_ty, int_ty, uint_ty, - uint_ty), + assert_eq!([uniq_ty, + tup2_ty, + tup1_ty, int_ty, uint_ty, int_ty, uint_ty, + tup1_ty, int_ty, uint_ty, int_ty, uint_ty, + uint_ty], walked); }) } diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index a0f42815b4396..05d4e0f59fefc 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -3074,19 +3074,19 @@ mod tests { #[test] fn test_decode_array() { let v: Vec<()> = super::decode("[]").unwrap(); - assert_eq!(v, vec![]); + assert_eq!(v, []); let v: Vec<()> = super::decode("[null]").unwrap(); - assert_eq!(v, vec![()]); + assert_eq!(v, [()]); let v: Vec = super::decode("[true]").unwrap(); - assert_eq!(v, vec![true]); + assert_eq!(v, [true]); let v: Vec = super::decode("[3, 1]").unwrap(); - assert_eq!(v, vec![3, 1]); + assert_eq!(v, [3, 1]); let v: Vec> = super::decode("[[3], [1, 2]]").unwrap(); - assert_eq!(v, vec![vec![3], vec![1, 2]]); + assert_eq!(v, [vec![3], vec![1, 2]]); } #[test] diff --git a/src/libstd/old_io/extensions.rs b/src/libstd/old_io/extensions.rs index c2a6c515acc70..8bd19f063f030 100644 --- a/src/libstd/old_io/extensions.rs +++ b/src/libstd/old_io/extensions.rs @@ -328,7 +328,7 @@ mod test { fn read_bytes() { let mut reader = MemReader::new(vec!(10, 11, 12, 13)); let bytes = reader.read_exact(4).unwrap(); - assert!(bytes == vec!(10, 11, 12, 13)); + assert_eq!(bytes, [10, 11, 12, 13]); } #[test] @@ -337,7 +337,7 @@ mod test { count: 0, }; let bytes = reader.read_exact(4).unwrap(); - assert!(bytes == vec!(10, 11, 12, 13)); + assert_eq!(bytes, [10, 11, 12, 13]); } #[test] @@ -351,7 +351,7 @@ mod test { let mut reader = MemReader::new(vec![10, 11, 12, 13]); let mut buf = vec![8, 9]; assert!(reader.push_at_least(4, 4, &mut buf).is_ok()); - assert!(buf == vec![8, 9, 10, 11, 12, 13]); + assert_eq!(buf, [8, 9, 10, 11, 12, 13]); } #[test] @@ -361,7 +361,7 @@ mod test { }; let mut buf = vec![8, 9]; assert!(reader.push_at_least(4, 4, &mut buf).is_ok()); - assert!(buf == vec![8, 9, 10, 11, 12, 13]); + assert_eq!(buf, [8, 9, 10, 11, 12, 13]); } #[test] @@ -369,7 +369,7 @@ mod test { let mut reader = MemReader::new(vec![10, 11]); let mut buf = vec![8, 9]; assert!(reader.push_at_least(4, 4, &mut buf).is_err()); - assert!(buf == vec![8, 9, 10, 11]); + assert_eq!(buf, [8, 9, 10, 11]); } #[test] @@ -379,7 +379,7 @@ mod test { }; let mut buf = vec![8, 9]; assert!(reader.push_at_least(4, 4, &mut buf).is_err()); - assert!(buf == vec![8, 9, 10]); + assert_eq!(buf, [8, 9, 10]); } #[test] @@ -388,7 +388,7 @@ mod test { count: 0, }; let buf = reader.read_to_end().unwrap(); - assert!(buf == vec!(10, 11, 12, 13)); + assert_eq!(buf, [10, 11, 12, 13]); } #[test] @@ -398,7 +398,7 @@ mod test { count: 0, }; let buf = reader.read_to_end().unwrap(); - assert!(buf == vec!(10, 11)); + assert_eq!(buf, [10, 11]); } #[test] diff --git a/src/libstd/old_io/mem.rs b/src/libstd/old_io/mem.rs index 1fd527014a3d6..c08a2c1f477b3 100644 --- a/src/libstd/old_io/mem.rs +++ b/src/libstd/old_io/mem.rs @@ -60,7 +60,7 @@ impl Writer for Vec { /// let mut w = MemWriter::new(); /// w.write(&[0, 1, 2]); /// -/// assert_eq!(w.into_inner(), vec!(0, 1, 2)); +/// assert_eq!(w.into_inner(), [0, 1, 2]); /// ``` #[unstable(feature = "io")] #[deprecated(since = "1.0.0", @@ -118,7 +118,7 @@ impl Writer for MemWriter { /// /// let mut r = MemReader::new(vec!(0, 1, 2)); /// -/// assert_eq!(r.read_to_end().unwrap(), vec!(0, 1, 2)); +/// assert_eq!(r.read_to_end().unwrap(), [0, 1, 2]); /// ``` pub struct MemReader { buf: Vec, @@ -321,7 +321,7 @@ impl<'a> Seek for BufWriter<'a> { /// let buf = [0, 1, 2, 3]; /// let mut r = BufReader::new(&buf); /// -/// assert_eq!(r.read_to_end().unwrap(), vec![0, 1, 2, 3]); +/// assert_eq!(r.read_to_end().unwrap(), [0, 1, 2, 3]); /// ``` pub struct BufReader<'a> { buf: &'a [u8], @@ -504,8 +504,8 @@ mod test { assert_eq!(&buf[..3], b); assert!(reader.read(&mut buf).is_err()); let mut reader = MemReader::new(vec!(0, 1, 2, 3, 4, 5, 6, 7)); - assert_eq!(reader.read_until(3).unwrap(), vec!(0, 1, 2, 3)); - assert_eq!(reader.read_until(3).unwrap(), vec!(4, 5, 6, 7)); + assert_eq!(reader.read_until(3).unwrap(), [0, 1, 2, 3]); + assert_eq!(reader.read_until(3).unwrap(), [4, 5, 6, 7]); assert!(reader.read(&mut buf).is_err()); } @@ -530,8 +530,8 @@ mod test { assert_eq!(&buf[..3], b); assert!(reader.read(&mut buf).is_err()); let mut reader = &mut &*in_buf; - assert_eq!(reader.read_until(3).unwrap(), vec!(0, 1, 2, 3)); - assert_eq!(reader.read_until(3).unwrap(), vec!(4, 5, 6, 7)); + assert_eq!(reader.read_until(3).unwrap(), [0, 1, 2, 3]); + assert_eq!(reader.read_until(3).unwrap(), [4, 5, 6, 7]); assert!(reader.read(&mut buf).is_err()); } @@ -557,8 +557,8 @@ mod test { assert_eq!(&buf[..3], b); assert!(reader.read(&mut buf).is_err()); let mut reader = BufReader::new(&in_buf); - assert_eq!(reader.read_until(3).unwrap(), vec!(0, 1, 2, 3)); - assert_eq!(reader.read_until(3).unwrap(), vec!(4, 5, 6, 7)); + assert_eq!(reader.read_until(3).unwrap(), [0, 1, 2, 3]); + assert_eq!(reader.read_until(3).unwrap(), [4, 5, 6, 7]); assert!(reader.read(&mut buf).is_err()); } diff --git a/src/libstd/old_io/result.rs b/src/libstd/old_io/result.rs index f42cb6ce8c97b..cdf2bae1cbad3 100644 --- a/src/libstd/old_io/result.rs +++ b/src/libstd/old_io/result.rs @@ -87,7 +87,7 @@ mod test { let mut writer: old_io::IoResult> = Ok(Vec::new()); writer.write_all(&[0, 1, 2]).unwrap(); writer.flush().unwrap(); - assert_eq!(writer.unwrap(), vec!(0, 1, 2)); + assert_eq!(writer.unwrap(), [0, 1, 2]); } #[test] diff --git a/src/libstd/old_io/util.rs b/src/libstd/old_io/util.rs index 5ae239014d188..8e49335ed5469 100644 --- a/src/libstd/old_io/util.rs +++ b/src/libstd/old_io/util.rs @@ -284,7 +284,7 @@ mod test { let mut r = MemReader::new(vec!(0, 1, 2)); { let mut r = LimitReader::new(r.by_ref(), 4); - assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap()); + assert_eq!([0, 1, 2], r.read_to_end().unwrap()); } } @@ -293,9 +293,9 @@ mod test { let mut r = MemReader::new(vec!(0, 1, 2)); { let mut r = LimitReader::new(r.by_ref(), 2); - assert_eq!(vec!(0, 1), r.read_to_end().unwrap()); + assert_eq!([0, 1], r.read_to_end().unwrap()); } - assert_eq!(vec!(2), r.read_to_end().unwrap()); + assert_eq!([2], r.read_to_end().unwrap()); } #[test] @@ -305,7 +305,7 @@ mod test { assert_eq!(3, r.limit()); assert_eq!(0, r.read_byte().unwrap()); assert_eq!(2, r.limit()); - assert_eq!(vec!(1, 2), r.read_to_end().unwrap()); + assert_eq!([1, 2], r.read_to_end().unwrap()); assert_eq!(0, r.limit()); } @@ -314,7 +314,7 @@ mod test { let mut r = MemReader::new(vec![0, 1, 2, 3, 4, 5]); let mut r = LimitReader::new(r.by_ref(), 1); r.consume(2); - assert_eq!(vec![], r.read_to_end().unwrap()); + assert_eq!([], r.read_to_end().unwrap()); } #[test] @@ -330,7 +330,7 @@ mod test { let mut s = ZeroReader; let mut buf = vec![1, 2, 3]; assert_eq!(s.read(&mut buf), Ok(3)); - assert_eq!(vec![0, 0, 0], buf); + assert_eq!([0, 0, 0], buf); } #[test] @@ -373,16 +373,16 @@ mod test { let rs = vec!(MemReader::new(vec!(0, 1)), MemReader::new(vec!()), MemReader::new(vec!(2, 3))); let mut r = ChainedReader::new(rs.into_iter()); - assert_eq!(vec!(0, 1, 2, 3), r.read_to_end().unwrap()); + assert_eq!([0, 1, 2, 3], r.read_to_end().unwrap()); } #[test] fn test_tee_reader() { let mut r = TeeReader::new(MemReader::new(vec!(0, 1, 2)), Vec::new()); - assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap()); + assert_eq!([0, 1, 2], r.read_to_end().unwrap()); let (_, w) = r.into_inner(); - assert_eq!(vec!(0, 1, 2), w); + assert_eq!([0, 1, 2], w); } #[test] @@ -390,7 +390,7 @@ mod test { let mut r = MemReader::new(vec!(0, 1, 2, 3, 4)); let mut w = Vec::new(); copy(&mut r, &mut w).unwrap(); - assert_eq!(vec!(0, 1, 2, 3, 4), w); + assert_eq!([0, 1, 2, 3, 4], w); } #[test] diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs index 9119a3c60d855..fb9d6fef1faa7 100644 --- a/src/libstd/sys/common/wtf8.rs +++ b/src/libstd/sys/common/wtf8.rs @@ -1202,11 +1202,11 @@ mod tests { string.code_points().map(|c| c.to_char()).collect::>() } let mut string = Wtf8Buf::from_str("é "); - assert_eq!(cp(&string), vec![Some('é'), Some(' ')]); + assert_eq!(cp(&string), [Some('é'), Some(' ')]); string.push(c(0xD83D)); - assert_eq!(cp(&string), vec![Some('é'), Some(' '), None]); + assert_eq!(cp(&string), [Some('é'), Some(' '), None]); string.push(c(0xDCA9)); - assert_eq!(cp(&string), vec![Some('é'), Some(' '), Some('💩')]); + assert_eq!(cp(&string), [Some('é'), Some(' '), Some('💩')]); } #[test] diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index bc239d0c7c269..91bfe6f32dc6c 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -2028,7 +2028,7 @@ foo_module!(); let renamed_crate = renamer.fold_crate(the_crate); let idents = crate_idents(&renamed_crate); let resolved : Vec = idents.iter().map(|id| mtwt::resolve(*id)).collect(); - assert_eq!(resolved,vec!(f_ident.name,Name(16),int_ident.name,Name(16),Name(16),Name(16))); + assert_eq!(resolved, [f_ident.name,Name(16),int_ident.name,Name(16),Name(16),Name(16)]); } // test the PatIdentRenamer; only PatIdents get renamed @@ -2044,8 +2044,6 @@ foo_module!(); let idents = crate_idents(&renamed_crate); let resolved : Vec = idents.iter().map(|id| mtwt::resolve(*id)).collect(); let x_name = x_ident.name; - assert_eq!(resolved,vec!(f_ident.name,Name(16),int_ident.name,Name(16),x_name,x_name)); + assert_eq!(resolved, [f_ident.name,Name(16),int_ident.name,Name(16),x_name,x_name]); } - - } diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs index b6563d77b8864..72431d8e6aa2c 100644 --- a/src/libsyntax/ext/mtwt.rs +++ b/src/libsyntax/ext/mtwt.rs @@ -288,19 +288,19 @@ mod tests { fn xorpush_test () { let mut s = Vec::new(); xor_push(&mut s, 14); - assert_eq!(s.clone(), vec!(14)); + assert_eq!(s.clone(), [14]); xor_push(&mut s, 14); - assert_eq!(s.clone(), Vec::new()); + assert_eq!(s.clone(), []); xor_push(&mut s, 14); - assert_eq!(s.clone(), vec!(14)); + assert_eq!(s.clone(), [14]); xor_push(&mut s, 15); - assert_eq!(s.clone(), vec!(14, 15)); + assert_eq!(s.clone(), [14, 15]); xor_push(&mut s, 16); - assert_eq!(s.clone(), vec!(14, 15, 16)); + assert_eq!(s.clone(), [14, 15, 16]); xor_push(&mut s, 16); - assert_eq!(s.clone(), vec!(14, 15)); + assert_eq!(s.clone(), [14, 15]); xor_push(&mut s, 15); - assert_eq!(s.clone(), vec!(14)); + assert_eq!(s.clone(), [14]); } fn id(n: u32, s: SyntaxContext) -> Ident { @@ -389,13 +389,13 @@ mod tests { assert_eq!(marksof_internal (EMPTY_CTXT,stopname,&t),Vec::new()); // FIXME #5074: ANF'd to dodge nested calls { let ans = unfold_marks(vec!(4,98),EMPTY_CTXT,&mut t); - assert_eq! (marksof_internal (ans,stopname,&t),vec!(4,98));} + assert_eq! (marksof_internal (ans,stopname,&t), [4, 98]);} // does xoring work? { let ans = unfold_marks(vec!(5,5,16),EMPTY_CTXT,&mut t); - assert_eq! (marksof_internal (ans,stopname,&t), vec!(16));} + assert_eq! (marksof_internal (ans,stopname,&t), [16]);} // does nested xoring work? { let ans = unfold_marks(vec!(5,10,10,5,16),EMPTY_CTXT,&mut t); - assert_eq! (marksof_internal (ans, stopname,&t), vec!(16));} + assert_eq! (marksof_internal (ans, stopname,&t), [16]);} // rename where stop doesn't match: { let chain = vec!(M(9), R(id(name1.usize() as u32, @@ -403,7 +403,7 @@ mod tests { Name(100101102)), M(14)); let ans = unfold_test_sc(chain,EMPTY_CTXT,&mut t); - assert_eq! (marksof_internal (ans, stopname, &t), vec!(9,14));} + assert_eq! (marksof_internal (ans, stopname, &t), [9, 14]);} // rename where stop does match { let name1sc = apply_mark_internal(4, EMPTY_CTXT, &mut t); let chain = vec!(M(9), @@ -411,7 +411,7 @@ mod tests { stopname), M(14)); let ans = unfold_test_sc(chain,EMPTY_CTXT,&mut t); - assert_eq! (marksof_internal (ans, stopname, &t), vec!(9)); } + assert_eq! (marksof_internal (ans, stopname, &t), [9]); } } diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs index 0a39d3809045a..90df23882a1d4 100644 --- a/src/libsyntax/util/small_vector.rs +++ b/src/libsyntax/util/small_vector.rs @@ -229,10 +229,10 @@ mod test { assert_eq!(Vec::new(), v); let v = SmallVector::one(1); - assert_eq!(vec![1], v.into_iter().collect::>()); + assert_eq!([1], v.into_iter().collect::>()); let v = SmallVector::many(vec![1, 2, 3]); - assert_eq!(vec!(1, 2, 3), v.into_iter().collect::>()); + assert_eq!([1, 2, 3], v.into_iter().collect::>()); } #[test] diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs index 0b577f8de74c2..112525fcce96e 100644 --- a/src/libterm/terminfo/parm.rs +++ b/src/libterm/terminfo/parm.rs @@ -652,15 +652,15 @@ mod test { let s = format!("%{{1}}%{{2}}%{}%d", op); let res = expand(s.as_bytes(), &[], &mut Variables::new()); assert!(res.is_ok(), res.err().unwrap()); - assert_eq!(res.unwrap(), vec!(b'0' + bs[0])); + assert_eq!(res.unwrap(), [b'0' + bs[0]]); let s = format!("%{{1}}%{{1}}%{}%d", op); let res = expand(s.as_bytes(), &[], &mut Variables::new()); assert!(res.is_ok(), res.err().unwrap()); - assert_eq!(res.unwrap(), vec!(b'0' + bs[1])); + assert_eq!(res.unwrap(), [b'0' + bs[1]]); let s = format!("%{{2}}%{{1}}%{}%d", op); let res = expand(s.as_bytes(), &[], &mut Variables::new()); assert!(res.is_ok(), res.err().unwrap()); - assert_eq!(res.unwrap(), vec!(b'0' + bs[2])); + assert_eq!(res.unwrap(), [b'0' + bs[2]]); } } diff --git a/src/test/run-pass/auto-ref-sliceable.rs b/src/test/run-pass/auto-ref-sliceable.rs index 652f21c2ae3f8..d2e9bc2efe727 100644 --- a/src/test/run-pass/auto-ref-sliceable.rs +++ b/src/test/run-pass/auto-ref-sliceable.rs @@ -23,5 +23,5 @@ pub fn main() { let mut v = vec!(1); v.push_val(2); v.push_val(3); - assert_eq!(v, vec!(1, 2, 3)); + assert_eq!(v, [1, 2, 3]); } diff --git a/src/test/run-pass/coerce-reborrow-mut-vec-arg.rs b/src/test/run-pass/coerce-reborrow-mut-vec-arg.rs index f87f2e07c9de0..2473b4b674e57 100644 --- a/src/test/run-pass/coerce-reborrow-mut-vec-arg.rs +++ b/src/test/run-pass/coerce-reborrow-mut-vec-arg.rs @@ -22,5 +22,5 @@ fn bar(v: &mut [uint]) { pub fn main() { let mut the_vec = vec!(1, 2, 3, 100); bar(&mut the_vec); - assert_eq!(the_vec, vec!(100, 3, 2, 1)); + assert_eq!(the_vec, [100, 3, 2, 1]); } diff --git a/src/test/run-pass/coerce-reborrow-mut-vec-rcvr.rs b/src/test/run-pass/coerce-reborrow-mut-vec-rcvr.rs index 4f97e6a20815d..ea09bb3904de6 100644 --- a/src/test/run-pass/coerce-reborrow-mut-vec-rcvr.rs +++ b/src/test/run-pass/coerce-reborrow-mut-vec-rcvr.rs @@ -18,5 +18,5 @@ fn bar(v: &mut [uint]) { pub fn main() { let mut the_vec = vec!(1, 2, 3, 100); bar(&mut the_vec); - assert_eq!(the_vec, vec!(100, 3, 2, 1)); + assert_eq!(the_vec, [100, 3, 2, 1]); } diff --git a/src/test/run-pass/generic-static-methods.rs b/src/test/run-pass/generic-static-methods.rs index 7f84efcdd5de8..010f54dd55934 100644 --- a/src/test/run-pass/generic-static-methods.rs +++ b/src/test/run-pass/generic-static-methods.rs @@ -24,5 +24,5 @@ impl vec_utils for Vec { } pub fn main() { - assert_eq!(vec_utils::map_(&vec!(1,2,3), |&x| x+1), vec!(2,3,4)); + assert_eq!(vec_utils::map_(&vec!(1,2,3), |&x| x+1), [2,3,4]); } diff --git a/src/test/run-pass/monad.rs b/src/test/run-pass/monad.rs index 457c0a35fd70f..0d563f1a714c3 100644 --- a/src/test/run-pass/monad.rs +++ b/src/test/run-pass/monad.rs @@ -44,11 +44,11 @@ fn transform(x: Option) -> Option { pub fn main() { assert_eq!(transform(Some(10)), Some("11".to_string())); assert_eq!(transform(None), None); - assert!((vec!("hi".to_string())) + assert_eq!((vec!("hi".to_string())) .bind(|x| vec!(x.clone(), format!("{}!", x)) ) - .bind(|x| vec!(x.clone(), format!("{}?", x)) ) == - vec!("hi".to_string(), - "hi?".to_string(), - "hi!".to_string(), - "hi!?".to_string())); + .bind(|x| vec!(x.clone(), format!("{}?", x)) ), + ["hi".to_string(), + "hi?".to_string(), + "hi!".to_string(), + "hi!?".to_string()]); } diff --git a/src/test/run-pass/trait-generic.rs b/src/test/run-pass/trait-generic.rs index 5f4b18df6e16b..0dedf621a4f28 100644 --- a/src/test/run-pass/trait-generic.rs +++ b/src/test/run-pass/trait-generic.rs @@ -44,9 +44,9 @@ fn bar>(x: T) -> Vec { } pub fn main() { - assert_eq!(foo(vec!(1)), vec!("hi".to_string())); - assert_eq!(bar:: >(vec!(4, 5)), vec!("4".to_string(), "5".to_string())); + assert_eq!(foo(vec!(1)), ["hi".to_string()]); + assert_eq!(bar:: >(vec!(4, 5)), ["4".to_string(), "5".to_string()]); assert_eq!(bar:: >(vec!("x".to_string(), "y".to_string())), - vec!("x".to_string(), "y".to_string())); - assert_eq!(bar::<(), Vec<()>>(vec!(())), vec!("()".to_string())); + ["x".to_string(), "y".to_string()]); + assert_eq!(bar::<(), Vec<()>>(vec!(())), ["()".to_string()]); } diff --git a/src/test/run-pass/unboxed-closures-infer-upvar.rs b/src/test/run-pass/unboxed-closures-infer-upvar.rs index 087ef5dcf05e4..1401fe7470b0a 100644 --- a/src/test/run-pass/unboxed-closures-infer-upvar.rs +++ b/src/test/run-pass/unboxed-closures-infer-upvar.rs @@ -18,5 +18,5 @@ fn f(mut f: F) { fn main() { let mut v: Vec<_> = vec![]; f(|| v.push(0)); - assert_eq!(v, vec![0]); + assert_eq!(v, [0]); } From c11807d32a0dd9e386e73c106f90da04c27c65cc Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 24 Feb 2015 23:42:09 +0300 Subject: [PATCH 18/39] Fix broken tests --- src/libcollections/vec_deque.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index 9476b98eb82c6..02927719d41b9 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -2868,17 +2868,17 @@ mod tests { // normal append a.append(&mut b); - assert_eq!(a.iter().cloned().collect(), [1, 2, 3, 4, 5, 6]); - assert_eq!(b.iter().cloned().collect(), []); + assert_eq!(a.iter().cloned().collect::>(), [1, 2, 3, 4, 5, 6]); + assert_eq!(b.iter().cloned().collect::>(), []); // append nothing to something a.append(&mut b); - assert_eq!(a.iter().cloned().collect(), [1, 2, 3, 4, 5, 6]); - assert_eq!(b.iter().cloned().collect(), []); + assert_eq!(a.iter().cloned().collect::>(), [1, 2, 3, 4, 5, 6]); + assert_eq!(b.iter().cloned().collect::>(), []); // append something to nothing b.append(&mut a); - assert_eq!(b.iter().cloned().collect(), [1, 2, 3, 4, 5, 6]); - assert_eq!(a.iter().cloned().collect(), []); + assert_eq!(b.iter().cloned().collect::>(), [1, 2, 3, 4, 5, 6]); + assert_eq!(a.iter().cloned().collect::>(), []); } } From ab45694198356ae78972025e0d3beece297431d1 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 23 Feb 2015 11:39:16 -0800 Subject: [PATCH 19/39] std: Stabilize some `ptr` functions Specifically, the following actions were taken: * The `copy_memory` and `copy_nonoverlapping_memory` functions to drop the `_memory` suffix (as it's implied by the functionality). Both functions are now marked as `#[stable]`. * The `set_memory` function was renamed to `write_bytes` and is now stable. * The `zero_memory` function is now deprecated in favor of `write_bytes` directly. * The `Unique` pointer type is now behind its own feature gate called `unique` to facilitate future stabilization. * All type parameters now are `T: ?Sized` wherever possible and new clauses were added to the `offset` functions to require that the type is sized. [breaking-change] --- src/liballoc/lib.rs | 1 + src/libcollections/btree/node.rs | 24 +++--- src/libcollections/lib.rs | 1 + src/libcollections/slice.rs | 26 +++---- src/libcollections/string.rs | 18 ++--- src/libcollections/vec.rs | 10 +-- src/libcollections/vec_deque.rs | 22 +++--- src/libcore/intrinsics.rs | 7 +- src/libcore/mem.rs | 6 +- src/libcore/ptr.rs | 109 ++++++++++++++------------- src/libcore/slice.rs | 8 +- src/libflate/lib.rs | 1 + src/libstd/collections/hash/table.rs | 8 +- src/libstd/io/buffered.rs | 6 +- src/libstd/lib.rs | 1 + 15 files changed, 126 insertions(+), 122 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 0cdc71b6f604f..82bd13475c74e 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -73,6 +73,7 @@ #![feature(unboxed_closures)] #![feature(unsafe_no_drop_flag)] #![feature(core)] +#![feature(unique)] #![cfg_attr(test, feature(test, alloc, rustc_private))] #![cfg_attr(all(not(feature = "external_funcs"), not(feature = "external_crate")), feature(libc))] diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index f0fc12da7275e..b8703f6e7d935 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -1136,12 +1136,12 @@ impl Node { // This must be followed by insert_edge on an internal node. #[inline] unsafe fn insert_kv(&mut self, index: usize, key: K, val: V) -> &mut V { - ptr::copy_memory( + ptr::copy( self.keys_mut().as_mut_ptr().offset(index as isize + 1), self.keys().as_ptr().offset(index as isize), self.len() - index ); - ptr::copy_memory( + ptr::copy( self.vals_mut().as_mut_ptr().offset(index as isize + 1), self.vals().as_ptr().offset(index as isize), self.len() - index @@ -1158,7 +1158,7 @@ impl Node { // This can only be called immediately after a call to insert_kv. #[inline] unsafe fn insert_edge(&mut self, index: usize, edge: Node) { - ptr::copy_memory( + ptr::copy( self.edges_mut().as_mut_ptr().offset(index as isize + 1), self.edges().as_ptr().offset(index as isize), self.len() - index @@ -1191,12 +1191,12 @@ impl Node { let key = ptr::read(self.keys().get_unchecked(index)); let val = ptr::read(self.vals().get_unchecked(index)); - ptr::copy_memory( + ptr::copy( self.keys_mut().as_mut_ptr().offset(index as isize), self.keys().as_ptr().offset(index as isize + 1), self.len() - index - 1 ); - ptr::copy_memory( + ptr::copy( self.vals_mut().as_mut_ptr().offset(index as isize), self.vals().as_ptr().offset(index as isize + 1), self.len() - index - 1 @@ -1212,7 +1212,7 @@ impl Node { unsafe fn remove_edge(&mut self, index: usize) -> Node { let edge = ptr::read(self.edges().get_unchecked(index)); - ptr::copy_memory( + ptr::copy( self.edges_mut().as_mut_ptr().offset(index as isize), self.edges().as_ptr().offset(index as isize + 1), self.len() - index + 1 @@ -1239,18 +1239,18 @@ impl Node { unsafe { right._len = self.len() / 2; let right_offset = self.len() - right.len(); - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( right.keys_mut().as_mut_ptr(), self.keys().as_ptr().offset(right_offset as isize), right.len() ); - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( right.vals_mut().as_mut_ptr(), self.vals().as_ptr().offset(right_offset as isize), right.len() ); if !self.is_leaf() { - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( right.edges_mut().as_mut_ptr(), self.edges().as_ptr().offset(right_offset as isize), right.len() + 1 @@ -1280,18 +1280,18 @@ impl Node { ptr::write(self.keys_mut().get_unchecked_mut(old_len), key); ptr::write(self.vals_mut().get_unchecked_mut(old_len), val); - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( self.keys_mut().as_mut_ptr().offset(old_len as isize + 1), right.keys().as_ptr(), right.len() ); - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( self.vals_mut().as_mut_ptr().offset(old_len as isize + 1), right.vals().as_ptr(), right.len() ); if !self.is_leaf() { - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( self.edges_mut().as_mut_ptr().offset(old_len as isize + 1), right.edges().as_ptr(), right.len() + 1 diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 1f3c54a4cb53f..7b66bfee34f21 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -30,6 +30,7 @@ #![feature(unboxed_closures)] #![feature(unicode)] #![feature(unsafe_destructor)] +#![feature(unique)] #![feature(unsafe_no_drop_flag)] #![cfg_attr(test, feature(rand, rustc_private, test))] #![cfg_attr(test, allow(deprecated))] // rand diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 4b2b125fc99f2..8ca60d717f4df 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -1331,12 +1331,10 @@ fn insertion_sort(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> O if i != j { let tmp = ptr::read(read_ptr); - ptr::copy_memory(buf_v.offset(j + 1), - &*buf_v.offset(j), - (i - j) as usize); - ptr::copy_nonoverlapping_memory(buf_v.offset(j), - &tmp, - 1); + ptr::copy(buf_v.offset(j + 1), + &*buf_v.offset(j), + (i - j) as usize); + ptr::copy_nonoverlapping(buf_v.offset(j), &tmp, 1); mem::forget(tmp); } } @@ -1409,10 +1407,10 @@ fn merge_sort(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order // j + 1 could be `len` (for the last `i`), but in // that case, `i == j` so we don't copy. The // `.offset(j)` is always in bounds. - ptr::copy_memory(buf_dat.offset(j + 1), - &*buf_dat.offset(j), - i - j as usize); - ptr::copy_nonoverlapping_memory(buf_dat.offset(j), read_ptr, 1); + ptr::copy(buf_dat.offset(j + 1), + &*buf_dat.offset(j), + i - j as usize); + ptr::copy_nonoverlapping(buf_dat.offset(j), read_ptr, 1); } } } @@ -1460,11 +1458,11 @@ fn merge_sort(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order if left == right_start { // the number remaining in this run. let elems = (right_end as usize - right as usize) / mem::size_of::(); - ptr::copy_nonoverlapping_memory(out, &*right, elems); + ptr::copy_nonoverlapping(out, &*right, elems); break; } else if right == right_end { let elems = (right_start as usize - left as usize) / mem::size_of::(); - ptr::copy_nonoverlapping_memory(out, &*left, elems); + ptr::copy_nonoverlapping(out, &*left, elems); break; } @@ -1478,7 +1476,7 @@ fn merge_sort(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order } else { step(&mut left) }; - ptr::copy_nonoverlapping_memory(out, &*to_copy, 1); + ptr::copy_nonoverlapping(out, &*to_copy, 1); step(&mut out); } } @@ -1492,7 +1490,7 @@ fn merge_sort(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order // write the result to `v` in one go, so that there are never two copies // of the same object in `v`. unsafe { - ptr::copy_nonoverlapping_memory(v.as_mut_ptr(), &*buf_dat, len); + ptr::copy_nonoverlapping(v.as_mut_ptr(), &*buf_dat, len); } // increment the pointer, returning the old pointer. diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 6c2624cd204de..e141a49002b2e 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -568,9 +568,9 @@ impl String { let CharRange { ch, next } = self.char_range_at(idx); unsafe { - ptr::copy_memory(self.vec.as_mut_ptr().offset(idx as isize), - self.vec.as_ptr().offset(next as isize), - len - next); + ptr::copy(self.vec.as_mut_ptr().offset(idx as isize), + self.vec.as_ptr().offset(next as isize), + len - next); self.vec.set_len(len - (next - idx)); } ch @@ -598,12 +598,12 @@ impl String { let amt = ch.encode_utf8(&mut bits).unwrap(); unsafe { - ptr::copy_memory(self.vec.as_mut_ptr().offset((idx + amt) as isize), - self.vec.as_ptr().offset(idx as isize), - len - idx); - ptr::copy_memory(self.vec.as_mut_ptr().offset(idx as isize), - bits.as_ptr(), - amt); + ptr::copy(self.vec.as_mut_ptr().offset((idx + amt) as isize), + self.vec.as_ptr().offset(idx as isize), + len - idx); + ptr::copy(self.vec.as_mut_ptr().offset(idx as isize), + bits.as_ptr(), + amt); self.vec.set_len(len + amt); } } diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 3f5f92889166f..8097b94cd3df4 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -267,7 +267,7 @@ impl Vec { pub unsafe fn from_raw_buf(ptr: *const T, elts: usize) -> Vec { let mut dst = Vec::with_capacity(elts); dst.set_len(elts); - ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(), ptr, elts); + ptr::copy_nonoverlapping(dst.as_mut_ptr(), ptr, elts); dst } @@ -548,7 +548,7 @@ impl Vec { let p = self.as_mut_ptr().offset(index as isize); // Shift everything over to make space. (Duplicating the // `index`th element into two consecutive places.) - ptr::copy_memory(p.offset(1), &*p, len - index); + ptr::copy(p.offset(1), &*p, len - index); // Write it in, overwriting the first copy of the `index`th // element. ptr::write(&mut *p, element); @@ -585,7 +585,7 @@ impl Vec { ret = ptr::read(ptr); // Shift everything down to fill in that spot. - ptr::copy_memory(ptr, &*ptr.offset(1), len - index - 1); + ptr::copy(ptr, &*ptr.offset(1), len - index - 1); } self.set_len(len - 1); ret @@ -718,7 +718,7 @@ impl Vec { self.reserve(other.len()); let len = self.len(); unsafe { - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( self.get_unchecked_mut(len), other.as_ptr(), other.len()); @@ -1036,7 +1036,7 @@ impl Vec { self.set_len(at); other.set_len(other_len); - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( other.as_mut_ptr(), self.as_ptr().offset(at as isize), other.len()); diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index f65e644fa5284..a7e93c4044745 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -134,7 +134,7 @@ impl VecDeque { self.cap); debug_assert!(src + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len, self.cap); - ptr::copy_memory( + ptr::copy( self.ptr.offset(dst as isize), self.ptr.offset(src as isize), len); @@ -147,7 +147,7 @@ impl VecDeque { self.cap); debug_assert!(src + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len, self.cap); - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( self.ptr.offset(dst as isize), self.ptr.offset(src as isize), len); @@ -1343,22 +1343,22 @@ impl VecDeque { // `at` lies in the first half. let amount_in_first = first_len - at; - ptr::copy_nonoverlapping_memory(*other.ptr, - first_half.as_ptr().offset(at as isize), - amount_in_first); + ptr::copy_nonoverlapping(*other.ptr, + first_half.as_ptr().offset(at as isize), + amount_in_first); // just take all of the second half. - ptr::copy_nonoverlapping_memory(other.ptr.offset(amount_in_first as isize), - second_half.as_ptr(), - second_len); + ptr::copy_nonoverlapping(other.ptr.offset(amount_in_first as isize), + second_half.as_ptr(), + second_len); } else { // `at` lies in the second half, need to factor in the elements we skipped // in the first half. let offset = at - first_len; let amount_in_second = second_len - offset; - ptr::copy_nonoverlapping_memory(*other.ptr, - second_half.as_ptr().offset(offset as isize), - amount_in_second); + ptr::copy_nonoverlapping(*other.ptr, + second_half.as_ptr().offset(offset as isize), + amount_in_second); } } diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index b2ee95963878e..e7af0be88a085 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -293,7 +293,7 @@ extern "rust-intrinsic" { /// } /// } /// ``` - #[unstable(feature = "core")] + #[stable(feature = "rust1", since = "1.0.0")] pub fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: usize); /// Copies `count * size_of` bytes from `src` to `dst`. The source @@ -323,13 +323,12 @@ extern "rust-intrinsic" { /// } /// ``` /// - #[unstable(feature = "core")] + #[stable(feature = "rust1", since = "1.0.0")] pub fn copy_memory(dst: *mut T, src: *const T, count: usize); /// Invokes memset on the specified pointer, setting `count * size_of::()` /// bytes of memory starting at `dst` to `c`. - #[unstable(feature = "core", - reason = "uncertain about naming and semantics")] + #[stable(feature = "rust1", since = "1.0.0")] pub fn set_memory(dst: *mut T, val: u8, count: usize); /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 740997b7a249d..2aa8ec0c548d9 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -203,9 +203,9 @@ pub fn swap(x: &mut T, y: &mut T) { let mut t: T = uninitialized(); // Perform the swap, `&mut` pointers never alias - ptr::copy_nonoverlapping_memory(&mut t, &*x, 1); - ptr::copy_nonoverlapping_memory(x, &*y, 1); - ptr::copy_nonoverlapping_memory(y, &t, 1); + ptr::copy_nonoverlapping(&mut t, &*x, 1); + ptr::copy_nonoverlapping(x, &*y, 1); + ptr::copy_nonoverlapping(y, &t, 1); // y and t now point to the same thing, but we need to completely forget `t` // because it's no longer relevant. diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index b44cc899787f5..0625c3c7d6018 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -101,16 +101,28 @@ use cmp::Ordering::{self, Less, Equal, Greater}; // FIXME #19649: intrinsic docs don't render, so these have no docs :( -#[unstable(feature = "core")] -pub use intrinsics::copy_nonoverlapping_memory; +#[stable(feature = "rust1", since = "1.0.0")] +pub use intrinsics::copy_nonoverlapping_memory as copy_nonoverlapping; -#[unstable(feature = "core")] -pub use intrinsics::copy_memory; +#[stable(feature = "rust1", since = "1.0.0")] +pub use intrinsics::copy_memory as copy; -#[unstable(feature = "core", - reason = "uncertain about naming and semantics")] -pub use intrinsics::set_memory; +#[stable(feature = "rust1", since = "1.0.0")] +pub use intrinsics::set_memory as write_bytes; +extern "rust-intrinsic" { + #[unstable(feature = "core")] + #[deprecated(since = "1.0.0", reason = "renamed to `copy_nonoverlapping`")] + pub fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: usize); + #[unstable(feature = "core")] + #[deprecated(since = "1.0.0", reason = "renamed to `copy`")] + pub fn copy_memory(dst: *mut T, src: *const T, count: usize); + + #[unstable(feature = "core", + reason = "uncertain about naming and semantics")] + #[deprecated(since = "1.0.0", reason = "renamed to `write_bytes`")] + pub fn set_memory(dst: *mut T, val: u8, count: usize); +} /// Creates a null raw pointer. /// @@ -150,8 +162,9 @@ pub fn null_mut() -> *mut T { 0 as *mut T } #[inline] #[unstable(feature = "core", reason = "may play a larger role in std::ptr future extensions")] +#[deprecated(since = "1.0.0", reason = "use `write_bytes` instead")] pub unsafe fn zero_memory(dst: *mut T, count: usize) { - set_memory(dst, 0, count); + write_bytes(dst, 0, count); } /// Swaps the values at two mutable locations of the same type, without @@ -169,9 +182,9 @@ pub unsafe fn swap(x: *mut T, y: *mut T) { let t: *mut T = &mut tmp; // Perform the swap - copy_nonoverlapping_memory(t, &*x, 1); - copy_memory(x, &*y, 1); // `x` and `y` may overlap - copy_nonoverlapping_memory(y, &*t, 1); + copy_nonoverlapping(t, &*x, 1); + copy(x, &*y, 1); // `x` and `y` may overlap + copy_nonoverlapping(y, &*t, 1); // y and t now point to the same thing, but we need to completely forget `tmp` // because it's no longer relevant. @@ -207,7 +220,7 @@ pub unsafe fn replace(dest: *mut T, mut src: T) -> T { #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn read(src: *const T) -> T { let mut tmp: T = mem::uninitialized(); - copy_nonoverlapping_memory(&mut tmp, src, 1); + copy_nonoverlapping(&mut tmp, src, 1); tmp } @@ -224,7 +237,7 @@ pub unsafe fn read_and_zero(dest: *mut T) -> T { let tmp = read(&*dest); // Now zero out `dest`: - zero_memory(dest, 1); + write_bytes(dest, 0, 1); tmp } @@ -248,9 +261,9 @@ pub unsafe fn write(dst: *mut T, src: T) { /// Methods on raw pointers #[stable(feature = "rust1", since = "1.0.0")] -pub trait PtrExt: Sized { +pub trait PtrExt { /// The type which is being pointed at - type Target; + type Target: ?Sized; /// Returns true if the pointer is null. #[stable(feature = "rust1", since = "1.0.0")] @@ -279,14 +292,14 @@ pub trait PtrExt: Sized { /// Otherwise `offset` invokes Undefined Behaviour, regardless of whether /// the pointer is used. #[stable(feature = "rust1", since = "1.0.0")] - unsafe fn offset(self, count: isize) -> Self; + unsafe fn offset(self, count: isize) -> Self where Self::Target: Sized; } /// Methods on mutable raw pointers #[stable(feature = "rust1", since = "1.0.0")] pub trait MutPtrExt { /// The type which is being pointed at - type Target; + type Target: ?Sized; /// Returns `None` if the pointer is null, or else returns a mutable /// reference to the value wrapped in `Some`. @@ -302,7 +315,7 @@ pub trait MutPtrExt { } #[stable(feature = "rust1", since = "1.0.0")] -impl PtrExt for *const T { +impl PtrExt for *const T { type Target = T; #[inline] @@ -311,7 +324,7 @@ impl PtrExt for *const T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] - unsafe fn offset(self, count: isize) -> *const T { + unsafe fn offset(self, count: isize) -> *const T where T: Sized { intrinsics::offset(self, count) } @@ -329,7 +342,7 @@ impl PtrExt for *const T { } #[stable(feature = "rust1", since = "1.0.0")] -impl PtrExt for *mut T { +impl PtrExt for *mut T { type Target = T; #[inline] @@ -338,7 +351,7 @@ impl PtrExt for *mut T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] - unsafe fn offset(self, count: isize) -> *mut T { + unsafe fn offset(self, count: isize) -> *mut T where T: Sized { intrinsics::offset(self, count) as *mut T } @@ -356,7 +369,7 @@ impl PtrExt for *mut T { } #[stable(feature = "rust1", since = "1.0.0")] -impl MutPtrExt for *mut T { +impl MutPtrExt for *mut T { type Target = T; #[inline] @@ -374,33 +387,25 @@ impl MutPtrExt for *mut T { // Equality for pointers #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for *const T { +impl PartialEq for *const T { #[inline] - fn eq(&self, other: &*const T) -> bool { - *self == *other - } - #[inline] - fn ne(&self, other: &*const T) -> bool { !self.eq(other) } + fn eq(&self, other: &*const T) -> bool { *self == *other } } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for *const T {} +impl Eq for *const T {} #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for *mut T { - #[inline] - fn eq(&self, other: &*mut T) -> bool { - *self == *other - } +impl PartialEq for *mut T { #[inline] - fn ne(&self, other: &*mut T) -> bool { !self.eq(other) } + fn eq(&self, other: &*mut T) -> bool { *self == *other } } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for *mut T {} +impl Eq for *mut T {} #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for *const T { +impl Clone for *const T { #[inline] fn clone(&self) -> *const T { *self @@ -408,7 +413,7 @@ impl Clone for *const T { } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for *mut T { +impl Clone for *mut T { #[inline] fn clone(&self) -> *mut T { *self @@ -452,7 +457,7 @@ mod externfnpointers { // Comparison for pointers #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for *const T { +impl Ord for *const T { #[inline] fn cmp(&self, other: &*const T) -> Ordering { if self < other { @@ -466,7 +471,7 @@ impl Ord for *const T { } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for *const T { +impl PartialOrd for *const T { #[inline] fn partial_cmp(&self, other: &*const T) -> Option { Some(self.cmp(other)) @@ -486,7 +491,7 @@ impl PartialOrd for *const T { } #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for *mut T { +impl Ord for *mut T { #[inline] fn cmp(&self, other: &*mut T) -> Ordering { if self < other { @@ -500,7 +505,7 @@ impl Ord for *mut T { } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for *mut T { +impl PartialOrd for *mut T { #[inline] fn partial_cmp(&self, other: &*mut T) -> Option { Some(self.cmp(other)) @@ -527,8 +532,8 @@ impl PartialOrd for *mut T { /// modified without a unique path to the `Unique` reference. Useful /// for building abstractions like `Vec` or `Box`, which /// internally use raw pointers to manage the memory that they own. -#[unstable(feature = "core", reason = "recently added to this module")] -pub struct Unique { +#[unstable(feature = "unique")] +pub struct Unique { pointer: NonZero<*const T>, _marker: PhantomData, } @@ -537,39 +542,37 @@ pub struct Unique { /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the /// `Unique` must enforce it. -#[unstable(feature = "core", reason = "recently added to this module")] +#[unstable(feature = "unique")] unsafe impl Send for Unique { } /// `Unique` pointers are `Sync` if `T` is `Sync` because the data they /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the /// `Unique` must enforce it. -#[unstable(feature = "core", reason = "recently added to this module")] +#[unstable(feature = "unique")] unsafe impl Sync for Unique { } -impl Unique { +impl Unique { /// Create a new `Unique`. - #[unstable(feature = "core", - reason = "recently added to this module")] + #[unstable(feature = "unique")] pub unsafe fn new(ptr: *mut T) -> Unique { Unique { pointer: NonZero::new(ptr as *const T), _marker: PhantomData } } /// Dereference the content. - #[unstable(feature = "core", - reason = "recently added to this module")] + #[unstable(feature = "unique")] pub unsafe fn get(&self) -> &T { &**self.pointer } /// Mutably dereference the content. - #[unstable(feature = "core", - reason = "recently added to this module")] + #[unstable(feature = "unique")] pub unsafe fn get_mut(&mut self) -> &mut T { &mut ***self } } +#[unstable(feature = "unique")] impl Deref for Unique { type Target = *mut T; diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 2debcaa581342..ae64a57a390f8 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -1500,7 +1500,7 @@ pub mod bytes { impl MutableByteVector for [u8] { #[inline] fn set_memory(&mut self, value: u8) { - unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) }; + unsafe { ptr::write_bytes(self.as_mut_ptr(), value, self.len()) }; } } @@ -1514,9 +1514,9 @@ pub mod bytes { // `dst` is unaliasable, so we know statically it doesn't overlap // with `src`. unsafe { - ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(), - src.as_ptr(), - len_src); + ptr::copy_nonoverlapping(dst.as_mut_ptr(), + src.as_ptr(), + len_src); } } } diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index 24660b3f396c1..2ce52cdec2560 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -27,6 +27,7 @@ #![feature(int_uint)] #![feature(libc)] #![feature(staged_api)] +#![feature(unique)] #[cfg(test)] #[macro_use] extern crate log; diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 7513cb8a61c7c..4c03d8915eb8a 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -23,7 +23,7 @@ use num::{Int, UnsignedInt}; use ops::{Deref, DerefMut, Drop}; use option::Option; use option::Option::{Some, None}; -use ptr::{self, PtrExt, copy_nonoverlapping_memory, Unique, zero_memory}; +use ptr::{self, PtrExt, Unique}; use rt::heap::{allocate, deallocate, EMPTY}; use collections::hash_state::HashState; @@ -477,8 +477,8 @@ impl>> GapThenFull { pub fn shift(mut self) -> Option> { unsafe { *self.gap.raw.hash = mem::replace(&mut *self.full.raw.hash, EMPTY_BUCKET); - copy_nonoverlapping_memory(self.gap.raw.key, self.full.raw.key, 1); - copy_nonoverlapping_memory(self.gap.raw.val, self.full.raw.val, 1); + ptr::copy_nonoverlapping(self.gap.raw.key, self.full.raw.key, 1); + ptr::copy_nonoverlapping(self.gap.raw.val, self.full.raw.val, 1); } let FullBucket { raw: prev_raw, idx: prev_idx, .. } = self.full; @@ -637,7 +637,7 @@ impl RawTable { pub fn new(capacity: usize) -> RawTable { unsafe { let ret = RawTable::new_uninitialized(capacity); - zero_memory(*ret.hashes, capacity); + ptr::write_bytes(*ret.hashes, 0, capacity); ret } } diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 9ef319782369d..6458dfc5aa242 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -155,9 +155,9 @@ impl BufWriter { if written > 0 { // NB: would be better expressed as .remove(0..n) if it existed unsafe { - ptr::copy_memory(self.buf.as_mut_ptr(), - self.buf.as_ptr().offset(written as isize), - len - written); + ptr::copy(self.buf.as_mut_ptr(), + self.buf.as_ptr().offset(written as isize), + len - written); } } self.buf.truncate(len - written); diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index caaedeeb2fc54..b5bdeb7f181b0 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -123,6 +123,7 @@ #![feature(unsafe_no_drop_flag)] #![feature(macro_reexport)] #![feature(hash)] +#![feature(unique)] #![cfg_attr(test, feature(test, rustc_private, env))] // Don't link to std. We are std. From 27f8708ba4aac3f4f2d3074b7b4a451774b1a813 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 24 Feb 2015 14:24:15 -0800 Subject: [PATCH 20/39] std: Recomend threadpool on crates.io for TaskPool --- src/libstd/sync/task_pool.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/sync/task_pool.rs b/src/libstd/sync/task_pool.rs index 2bc51e340c034..83e4c6c2e3bdb 100644 --- a/src/libstd/sync/task_pool.rs +++ b/src/libstd/sync/task_pool.rs @@ -12,8 +12,8 @@ #![deprecated(since = "1.0.0", reason = "This kind of API needs some time to bake in \ - crates.io. Consider trying \ - https://github.com/carllerche/syncbox")] + crates.io. This functionality is available through \ + https://crates.io/crates/threadpool")] #![unstable(feature = "std_misc")] use core::prelude::*; From 14c76834fe06e011c87055ee56dfe08f8a3d83f5 Mon Sep 17 00:00:00 2001 From: Raphael Nestler Date: Tue, 24 Feb 2015 23:26:25 +0100 Subject: [PATCH 21/39] Fix "How to submit a bug report" link According to #22650 and bb0bbf639eafdd79380a3b1e2e92263a2aa914f9 the link changed --- src/doc/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/index.md b/src/doc/index.md index a4f7941222018..f6b0a18824a02 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -68,7 +68,7 @@ There are questions that are asked quite often, and so we've made FAQs for them: * [Language Design FAQ](complement-design-faq.html) * [Language FAQ](complement-lang-faq.html) * [Project FAQ](complement-project-faq.html) -* [How to submit a bug report](complement-bugreport.html) +* [How to submit a bug report](https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports) # The standard library From 408f7b57470d1761297e1490a38ecb79ad6e4657 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Tue, 10 Feb 2015 22:12:13 +0100 Subject: [PATCH 22/39] Modify collection's `Debug` output to resemble in their content only --- src/libcollections/bit.rs | 6 +++--- src/libcollections/enum_set.rs | 8 ++++---- src/libcollections/linked_list.rs | 6 +++--- src/libcollections/vec_deque.rs | 6 +++--- src/libcollections/vec_map.rs | 6 +++--- src/libstd/collections/hash/map.rs | 8 ++++---- src/libstd/collections/hash/set.rs | 6 +++--- src/test/run-pass/issue-3559.rs | 4 ++-- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index f28f9976f0c5d..f2447abf42cd7 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -978,7 +978,7 @@ impl Ord for BitVec { impl fmt::Debug for BitVec { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { for bit in self { - try!(write!(fmt, "{}", if bit { 1u32 } else { 0u32 })); + try!(write!(fmt, "{}", if bit { 1 } else { 0 })); } Ok(()) } @@ -1752,7 +1752,7 @@ impl BitSet { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for BitSet { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - try!(write!(fmt, "BitSet {{")); + try!(write!(fmt, "{{")); let mut first = true; for n in self { if !first { @@ -2655,7 +2655,7 @@ mod bit_set_test { s.insert(10); s.insert(50); s.insert(2); - assert_eq!("BitSet {1, 2, 10, 50}", format!("{:?}", s)); + assert_eq!("{1, 2, 10, 50}", format!("{:?}", s)); } #[test] diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index 0c95742606083..bc14093ffa2c9 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -36,7 +36,7 @@ impl Copy for EnumSet {} #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for EnumSet { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - try!(write!(fmt, "EnumSet {{")); + try!(write!(fmt, "{{")); let mut first = true; for e in self { if !first { @@ -314,11 +314,11 @@ mod test { #[test] fn test_show() { let mut e = EnumSet::new(); - assert!(format!("{:?}", e) == "EnumSet {}"); + assert!(format!("{:?}", e) == "{}"); e.insert(A); - assert!(format!("{:?}", e) == "EnumSet {A}"); + assert!(format!("{:?}", e) == "{A}"); e.insert(C); - assert!(format!("{:?}", e) == "EnumSet {A, C}"); + assert!(format!("{:?}", e) == "{A, C}"); } #[test] diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index 3c61fc3da90e3..c446e3d399886 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -918,7 +918,7 @@ impl Clone for LinkedList { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for LinkedList { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "LinkedList [")); + try!(write!(f, "[")); for (i, e) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -1387,10 +1387,10 @@ mod tests { #[test] fn test_show() { let list: LinkedList<_> = (0..10).collect(); - assert_eq!(format!("{:?}", list), "LinkedList [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); + assert_eq!(format!("{:?}", list), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); let list: LinkedList<_> = vec!["just", "one", "test", "more"].iter().cloned().collect(); - assert_eq!(format!("{:?}", list), "LinkedList [\"just\", \"one\", \"test\", \"more\"]"); + assert_eq!(format!("{:?}", list), "[\"just\", \"one\", \"test\", \"more\"]"); } #[cfg(test)] diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index f65e644fa5284..8b6949e02fee6 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -1754,7 +1754,7 @@ impl Extend for VecDeque { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for VecDeque { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "VecDeque [")); + try!(write!(f, "[")); for (i, e) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -2435,12 +2435,12 @@ mod tests { #[test] fn test_show() { let ringbuf: VecDeque<_> = (0..10).collect(); - assert_eq!(format!("{:?}", ringbuf), "VecDeque [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); + assert_eq!(format!("{:?}", ringbuf), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); let ringbuf: VecDeque<_> = vec!["just", "one", "test", "more"].iter() .cloned() .collect(); - assert_eq!(format!("{:?}", ringbuf), "VecDeque [\"just\", \"one\", \"test\", \"more\"]"); + assert_eq!(format!("{:?}", ringbuf), "[\"just\", \"one\", \"test\", \"more\"]"); } #[test] diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index d92249379fa8f..d2a4f6c043731 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -739,7 +739,7 @@ impl Ord for VecMap { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for VecMap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "VecMap {{")); + try!(write!(f, "{{")); for (i, (k, v)) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -1318,8 +1318,8 @@ mod test_map { map.insert(3, 4); let map_str = format!("{:?}", map); - assert!(map_str == "VecMap {1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}"); - assert_eq!(format!("{:?}", empty), "VecMap {}"); + assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}"); + assert_eq!(format!("{:?}", empty), "{}"); } #[test] diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index df2fb538c0a50..faddbba50590f 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1212,7 +1212,7 @@ impl Debug for HashMap where K: Eq + Hash + Debug, V: Debug, S: HashState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "HashMap {{")); + try!(write!(f, "{{")); for (i, (k, v)) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -1999,9 +1999,9 @@ mod test_map { let map_str = format!("{:?}", map); - assert!(map_str == "HashMap {1: 2, 3: 4}" || - map_str == "HashMap {3: 4, 1: 2}"); - assert_eq!(format!("{:?}", empty), "HashMap {}"); + assert!(map_str == "{1: 2, 3: 4}" || + map_str == "{3: 4, 1: 2}"); + assert_eq!(format!("{:?}", empty), "{}"); } #[test] diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index e0631a64d44b1..cdc0ebd76aada 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -598,7 +598,7 @@ impl fmt::Debug for HashSet S: HashState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "HashSet {{")); + try!(write!(f, "{{")); for (i, x) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -1186,8 +1186,8 @@ mod test_set { let set_str = format!("{:?}", set); - assert!(set_str == "HashSet {1, 2}" || set_str == "HashSet {2, 1}"); - assert_eq!(format!("{:?}", empty), "HashSet {}"); + assert!(set_str == "{1, 2}" || set_str == "{2, 1}"); + assert_eq!(format!("{:?}", empty), "{}"); } #[test] diff --git a/src/test/run-pass/issue-3559.rs b/src/test/run-pass/issue-3559.rs index 754412ea94938..3f1a1c75d8a78 100644 --- a/src/test/run-pass/issue-3559.rs +++ b/src/test/run-pass/issue-3559.rs @@ -24,6 +24,6 @@ pub fn main() { let mut table = HashMap::new(); table.insert("one".to_string(), 1); table.insert("two".to_string(), 2); - assert!(check_strs(&format!("{:?}", table), "HashMap {\"one\": 1, \"two\": 2}") || - check_strs(&format!("{:?}", table), "HashMap {\"two\": 2, \"one\": 1}")); + assert!(check_strs(&format!("{:?}", table), "{\"one\": 1, \"two\": 2}") || + check_strs(&format!("{:?}", table), "{\"two\": 2, \"one\": 1}")); } From 870ad3bc75ef25a01b81ff115ab307d21c738a0f Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Wed, 11 Feb 2015 00:14:48 +0100 Subject: [PATCH 23/39] Change `Debug` implementation of `BTree*` as well --- src/libcollections/btree/map.rs | 2 +- src/libcollections/btree/set.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 1b456eec830b1..9e0e7fad6be49 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -899,7 +899,7 @@ impl Ord for BTreeMap { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for BTreeMap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "BTreeMap {{")); + try!(write!(f, "{{")); for (i, (k, v)) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index 929b2f5804303..4273f9a823000 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -613,7 +613,7 @@ impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet> for &'a BTreeSet { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for BTreeSet { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "BTreeSet {{")); + try!(write!(f, "{{")); for (i, x) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -911,7 +911,7 @@ mod test { let set_str = format!("{:?}", set); - assert_eq!(set_str, "BTreeSet {1, 2}"); - assert_eq!(format!("{:?}", empty), "BTreeSet {}"); + assert_eq!(set_str, "{1, 2}"); + assert_eq!(format!("{:?}", empty), "{}"); } } From db6ae66764ddb80926b2a18672162d1706ff82a6 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 20 Feb 2015 10:18:38 -0500 Subject: [PATCH 24/39] Make traits with assoc types invariant in their inputs. --- src/librustc/middle/infer/combine.rs | 8 +--- src/librustc_typeck/variance.rs | 65 +++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs index 99cb2a0978e7e..40ccab510c4f5 100644 --- a/src/librustc/middle/infer/combine.rs +++ b/src/librustc/middle/infer/combine.rs @@ -265,13 +265,7 @@ pub trait Combine<'tcx> : Sized { Err(ty::terr_projection_name_mismatched( expected_found(self, a.item_name, b.item_name))) } else { - // Note that the trait refs for the projection must be - // *equal*. This is because there is no inherent - // relationship between `::Bar` and `::Bar` that we can derive based on how `T` relates - // to `U`. Issue #21726 contains further discussion and - // in-depth examples. - let trait_ref = try!(self.equate().trait_refs(&*a.trait_ref, &*b.trait_ref)); + let trait_ref = try!(self.trait_refs(&*a.trait_ref, &*b.trait_ref)); Ok(ty::ProjectionTy { trait_ref: Rc::new(trait_ref), item_name: a.item_name }) } } diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index 90ca6a798056b..1fba4a21ccd37 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -203,6 +203,56 @@ //! failure, but rather because the target type `Foo` is itself just //! not well-formed. Basically we get to assume well-formedness of all //! types involved before considering variance. +//! +//! ### Associated types +//! +//! Any trait with an associated type is invariant with respect to all +//! of its inputs. To see why this makes sense, consider what +//! subtyping for a trait reference means: +//! +//! <: +//! +//! means that if I know that `T as Trait`, +//! I also know that `U as +//! Trait`. Moreover, if you think of it as +//! dictionary passing style, it means that +//! a dictionary for `` is safe +//! to use where a dictionary for `` is expected. +//! +//! The problem is that when you can +//! project types out from ``, +//! the relationship to types projected out +//! of `` is completely unknown +//! unless `T==U` (see #21726 for more +//! details). Making `Trait` invariant +//! ensures that this is true. +//! +//! *Historical note: we used to preserve this invariant another way, +//! by tweaking the subtyping rules and requiring that when a type `T` +//! appeared as part of a projection, that was considered an invariant +//! location, but this version does away with the need for those +//! somewhat "special-case-feeling" rules.* +//! +//! Another related reason is that if we didn't make traits with +//! associated types invariant, then projection is no longer a +//! function with a single result. Consider: +//! +//! ``` +//! trait Identity { type Out; fn foo(&self); } +//! impl Identity for T { type Out = T; ... } +//! ``` +//! +//! Now if I have `<&'static () as Identity>::Out`, this can be +//! validly derived as `&'a ()` for any `'a`: +//! +//! <&'a () as Identity> <: <&'static () as Identity> +//! if &'static () < : &'a () -- Identity is contravariant in Self +//! if 'static : 'a -- Subtyping rules for relations +//! +//! This change otoh means that `<'static () as Identity>::Out` is +//! always `&'static ()` (which might then be upcast to `'a ()`, +//! separately). This was helpful in solving #21750. use self::VarianceTerm::*; use self::ParamKind::*; @@ -613,7 +663,18 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> { &method.fty.sig, self.covariant); } - ty::TypeTraitItem(_) => {} + ty::TypeTraitItem(ref data) => { + // Any trait with an associated type is + // invariant with respect to all of its + // inputs. See length discussion in the comment + // on this module. + let projection_ty = ty::mk_projection(tcx, + trait_def.trait_ref.clone(), + data.name); + self.add_constraints_from_ty(&trait_def.generics, + projection_ty, + self.invariant); + } } } } @@ -893,7 +954,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { trait_def.generics.types.as_slice(), trait_def.generics.regions.as_slice(), trait_ref.substs, - self.invariant); + variance); } ty::ty_trait(ref data) => { From eb841fc44a821fdfd23117b3a35958935752c857 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 20 Feb 2015 06:21:46 -0500 Subject: [PATCH 25/39] Resolve regions too when normalizing param env. --- src/librustc/middle/traits/mod.rs | 91 +++++++++++++++++-------------- 1 file changed, 50 insertions(+), 41 deletions(-) diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 8b836fd322e3c..5a5639c701291 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -18,7 +18,7 @@ pub use self::ObligationCauseCode::*; use middle::subst; use middle::ty::{self, HasProjectionTypes, Ty}; use middle::ty_fold::TypeFoldable; -use middle::infer::{self, InferCtxt}; +use middle::infer::{self, fixup_err_to_string, InferCtxt}; use std::slice::Iter; use std::rc::Rc; use syntax::ast; @@ -395,53 +395,64 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, } } +/// Normalizes the parameter environment, reporting errors if they occur. pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvironment<'a,'tcx>, cause: ObligationCause<'tcx>) -> ty::ParameterEnvironment<'a,'tcx> { - match normalize_param_env(&unnormalized_env, cause) { - Ok(p) => p, + // I'm not wild about reporting errors here; I'd prefer to + // have the errors get reported at a defined place (e.g., + // during typeck). Instead I have all parameter + // environments, in effect, going through this function + // and hence potentially reporting errors. This ensurse of + // course that we never forget to normalize (the + // alternative seemed like it would involve a lot of + // manual invocations of this fn -- and then we'd have to + // deal with the errors at each of those sites). + // + // In any case, in practice, typeck constructs all the + // parameter environments once for every fn as it goes, + // and errors will get reported then; so after typeck we + // can be sure that no errors should occur. + + let tcx = unnormalized_env.tcx; + let span = cause.span; + let body_id = cause.body_id; + + debug!("normalize_param_env_or_error(unnormalized_env={})", + unnormalized_env.repr(tcx)); + + let infcx = infer::new_infer_ctxt(tcx); + let predicates = match fully_normalize(&infcx, &unnormalized_env, cause, + &unnormalized_env.caller_bounds) { + Ok(predicates) => predicates, Err(errors) => { - // I'm not wild about reporting errors here; I'd prefer to - // have the errors get reported at a defined place (e.g., - // during typeck). Instead I have all parameter - // environments, in effect, going through this function - // and hence potentially reporting errors. This ensurse of - // course that we never forget to normalize (the - // alternative seemed like it would involve a lot of - // manual invocations of this fn -- and then we'd have to - // deal with the errors at each of those sites). - // - // In any case, in practice, typeck constructs all the - // parameter environments once for every fn as it goes, - // and errors will get reported then; so after typeck we - // can be sure that no errors should occur. - let infcx = infer::new_infer_ctxt(unnormalized_env.tcx); report_fulfillment_errors(&infcx, &errors); - - // Normalized failed? use what they gave us, it's better than nothing. - unnormalized_env + return unnormalized_env; // an unnormalized env is better than nothing } - } -} - -pub fn normalize_param_env<'a,'tcx>(param_env: &ty::ParameterEnvironment<'a,'tcx>, - cause: ObligationCause<'tcx>) - -> Result, - Vec>> -{ - let tcx = param_env.tcx; - - debug!("normalize_param_env(param_env={})", - param_env.repr(tcx)); + }; - let infcx = infer::new_infer_ctxt(tcx); - let predicates = try!(fully_normalize(&infcx, param_env, cause, ¶m_env.caller_bounds)); + infcx.resolve_regions_and_report_errors(body_id); + let predicates = match infcx.fully_resolve(&predicates) { + Ok(predicates) => predicates, + Err(fixup_err) => { + // If we encounter a fixup error, it means that some type + // variable wound up unconstrained. I actually don't know + // if this can happen, and I certainly don't expect it to + // happen often, but if it did happen it probably + // represents a legitimate failure due to some kind of + // unconstrained variable, and it seems better not to ICE, + // all things considered. + let err_msg = fixup_err_to_string(fixup_err); + tcx.sess.span_err(span, &err_msg); + return unnormalized_env; // an unnormalized env is better than nothing + } + }; - debug!("normalize_param_env: predicates={}", + debug!("normalize_param_env_or_error: predicates={}", predicates.repr(tcx)); - Ok(param_env.with_caller_bounds(predicates)) + unnormalized_env.with_caller_bounds(predicates) } pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, @@ -453,8 +464,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, { let tcx = closure_typer.tcx(); - debug!("normalize_param_env(value={})", - value.repr(tcx)); + debug!("normalize_param_env(value={})", value.repr(tcx)); let mut selcx = &mut SelectionContext::new(infcx, closure_typer); let mut fulfill_cx = FulfillmentContext::new(); @@ -468,8 +478,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, } try!(fulfill_cx.select_all_or_error(infcx, closure_typer)); let resolved_value = infcx.resolve_type_vars_if_possible(&normalized_value); - debug!("normalize_param_env: resolved_value={}", - resolved_value.repr(tcx)); + debug!("normalize_param_env: resolved_value={}", resolved_value.repr(tcx)); Ok(resolved_value) } From 206c2546c03c5d28aea3752f5746c9e161ee3692 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 23 Feb 2015 13:02:31 -0500 Subject: [PATCH 26/39] Improve debug output from coherence. --- src/librustc/middle/traits/coherence.rs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index 4d45bb841f49f..62b81f0ebe7db 100644 --- a/src/librustc/middle/traits/coherence.rs +++ b/src/librustc/middle/traits/coherence.rs @@ -52,9 +52,16 @@ fn overlap(selcx: &mut SelectionContext, b_def_id: ast::DefId) -> bool { + debug!("overlap(a_def_id={}, b_def_id={})", + a_def_id.repr(selcx.tcx()), + b_def_id.repr(selcx.tcx())); + let (a_trait_ref, a_obligations) = impl_trait_ref_and_oblig(selcx, a_def_id); let (b_trait_ref, b_obligations) = impl_trait_ref_and_oblig(selcx, b_def_id); + debug!("overlap: a_trait_ref={}", a_trait_ref.repr(selcx.tcx())); + debug!("overlap: b_trait_ref={}", b_trait_ref.repr(selcx.tcx())); + // Does `a <: b` hold? If not, no overlap. if let Err(_) = infer::mk_sub_poly_trait_refs(selcx.infcx(), true, @@ -64,10 +71,20 @@ fn overlap(selcx: &mut SelectionContext, return false; } + debug!("overlap: subtraitref check succeeded"); + // Are any of the obligations unsatisfiable? If so, no overlap. - a_obligations.iter() - .chain(b_obligations.iter()) - .all(|o| selcx.evaluate_obligation(o)) + let opt_failing_obligation = + a_obligations.iter() + .chain(b_obligations.iter()) + .find(|o| !selcx.evaluate_obligation(o)); + + if let Some(failing_obligation) = opt_failing_obligation { + debug!("overlap: obligation unsatisfiable {}", failing_obligation.repr(selcx.tcx())); + return false; + } + + true } /// Instantiate fresh variables for all bound parameters of the impl From 2d200c9c8bd6659720a68ab8dd74218b1e58c1e9 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 23 Feb 2015 10:59:17 -0800 Subject: [PATCH 27/39] std: Move std::env to the new I/O APIs This commit moves `std::env` away from the `std::old_io` error type as well as the `std::old_path` module. Methods returning an error now return `io::Error` and methods consuming or returning paths use `std::path` instead of `std::old_path`. This commit does not yet mark these APIs as `#[stable]`. This commit also migrates `std::old_io::TempDir` to `std::fs::TempDir` with essentially the exact same API. This type was added to interoperate with the new path API and has its own `tempdir` feature. Finally, this commit reverts the deprecation of `std::os` APIs returning the old path API types. This deprecation can come back once the entire `std::old_path` module is deprecated. [breaking-change] --- src/librustc/lib.rs | 1 + src/librustc/metadata/filesearch.rs | 7 +- src/librustc/plugin/load.rs | 4 +- src/librustc/session/mod.rs | 6 +- src/librustc_back/archive.rs | 6 +- src/librustc_back/fs.rs | 4 +- src/librustc_back/lib.rs | 1 + src/librustc_back/rpath.rs | 6 +- src/librustc_back/target/mod.rs | 3 +- src/librustc_driver/driver.rs | 5 +- src/librustdoc/test.rs | 6 +- src/libstd/dynamic_lib.rs | 3 +- src/libstd/env.rs | 27 +++--- src/libstd/{fs.rs => fs/mod.rs} | 4 + src/libstd/fs/tempdir.rs | 125 ++++++++++++++++++++++++++++ src/libstd/net/test.rs | 2 +- src/libstd/old_io/tempfile.rs | 6 +- src/libstd/old_io/test.rs | 5 +- src/libstd/os.rs | 55 ++++++++---- src/libstd/sys/unix/backtrace.rs | 5 +- src/libstd/sys/unix/os.rs | 57 +++++++------ src/libstd/sys/windows/fs.rs | 4 +- src/libstd/sys/windows/mod.rs | 14 ++-- src/libstd/sys/windows/os.rs | 36 ++++---- src/libstd/sys/windows/process2.rs | 10 +-- src/libterm/lib.rs | 1 + src/libterm/terminfo/searcher.rs | 3 +- src/test/run-pass/env-home-dir.rs | 3 +- src/test/run-pass/issue-15149.rs | 32 +++---- src/test/run-pass/issue-16272.rs | 6 +- src/test/run-pass/issue-20091.rs | 17 ++-- 31 files changed, 323 insertions(+), 141 deletions(-) rename src/libstd/{fs.rs => fs/mod.rs} (99%) create mode 100644 src/libstd/fs/tempdir.rs diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index fe9a81bb7c984..26cb4f917c566 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -40,6 +40,7 @@ #![feature(staged_api)] #![feature(std_misc)] #![feature(unicode)] +#![feature(os)] #![cfg_attr(test, feature(test))] extern crate arena; diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index d63b3dd60d01d..a8d39f9573932 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -14,6 +14,7 @@ pub use self::FileMatch::*; use std::collections::HashSet; use std::env; +use std::os; use std::old_io::fs::PathExtensions; use std::old_io::fs; @@ -194,7 +195,7 @@ pub fn get_or_default_sysroot() -> Path { }) } - match canonicalize(env::current_exe().ok()) { + match canonicalize(os::self_exe_name()) { Some(mut p) => { p.pop(); p.pop(); p } None => panic!("can't determine value for sysroot") } @@ -224,7 +225,7 @@ pub fn rust_path() -> Vec { } None => Vec::new() }; - let mut cwd = env::current_dir().unwrap(); + let mut cwd = os::getcwd().unwrap(); // now add in default entries let cwd_dot_rust = cwd.join(".rust"); if !env_rust_path.contains(&cwd_dot_rust) { @@ -243,7 +244,7 @@ pub fn rust_path() -> Vec { } cwd.pop(); } - if let Some(h) = env::home_dir() { + if let Some(h) = os::homedir() { let p = h.join(".rust"); if !env_rust_path.contains(&p) && p.exists() { env_rust_path.push(p); diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs index b3bc898748fdc..a419d4134b40e 100644 --- a/src/librustc/plugin/load.rs +++ b/src/librustc/plugin/load.rs @@ -15,7 +15,7 @@ use metadata::creader::CrateReader; use plugin::registry::Registry; use std::mem; -use std::env; +use std::os; use std::dynamic_lib::DynamicLibrary; use std::borrow::ToOwned; use syntax::ast; @@ -103,7 +103,7 @@ impl<'a> PluginLoader<'a> { path: Path, symbol: String) -> PluginRegistrarFun { // Make sure the path contains a / or the linker will search for it. - let path = env::current_dir().unwrap().join(&path); + let path = os::getcwd().unwrap().join(&path); let lib = match DynamicLibrary::open(Some(&path)) { Ok(lib) => lib, diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index b690cc7f7d06b..615ee77c1e095 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -27,8 +27,8 @@ use syntax::{ast, codemap}; use rustc_back::target::Target; -use std::env; use std::cell::{Cell, RefCell}; +use std::os; pub mod config; pub mod search_paths; @@ -347,7 +347,7 @@ pub fn build_session_(sopts: config::Options, if path.is_absolute() { path.clone() } else { - env::current_dir().unwrap().join(&path) + os::getcwd().unwrap().join(&path) } ); @@ -370,7 +370,7 @@ pub fn build_session_(sopts: config::Options, plugin_registrar_fn: Cell::new(None), default_sysroot: default_sysroot, local_crate_source_file: local_crate_source_file, - working_dir: env::current_dir().unwrap(), + working_dir: os::getcwd().unwrap(), lint_store: RefCell::new(lint::LintStore::new()), lints: RefCell::new(NodeMap()), crate_types: RefCell::new(Vec::new()), diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs index 6bf745315eace..3fcae6a8034c2 100644 --- a/src/librustc_back/archive.rs +++ b/src/librustc_back/archive.rs @@ -14,7 +14,7 @@ use std::old_io::fs::PathExtensions; use std::old_io::process::{Command, ProcessOutput}; use std::old_io::{fs, TempDir}; use std::old_io; -use std::env; +use std::os; use std::str; use syntax::diagnostic::Handler as ErrorHandler; @@ -224,7 +224,7 @@ impl<'a> ArchiveBuilder<'a> { pub fn build(self) -> Archive<'a> { // Get an absolute path to the destination, so `ar` will work even // though we run it from `self.work_dir`. - let abs_dst = env::current_dir().unwrap().join(&self.archive.dst); + let abs_dst = os::getcwd().unwrap().join(&self.archive.dst); assert!(!abs_dst.is_relative()); let mut args = vec![&abs_dst]; let mut total_len = abs_dst.as_vec().len(); @@ -283,7 +283,7 @@ impl<'a> ArchiveBuilder<'a> { // First, extract the contents of the archive to a temporary directory. // We don't unpack directly into `self.work_dir` due to the possibility // of filename collisions. - let archive = env::current_dir().unwrap().join(archive); + let archive = os::getcwd().unwrap().join(archive); run_ar(self.archive.handler, &self.archive.maybe_ar_prog, "x", Some(loc.path()), &[&archive]); diff --git a/src/librustc_back/fs.rs b/src/librustc_back/fs.rs index acf49d1ca46e3..99a1df95a80cd 100644 --- a/src/librustc_back/fs.rs +++ b/src/librustc_back/fs.rs @@ -10,13 +10,13 @@ use std::old_io; use std::old_io::fs; -use std::env; +use std::os; /// Returns an absolute path in the filesystem that `path` points to. The /// returned path does not contain any symlinks in its hierarchy. pub fn realpath(original: &Path) -> old_io::IoResult { static MAX_LINKS_FOLLOWED: uint = 256; - let original = try!(env::current_dir()).join(original); + let original = try!(os::getcwd()).join(original); // Right now lstat on windows doesn't work quite well if cfg!(windows) { diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index d589b063204c7..711f937d2f355 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -41,6 +41,7 @@ #![feature(rustc_private)] #![feature(staged_api)] #![feature(env)] +#![feature(path)] extern crate syntax; extern crate serialize; diff --git a/src/librustc_back/rpath.rs b/src/librustc_back/rpath.rs index 3f2dcee511095..943ff52925a24 100644 --- a/src/librustc_back/rpath.rs +++ b/src/librustc_back/rpath.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - use std::collections::HashSet; use std::env; use std::old_io::IoError; +use std::os; use syntax::ast; pub struct RPathConfig where @@ -109,7 +109,7 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path "$ORIGIN" }; - let cwd = env::current_dir().unwrap(); + let cwd = os::getcwd().unwrap(); let mut lib = (config.realpath)(&cwd.join(lib)).unwrap(); lib.pop(); let mut output = (config.realpath)(&cwd.join(&config.out_filename)).unwrap(); @@ -129,7 +129,7 @@ fn get_install_prefix_rpath(config: RPathConfig) -> String where let path = (config.get_install_prefix_lib_path)(); let path = env::current_dir().unwrap().join(&path); // FIXME (#9639): This needs to handle non-utf8 paths - path.as_str().expect("non-utf8 component in rpath").to_string() + path.to_str().expect("non-utf8 component in rpath").to_string() } fn minimize_rpaths(rpaths: &[String]) -> Vec { diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index b04c07977c369..d09a7c355d3e3 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -310,6 +310,7 @@ impl Target { /// JSON decoding. pub fn search(target: &str) -> Result { use std::env; + use std::os; use std::ffi::OsString; use std::old_io::File; use std::old_path::Path; @@ -396,7 +397,7 @@ impl Target { // FIXME 16351: add a sane default search path? - for dir in env::split_paths(&target_path) { + for dir in os::split_paths(target_path.to_str().unwrap()).iter() { let p = dir.join(path.clone()); if p.is_file() { return load_file(&p); diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index b12f05d7c50f7..a1a0e71f3343f 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -32,6 +32,7 @@ use super::Compilation; use serialize::json; use std::env; +use std::os; use std::ffi::OsString; use std::old_io::fs; use std::old_io; @@ -471,7 +472,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, if cfg!(windows) { _old_path = env::var_os("PATH").unwrap_or(_old_path); let mut new_path = sess.host_filesearch(PathKind::All).get_dylib_search_paths(); - new_path.extend(env::split_paths(&_old_path)); + new_path.extend(os::split_paths(_old_path.to_str().unwrap()).into_iter()); env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap()); } let features = sess.features.borrow(); @@ -738,7 +739,7 @@ pub fn phase_6_link_output(sess: &Session, outputs: &OutputFilenames) { let old_path = env::var_os("PATH").unwrap_or(OsString::from_str("")); let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(); - new_path.extend(env::split_paths(&old_path)); + new_path.extend(os::split_paths(old_path.to_str().unwrap()).into_iter()); env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap()); time(sess.time_passes(), "linking", (), |_| diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index bf14b86ebd1e3..78f126dcf6a82 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -13,7 +13,7 @@ use std::sync::mpsc::channel; use std::dynamic_lib::DynamicLibrary; use std::old_io::{Command, TempDir}; use std::old_io; -use std::env; +use std::os; use std::str; use std::thread; use std::thunk::Thunk; @@ -46,7 +46,7 @@ pub fn run(input: &str, let input = config::Input::File(input_path.clone()); let sessopts = config::Options { - maybe_sysroot: Some(env::current_exe().unwrap().dir_path().dir_path()), + maybe_sysroot: Some(os::self_exe_name().unwrap().dir_path().dir_path()), search_paths: libs.clone(), crate_types: vec!(config::CrateTypeDylib), externs: externs.clone(), @@ -113,7 +113,7 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths, let input = config::Input::Str(test.to_string()); let sessopts = config::Options { - maybe_sysroot: Some(env::current_exe().unwrap().dir_path().dir_path()), + maybe_sysroot: Some(os::self_exe_name().unwrap().dir_path().dir_path()), search_paths: libs, crate_types: vec!(config::CrateTypeExecutable), output_types: vec!(config::OutputTypeExe), diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs index fcae8e791604d..babae3b3019ec 100644 --- a/src/libstd/dynamic_lib.rs +++ b/src/libstd/dynamic_lib.rs @@ -21,6 +21,7 @@ use ffi::CString; use mem; use env; use str; +use os; pub struct DynamicLibrary { handle: *mut u8 @@ -102,7 +103,7 @@ impl DynamicLibrary { /// process pub fn search_path() -> Vec { match env::var_os(DynamicLibrary::envvar()) { - Some(var) => env::split_paths(&var).collect(), + Some(var) => os::split_paths(var.to_str().unwrap()), None => Vec::new(), } } diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 0e1f5f2ba0294..5db9f6ef7fdd4 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -21,7 +21,8 @@ use prelude::v1::*; use error::Error; use ffi::{OsString, AsOsStr}; use fmt; -use old_io::IoResult; +use io; +use path::{AsPath, PathBuf}; use sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT, Ordering}; use sync::{StaticMutex, MUTEX_INIT}; use sys::os as os_imp; @@ -46,7 +47,7 @@ use sys::os as os_imp; /// let p = env::current_dir().unwrap(); /// println!("The current directory is {}", p.display()); /// ``` -pub fn current_dir() -> IoResult { +pub fn current_dir() -> io::Result { os_imp::getcwd() } @@ -57,14 +58,14 @@ pub fn current_dir() -> IoResult { /// /// ```rust /// use std::env; -/// use std::old_path::Path; +/// use std::path::Path; /// /// let root = Path::new("/"); /// assert!(env::set_current_dir(&root).is_ok()); /// println!("Successfully changed working directory to {}!", root.display()); /// ``` -pub fn set_current_dir(p: &Path) -> IoResult<()> { - os_imp::chdir(p) +pub fn set_current_dir(p: &P) -> io::Result<()> { + os_imp::chdir(p.as_path()) } static ENV_LOCK: StaticMutex = MUTEX_INIT; @@ -280,8 +281,8 @@ pub fn split_paths(unparsed: &T) -> SplitPaths { } impl<'a> Iterator for SplitPaths<'a> { - type Item = Path; - fn next(&mut self) -> Option { self.inner.next() } + type Item = PathBuf; + fn next(&mut self) -> Option { self.inner.next() } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } @@ -305,10 +306,11 @@ pub struct JoinPathsError { /// /// ```rust /// use std::env; +/// use std::path::PathBuf; /// /// if let Some(path) = env::var_os("PATH") { /// let mut paths = env::split_paths(&path).collect::>(); -/// paths.push(Path::new("/home/xyz/bin")); +/// paths.push(PathBuf::new("/home/xyz/bin")); /// let new_path = env::join_paths(paths.iter()).unwrap(); /// env::set_var("PATH", &new_path); /// } @@ -355,7 +357,7 @@ impl Error for JoinPathsError { /// None => println!("Impossible to get your home dir!") /// } /// ``` -pub fn home_dir() -> Option { +pub fn home_dir() -> Option { os_imp::home_dir() } @@ -369,7 +371,7 @@ pub fn home_dir() -> Option { /// On Windows, returns the value of, in order, the 'TMP', 'TEMP', /// 'USERPROFILE' environment variable if any are set and not the empty /// string. Otherwise, tmpdir returns the path to the Windows directory. -pub fn temp_dir() -> Path { +pub fn temp_dir() -> PathBuf { os_imp::temp_dir() } @@ -396,7 +398,7 @@ pub fn temp_dir() -> Path { /// Err(e) => println!("failed to get current exe path: {}", e), /// }; /// ``` -pub fn current_exe() -> IoResult { +pub fn current_exe() -> io::Result { os_imp::current_exe() } @@ -825,6 +827,7 @@ mod tests { use iter::repeat; use rand::{self, Rng}; use ffi::{OsString, OsStr}; + use path::PathBuf; fn make_rand_name() -> OsString { let mut rng = rand::thread_rng(); @@ -944,7 +947,7 @@ mod tests { fn split_paths_unix() { fn check_parse(unparsed: &str, parsed: &[&str]) -> bool { split_paths(unparsed).collect::>() == - parsed.iter().map(|s| Path::new(*s)).collect::>() + parsed.iter().map(|s| PathBuf::new(*s)).collect::>() } assert!(check_parse("", &mut [""])); diff --git a/src/libstd/fs.rs b/src/libstd/fs/mod.rs similarity index 99% rename from src/libstd/fs.rs rename to src/libstd/fs/mod.rs index 98c1b50a9bf14..aa2117586216a 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs/mod.rs @@ -25,6 +25,10 @@ use sys::fs2 as fs_imp; use sys_common::{AsInnerMut, FromInner, AsInner}; use vec::Vec; +pub use self::tempdir::TempDir; + +mod tempdir; + /// A reference to an open file on the filesystem. /// /// An instance of a `File` can be read and/or written depending on what options diff --git a/src/libstd/fs/tempdir.rs b/src/libstd/fs/tempdir.rs new file mode 100644 index 0000000000000..79bdb35dd48cd --- /dev/null +++ b/src/libstd/fs/tempdir.rs @@ -0,0 +1,125 @@ +// Copyright 2015 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. + +#![unstable(feature = "tempdir", reason = "needs an RFC before stabilization")] + +use prelude::v1::*; + +use env; +use io::{self, Error, ErrorKind}; +use fs; +use path::{self, PathBuf, AsPath}; +use rand::{thread_rng, Rng}; + +/// A wrapper for a path to temporary directory implementing automatic +/// scope-based deletion. +pub struct TempDir { + path: Option, +} + +// How many times should we (re)try finding an unused random name? It should be +// enough that an attacker will run out of luck before we run out of patience. +const NUM_RETRIES: u32 = 1 << 31; +// How many characters should we include in a random file name? It needs to +// be enough to dissuade an attacker from trying to preemptively create names +// of that length, but not so huge that we unnecessarily drain the random number +// generator of entropy. +const NUM_RAND_CHARS: uint = 12; + +impl TempDir { + /// Attempts to make a temporary directory inside of `tmpdir` whose name + /// will have the prefix `prefix`. The directory will be automatically + /// deleted once the returned wrapper is destroyed. + /// + /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] // rand usage + pub fn new_in(tmpdir: &P, prefix: &str) + -> io::Result { + let storage; + let mut tmpdir = tmpdir.as_path(); + if !tmpdir.is_absolute() { + let cur_dir = try!(env::current_dir()); + storage = cur_dir.join(tmpdir); + tmpdir = &storage; + // return TempDir::new_in(&cur_dir.join(tmpdir), prefix); + } + + let mut rng = thread_rng(); + for _ in 0..NUM_RETRIES { + let suffix: String = rng.gen_ascii_chars().take(NUM_RAND_CHARS).collect(); + let leaf = if prefix.len() > 0 { + format!("{}.{}", prefix, suffix) + } else { + // If we're given an empty string for a prefix, then creating a + // directory starting with "." would lead to it being + // semi-invisible on some systems. + suffix + }; + let path = tmpdir.join(&leaf); + match fs::create_dir(&path) { + Ok(_) => return Ok(TempDir { path: Some(path) }), + Err(ref e) if e.kind() == ErrorKind::PathAlreadyExists => {} + Err(e) => return Err(e) + } + } + + Err(Error::new(ErrorKind::PathAlreadyExists, + "too many temporary directories already exist", + None)) + } + + /// Attempts to make a temporary directory inside of `env::temp_dir()` whose + /// name will have the prefix `prefix`. The directory will be automatically + /// deleted once the returned wrapper is destroyed. + /// + /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] + pub fn new(prefix: &str) -> io::Result { + TempDir::new_in(&env::temp_dir(), prefix) + } + + /// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper. + /// This discards the wrapper so that the automatic deletion of the + /// temporary directory is prevented. + pub fn into_path(mut self) -> PathBuf { + self.path.take().unwrap() + } + + /// Access the wrapped `std::path::Path` to the temporary directory. + pub fn path(&self) -> &path::Path { + self.path.as_ref().unwrap() + } + + /// Close and remove the temporary directory + /// + /// Although `TempDir` removes the directory on drop, in the destructor + /// any errors are ignored. To detect errors cleaning up the temporary + /// directory, call `close` instead. + pub fn close(mut self) -> io::Result<()> { + self.cleanup_dir() + } + + fn cleanup_dir(&mut self) -> io::Result<()> { + match self.path { + Some(ref p) => fs::remove_dir_all(p), + None => Ok(()) + } + } +} + +impl Drop for TempDir { + fn drop(&mut self) { + let _ = self.cleanup_dir(); + } +} + +// the tests for this module need to change the path using change_dir, +// and this doesn't play nicely with other tests so these unit tests are located +// in src/test/run-pass/tempfile.rs diff --git a/src/libstd/net/test.rs b/src/libstd/net/test.rs index c70e92884ac65..aec50d638c69f 100644 --- a/src/libstd/net/test.rs +++ b/src/libstd/net/test.rs @@ -34,6 +34,6 @@ fn base_port() -> u16 { let dirs = ["32-opt", "32-nopt", "64-opt", "64-nopt", "64-opt-vg", "all-opt", "snap3", "dist"]; dirs.iter().enumerate().find(|&(_, dir)| { - cwd.as_str().unwrap().contains(dir) + cwd.to_str().unwrap().contains(dir) }).map(|p| p.0).unwrap_or(0) as u16 * 1000 + 19600 } diff --git a/src/libstd/old_io/tempfile.rs b/src/libstd/old_io/tempfile.rs index 42317c7a2d431..76753dca52e1e 100644 --- a/src/libstd/old_io/tempfile.rs +++ b/src/libstd/old_io/tempfile.rs @@ -96,9 +96,10 @@ impl TempDir { /// deleted once the returned wrapper is destroyed. /// /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] pub fn new_in(tmpdir: &Path, prefix: &str) -> IoResult { if !tmpdir.is_absolute() { - let cur_dir = try!(env::current_dir()); + let cur_dir = try!(::os::getcwd()); return TempDir::new_in(&cur_dir.join(tmpdir), prefix); } @@ -132,8 +133,9 @@ impl TempDir { /// deleted once the returned wrapper is destroyed. /// /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] pub fn new(prefix: &str) -> IoResult { - TempDir::new_in(&env::temp_dir(), prefix) + TempDir::new_in(&::os::tmpdir(), prefix) } /// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper. diff --git a/src/libstd/old_io/test.rs b/src/libstd/old_io/test.rs index ee72beccfa848..43c0b9268a242 100644 --- a/src/libstd/old_io/test.rs +++ b/src/libstd/old_io/test.rs @@ -38,10 +38,11 @@ fn next_test_unix_socket() -> String { /// Get a temporary path which could be the location of a unix socket #[cfg(not(target_os = "ios"))] +#[allow(deprecated)] pub fn next_test_unix() -> Path { let string = next_test_unix_socket(); if cfg!(unix) { - env::temp_dir().join(string) + ::os::tmpdir().join(string) } else { Path::new(format!("{}{}", r"\\.\pipe\", string)) } @@ -88,7 +89,7 @@ fn base_port() -> u16 { // FIXME (#9639): This needs to handle non-utf8 paths let path = env::current_dir().unwrap(); - let path_s = path.as_str().unwrap(); + let path_s = path.to_str().unwrap(); let mut final_base = base; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 86f5c2c356e5e..9c42d1be77ee1 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -49,6 +49,7 @@ use ops::{Drop, FnOnce}; use option::Option::{Some, None}; use option::Option; use old_path::{Path, GenericPath, BytesContainer}; +use path::{self, PathBuf}; use ptr::PtrExt; use ptr; use result::Result::{Err, Ok}; @@ -67,6 +68,35 @@ use vec::Vec; #[cfg(unix)] pub use sys::ext as unix; #[cfg(windows)] pub use sys::ext as windows; +fn err2old(new: ::io::Error) -> IoError { + IoError { + kind: ::old_io::OtherIoError, + desc: "os error", + detail: Some(new.to_string()), + } +} + +#[cfg(windows)] +fn path2new(path: &Path) -> PathBuf { + PathBuf::new(path.as_str().unwrap()) +} +#[cfg(unix)] +fn path2new(path: &Path) -> PathBuf { + use os::unix::prelude::*; + PathBuf::new(::from_bytes(path.as_vec())) +} + +#[cfg(unix)] +fn path2old(path: &path::Path) -> Path { + use os::unix::prelude::*; + use ffi::AsOsStr; + Path::new(path.as_os_str().as_bytes()) +} +#[cfg(windows)] +fn path2old(path: &path::Path) -> Path { + Path::new(path.to_str().unwrap()) +} + /// Get the number of cores available pub fn num_cpus() -> uint { unsafe { @@ -100,10 +130,9 @@ pub const TMPBUF_SZ : uint = 1000; /// let current_working_directory = os::getcwd().unwrap(); /// println!("The current directory is {:?}", current_working_directory.display()); /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to std::env::current_dir")] #[unstable(feature = "os")] pub fn getcwd() -> IoResult { - env::current_dir() + env::current_dir().map_err(err2old).map(|s| path2old(&s)) } /// Returns a vector of (variable, value) pairs, for all the environment @@ -245,12 +274,11 @@ pub fn unsetenv(n: &str) { /// None => println!("{} is not defined in the environment.", key) /// } /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to env::split_paths")] #[unstable(feature = "os")] pub fn split_paths(unparsed: T) -> Vec { let b = unparsed.container_as_bytes(); let s = str::from_utf8(b).unwrap(); - env::split_paths(s).collect() + env::split_paths(s).map(|s| path2old(&s)).collect() } /// Joins a collection of `Path`s appropriately for the `PATH` @@ -274,7 +302,6 @@ pub fn split_paths(unparsed: T) -> Vec { /// paths.push(Path::new("/home/xyz/bin")); /// os::setenv(key, os::join_paths(paths.as_slice()).unwrap()); /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to env::join_paths")] #[unstable(feature = "os")] pub fn join_paths(paths: &[T]) -> Result, &'static str> { env::join_paths(paths.iter().map(|s| { @@ -335,10 +362,9 @@ pub fn dll_filename(base: &str) -> String { /// None => println!("Unable to get the path of this executable!") /// }; /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to env::current_exe")] #[unstable(feature = "os")] pub fn self_exe_name() -> Option { - env::current_exe().ok() + env::current_exe().ok().map(|p| path2old(&p)) } /// Optionally returns the filesystem path to the current executable which is @@ -356,10 +382,9 @@ pub fn self_exe_name() -> Option { /// None => println!("Impossible to fetch the path of this executable.") /// }; /// ``` -#[deprecated(since = "1.0.0", reason = "use env::current_exe + dir_path/pop")] #[unstable(feature = "os")] pub fn self_exe_path() -> Option { - env::current_exe().ok().map(|mut p| { p.pop(); p }) + env::current_exe().ok().map(|p| { let mut p = path2old(&p); p.pop(); p }) } /// Optionally returns the path to the current user's home directory if known. @@ -386,9 +411,8 @@ pub fn self_exe_path() -> Option { /// None => println!("Impossible to get your home dir!") /// } /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to env::home_dir")] -#[allow(deprecated)] #[unstable(feature = "os")] +#[allow(deprecated)] pub fn homedir() -> Option { #[inline] #[cfg(unix)] @@ -424,9 +448,8 @@ pub fn homedir() -> Option { /// On Windows, returns the value of, in order, the 'TMP', 'TEMP', /// 'USERPROFILE' environment variable if any are set and not the empty /// string. Otherwise, tmpdir returns the path to the Windows directory. -#[deprecated(since = "1.0.0", reason = "renamed to env::temp_dir")] -#[allow(deprecated)] #[unstable(feature = "os")] +#[allow(deprecated)] pub fn tmpdir() -> Path { return lookup(); @@ -488,7 +511,8 @@ pub fn make_absolute(p: &Path) -> IoResult { if p.is_absolute() { Ok(p.clone()) } else { - env::current_dir().map(|mut cwd| { + env::current_dir().map_err(err2old).map(|cwd| { + let mut cwd = path2old(&cwd); cwd.push(p); cwd }) @@ -507,10 +531,9 @@ pub fn make_absolute(p: &Path) -> IoResult { /// assert!(os::change_dir(&root).is_ok()); /// println!("Successfully changed working directory to {}!", root.display()); /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to env::set_current_dir")] #[unstable(feature = "os")] pub fn change_dir(p: &Path) -> IoResult<()> { - return sys::os::chdir(p); + sys::os::chdir(&path2new(p)).map_err(err2old) } /// Returns the platform-specific value of errno diff --git a/src/libstd/sys/unix/backtrace.rs b/src/libstd/sys/unix/backtrace.rs index 6f07dea5279fd..6267792ba745e 100644 --- a/src/libstd/sys/unix/backtrace.rs +++ b/src/libstd/sys/unix/backtrace.rs @@ -84,8 +84,9 @@ /// all unix platforms we support right now, so it at least gets the job done. use prelude::v1::*; +use os::unix::prelude::*; -use ffi::CStr; +use ffi::{CStr, AsOsStr}; use old_io::IoResult; use libc; use mem; @@ -327,7 +328,7 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> { }; let filename = match selfname { Some(path) => { - let bytes = path.as_vec(); + let bytes = path.as_os_str().as_bytes(); 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/os.rs b/src/libstd/sys/unix/os.rs index d51f907307e46..951c091f9f36c 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -16,12 +16,13 @@ use os::unix::*; use error::Error as StdError; use ffi::{CString, CStr, OsString, OsStr, AsOsStr}; use fmt; +use io; use iter; use libc::{self, c_int, c_char, c_void}; use mem; -use io; -use old_io::{IoResult, IoError, fs}; +use old_io::{IoError, IoResult}; use ptr; +use path::{self, PathBuf}; use slice; use str; use sys::c; @@ -32,6 +33,14 @@ use vec; const BUF_BYTES: usize = 2048; const TMPBUF_SZ: usize = 128; +fn bytes2path(b: &[u8]) -> PathBuf { + PathBuf::new(::from_bytes(b)) +} + +fn os2path(os: OsString) -> PathBuf { + bytes2path(os.as_bytes()) +} + /// Returns the platform-specific value of errno pub fn errno() -> i32 { #[cfg(any(target_os = "macos", @@ -102,30 +111,30 @@ pub fn error_string(errno: i32) -> String { } } -pub fn getcwd() -> IoResult { +pub fn getcwd() -> io::Result { let mut buf = [0 as c_char; BUF_BYTES]; unsafe { if libc::getcwd(buf.as_mut_ptr(), buf.len() as libc::size_t).is_null() { - Err(IoError::last_error()) + Err(io::Error::last_os_error()) } else { - Ok(Path::new(CStr::from_ptr(buf.as_ptr()).to_bytes())) + Ok(bytes2path(CStr::from_ptr(buf.as_ptr()).to_bytes())) } } } -pub fn chdir(p: &Path) -> IoResult<()> { - let p = CString::new(p.as_vec()).unwrap(); +pub fn chdir(p: &path::Path) -> io::Result<()> { + let p = try!(CString::new(p.as_os_str().as_bytes())); unsafe { match libc::chdir(p.as_ptr()) == (0 as c_int) { true => Ok(()), - false => Err(IoError::last_error()), + false => Err(io::Error::last_os_error()), } } } pub struct SplitPaths<'a> { iter: iter::Map bool>, - fn(&'a [u8]) -> Path>, + fn(&'a [u8]) -> PathBuf>, } pub fn split_paths<'a>(unparsed: &'a OsStr) -> SplitPaths<'a> { @@ -133,13 +142,13 @@ pub fn split_paths<'a>(unparsed: &'a OsStr) -> SplitPaths<'a> { let unparsed = unparsed.as_bytes(); SplitPaths { iter: unparsed.split(is_colon as fn(&u8) -> bool) - .map(Path::new as fn(&'a [u8]) -> Path) + .map(bytes2path as fn(&'a [u8]) -> PathBuf) } } impl<'a> Iterator for SplitPaths<'a> { - type Item = Path; - fn next(&mut self) -> Option { self.iter.next() } + type Item = PathBuf; + fn next(&mut self) -> Option { self.iter.next() } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } @@ -200,12 +209,12 @@ pub fn current_exe() -> IoResult { } #[cfg(target_os = "dragonfly")] -pub fn current_exe() -> IoResult { - fs::readlink(&Path::new("/proc/curproc/file")) +pub fn current_exe() -> io::Result { + ::fs::read_link("/proc/curproc/file") } #[cfg(any(target_os = "bitrig", target_os = "openbsd"))] -pub fn current_exe() -> IoResult { +pub fn current_exe() -> io::Result { use sync::{StaticMutex, MUTEX_INIT}; static LOCK: StaticMutex = MUTEX_INIT; @@ -226,8 +235,8 @@ pub fn current_exe() -> IoResult { } #[cfg(any(target_os = "linux", target_os = "android"))] -pub fn current_exe() -> IoResult { - fs::readlink(&Path::new("/proc/self/exe")) +pub fn current_exe() -> io::Result { + ::fs::read_link("/proc/self/exe") } #[cfg(any(target_os = "macos", target_os = "ios"))] @@ -451,22 +460,20 @@ pub fn page_size() -> usize { } } -pub fn temp_dir() -> Path { - getenv("TMPDIR".as_os_str()).map(|p| Path::new(p.into_vec())).unwrap_or_else(|| { +pub fn temp_dir() -> PathBuf { + getenv("TMPDIR".as_os_str()).map(os2path).unwrap_or_else(|| { if cfg!(target_os = "android") { - Path::new("/data/local/tmp") + PathBuf::new("/data/local/tmp") } else { - Path::new("/tmp") + PathBuf::new("/tmp") } }) } -pub fn home_dir() -> Option { +pub fn home_dir() -> Option { return getenv("HOME".as_os_str()).or_else(|| unsafe { fallback() - }).map(|os| { - Path::new(os.into_vec()) - }); + }).map(os2path); #[cfg(any(target_os = "android", target_os = "ios"))] diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index 304d7e0153279..309d6c9dc48c2 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -368,7 +368,9 @@ pub fn readlink(p: &Path) -> IoResult { buf as *const u16, sz - 1, libc::VOLUME_NAME_DOS) - }, super::os2path); + }, |data| { + Path::new(String::from_utf16(data).unwrap()) + }); assert!(unsafe { libc::CloseHandle(handle) } != 0); return ret; } diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index a756fb29f81ae..51df18d504dc1 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -14,13 +14,14 @@ use prelude::v1::*; -use ffi::OsStr; +use ffi::{OsStr, OsString}; use io::{self, ErrorKind}; use libc; use mem; -use old_io::{self, IoResult, IoError}; use num::Int; -use os::windows::OsStrExt; +use old_io::{self, IoResult, IoError}; +use os::windows::{OsStrExt, OsStringExt}; +use path::PathBuf; use sync::{Once, ONCE_INIT}; macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => ( @@ -314,9 +315,10 @@ fn fill_utf16_buf_new(f1: F1, f2: F2) -> io::Result fill_utf16_buf_base(f1, f2).map_err(|()| io::Error::last_os_error()) } -fn os2path(s: &[u16]) -> Path { - // FIXME: this should not be a panicking conversion (aka path reform) - Path::new(String::from_utf16(s).unwrap()) +fn os2path(s: &[u16]) -> PathBuf { + let os = ::from_wide(s); + // FIXME(#22751) should consume `os` + PathBuf::new(&os) } pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] { diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index 6520d30487c76..587ab7924fd1d 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -18,11 +18,13 @@ use os::windows::*; use error::Error as StdError; use ffi::{OsString, OsStr, AsOsStr}; use fmt; -use ops::Range; +use io; use libc::types::os::arch::extra::LPWCH; use libc::{self, c_int, c_void}; use mem; use old_io::{IoError, IoResult}; +use ops::Range; +use path::{self, PathBuf}; use ptr; use slice; use sys::c; @@ -151,8 +153,8 @@ pub fn split_paths(unparsed: &OsStr) -> SplitPaths { } impl<'a> Iterator for SplitPaths<'a> { - type Item = Path; - fn next(&mut self) -> Option { + type Item = PathBuf; + fn next(&mut self) -> Option { // On Windows, the PATH environment variable is semicolon separated. // Double quotes are used as a way of introducing literal semicolons // (since c:\some;dir is a valid Windows path). Double quotes are not @@ -186,7 +188,7 @@ impl<'a> Iterator for SplitPaths<'a> { if !must_yield && in_progress.is_empty() { None } else { - Some(super::os2path(&in_progress[..])) + Some(super::os2path(&in_progress)) } } } @@ -228,33 +230,33 @@ impl StdError for JoinPathsError { fn description(&self) -> &str { "failed to join paths" } } -pub fn current_exe() -> IoResult { - super::fill_utf16_buf(|buf, sz| unsafe { +pub fn current_exe() -> io::Result { + super::fill_utf16_buf_new(|buf, sz| unsafe { libc::GetModuleFileNameW(ptr::null_mut(), buf, sz) }, super::os2path) } -pub fn getcwd() -> IoResult { - super::fill_utf16_buf(|buf, sz| unsafe { +pub fn getcwd() -> io::Result { + super::fill_utf16_buf_new(|buf, sz| unsafe { libc::GetCurrentDirectoryW(sz, buf) }, super::os2path) } -pub fn chdir(p: &Path) -> IoResult<()> { +pub fn chdir(p: &path::Path) -> io::Result<()> { let mut p = p.as_os_str().encode_wide().collect::>(); p.push(0); unsafe { match libc::SetCurrentDirectoryW(p.as_ptr()) != (0 as libc::BOOL) { true => Ok(()), - false => Err(IoError::last_error()), + false => Err(io::Error::last_os_error()), } } } pub fn getenv(k: &OsStr) -> Option { let k = super::to_utf16_os(k); - super::fill_utf16_buf(|buf, sz| unsafe { + super::fill_utf16_buf_new(|buf, sz| unsafe { libc::GetEnvironmentVariableW(k.as_ptr(), buf, sz) }, |buf| { OsStringExt::from_wide(buf) @@ -349,18 +351,18 @@ pub unsafe fn pipe() -> IoResult<(FileDesc, FileDesc)> { } } -pub fn temp_dir() -> Path { - super::fill_utf16_buf(|buf, sz| unsafe { +pub fn temp_dir() -> PathBuf { + super::fill_utf16_buf_new(|buf, sz| unsafe { c::GetTempPathW(sz, buf) }, super::os2path).unwrap() } -pub fn home_dir() -> Option { +pub fn home_dir() -> Option { getenv("HOME".as_os_str()).or_else(|| { getenv("USERPROFILE".as_os_str()) }).map(|os| { - // FIXME: OsString => Path - Path::new(os.to_str().unwrap()) + // FIXME(#22751) should consume `os` + PathBuf::new(&os) }).or_else(|| unsafe { let me = c::GetCurrentProcess(); let mut token = ptr::null_mut(); @@ -368,7 +370,7 @@ pub fn home_dir() -> Option { return None } let _handle = RawHandle::new(token); - super::fill_utf16_buf(|buf, mut sz| { + super::fill_utf16_buf_new(|buf, mut sz| { match c::GetUserProfileDirectoryW(token, buf, &mut sz) { 0 if libc::GetLastError() != 0 => 0, 0 => sz, diff --git a/src/libstd/sys/windows/process2.rs b/src/libstd/sys/windows/process2.rs index 19e38196d199f..d4c6e85489f5d 100644 --- a/src/libstd/sys/windows/process2.rs +++ b/src/libstd/sys/windows/process2.rs @@ -16,16 +16,15 @@ use collections; use env; use ffi::{OsString, OsStr}; use fmt; +use fs; use io::{self, Error}; use libc::{self, c_void}; -use old_io::fs; -use old_path; use os::windows::OsStrExt; use ptr; use sync::{StaticMutex, MUTEX_INIT}; +use sys::handle::Handle; use sys::pipe2::AnonPipe; use sys::{self, cvt}; -use sys::handle::Handle; use sys_common::{AsInner, FromInner}; //////////////////////////////////////////////////////////////////////////////// @@ -142,9 +141,8 @@ impl Process { for path in split_paths(&v) { let path = path.join(cfg.program.to_str().unwrap()) .with_extension(env::consts::EXE_EXTENSION); - // FIXME: update with new fs module once it lands - if fs::stat(&old_path::Path::new(&path)).is_ok() { - return Some(OsString::from_str(path.as_str().unwrap())) + if fs::metadata(&path).is_ok() { + return Some(path.into_os_string()) } } break diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index 5418533aff1d9..823d2879236d1 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -60,6 +60,7 @@ #![feature(unicode)] #![feature(std_misc)] #![feature(env)] +#![feature(os)] #![cfg_attr(windows, feature(libc))] #[macro_use] extern crate log; diff --git a/src/libterm/terminfo/searcher.rs b/src/libterm/terminfo/searcher.rs index c40a5534efbbb..a0cd784207001 100644 --- a/src/libterm/terminfo/searcher.rs +++ b/src/libterm/terminfo/searcher.rs @@ -17,12 +17,13 @@ use std::old_io::fs::PathExtensions; use std::env; /// Return path to database entry for `term` +#[allow(deprecated)] pub fn get_dbpath_for_term(term: &str) -> Option> { if term.len() == 0 { return None; } - let homedir = env::home_dir(); + let homedir = ::std::os::homedir(); let mut dirs_to_search = Vec::new(); let first_char = term.char_at(0); diff --git a/src/test/run-pass/env-home-dir.rs b/src/test/run-pass/env-home-dir.rs index 0e1ab73c02d08..2ab6feaf782f3 100644 --- a/src/test/run-pass/env-home-dir.rs +++ b/src/test/run-pass/env-home-dir.rs @@ -9,13 +9,14 @@ // except according to those terms. use std::env::*; +use std::path::PathBuf; #[cfg(unix)] fn main() { let oldhome = var("HOME"); set_var("HOME", "/home/MountainView"); - assert!(home_dir() == Some(Path::new("/home/MountainView"))); + assert!(home_dir() == Some(PathBuf::new("/home/MountainView"))); remove_var("HOME"); if cfg!(target_os = "android") { diff --git a/src/test/run-pass/issue-15149.rs b/src/test/run-pass/issue-15149.rs index aa176d5b0f041..d995ecc492e34 100644 --- a/src/test/run-pass/issue-15149.rs +++ b/src/test/run-pass/issue-15149.rs @@ -1,5 +1,3 @@ -// no-prefer-dynamic - // 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. @@ -10,12 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::slice::SliceExt; -use std::old_io::{fs, USER_RWX}; -use std::process; +// no-prefer-dynamic + +#![feature(fs, process, env, path, rand)] + use std::env; -use std::old_path::BytesContainer; +use std::fs; +use std::process; use std::rand::random; +use std::str; fn main() { // If we're the child, make sure we were invoked correctly @@ -34,21 +35,20 @@ fn main() { fn test() { // If we're the parent, copy our own binary to a new directory. let my_path = env::current_exe().unwrap(); - let my_dir = my_path.dir_path(); + let my_dir = my_path.parent().unwrap(); let random_u32: u32 = random(); - let child_dir = Path::new(my_dir.join(format!("issue-15149-child-{}", - random_u32))); - fs::mkdir(&child_dir, USER_RWX).unwrap(); + let child_dir = my_dir.join(&format!("issue-15149-child-{}", random_u32)); + fs::create_dir(&child_dir).unwrap(); - let child_path = child_dir.join(format!("mytest{}", - env::consts::EXE_SUFFIX)); + let child_path = child_dir.join(&format!("mytest{}", + env::consts::EXE_SUFFIX)); fs::copy(&my_path, &child_path).unwrap(); // Append the new directory to our own PATH. let path = { let mut paths: Vec<_> = env::split_paths(&env::var_os("PATH").unwrap()).collect(); - paths.push(child_dir.clone()); + paths.push(child_dir.to_path_buf()); env::join_paths(paths.iter()).unwrap() }; @@ -58,9 +58,9 @@ fn test() { assert!(child_output.status.success(), format!("child assertion failed\n child stdout:\n {}\n child stderr:\n {}", - child_output.stdout.container_as_str().unwrap(), - child_output.stderr.container_as_str().unwrap())); + str::from_utf8(&child_output.stdout).unwrap(), + str::from_utf8(&child_output.stderr).unwrap())); - fs::rmdir_recursive(&child_dir).unwrap(); + fs::remove_dir_all(&child_dir).unwrap(); } diff --git a/src/test/run-pass/issue-16272.rs b/src/test/run-pass/issue-16272.rs index 3bab78ab0df9f..92d8dfa2cf9a9 100644 --- a/src/test/run-pass/issue-16272.rs +++ b/src/test/run-pass/issue-16272.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::old_io::{process, Command}; +use std::process::Command; use std::env; fn main() { @@ -22,10 +22,8 @@ fn main() { } fn test() { - let status = Command::new(env::current_exe().unwrap()) + let status = Command::new(&env::current_exe().unwrap()) .arg("foo").arg("") - .stdout(process::InheritFd(1)) - .stderr(process::InheritFd(2)) .status().unwrap(); assert!(status.success()); } diff --git a/src/test/run-pass/issue-20091.rs b/src/test/run-pass/issue-20091.rs index 4d20e6360ad4f..ba107dd2cf9a2 100644 --- a/src/test/run-pass/issue-20091.rs +++ b/src/test/run-pass/issue-20091.rs @@ -8,14 +8,19 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-windows currently windows requires UTF-8 for spawning processes - -use std::old_io::Command; -use std::env; - +#[cfg(unix)] fn main() { + use std::process::Command; + use std::env; + use std::os::unix::prelude::*; + use std::ffi::OsStr; + if env::args().len() == 1 { - assert!(Command::new(env::current_exe().unwrap()).arg(b"\xff") + assert!(Command::new(&env::current_exe().unwrap()) + .arg(::from_bytes(b"\xff")) .status().unwrap().success()) } } + +#[cfg(windows)] +fn main() {} From 65e1e6bb942701a061f6772507141ea9f8e920e2 Mon Sep 17 00:00:00 2001 From: Keegan McAllister Date: Fri, 20 Feb 2015 12:12:25 -0800 Subject: [PATCH 28/39] Add a section on recursive macros --- src/doc/trpl/macros.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/doc/trpl/macros.md b/src/doc/trpl/macros.md index ce6fa3ce949cd..d0fa735b1dfbd 100644 --- a/src/doc/trpl/macros.md +++ b/src/doc/trpl/macros.md @@ -357,6 +357,45 @@ fn main() { [items]: ../reference.html#items +# Recursive macros + +A macro's expansion can include more macro invocations, including invocations +of the very same macro being expanded. These recursive macros are useful for +processing tree-structured input, as illustrated by this (simplistic) HTML +shorthand: + +```rust +# #![allow(unused_must_use)] +macro_rules! write_html { + ($w:expr, ) => (()); + + ($w:expr, $e:tt) => (write!($w, "{}", $e)); + + ($w:expr, $tag:ident [ $($inner:tt)* ] $($rest:tt)*) => {{ + write!($w, "<{}>", stringify!($tag)); + write_html!($w, $($inner)*); + write!($w, "", stringify!($tag)); + write_html!($w, $($rest)*); + }}; +} + +fn main() { +# // FIXME(#21826) + use std::fmt::Write; + let mut out = String::new(); + + write_html!(&mut out, + html[ + head[title["Macros guide"]] + body[h1["Macros are the best!"]] + ]); + + assert_eq!(out, + "Macros guide\ +

Macros are the best!

"); +} +``` + # Further reading The [advanced macros chapter][] goes into more detail about macro syntax. It From 1804242a2d4037fd3ae854989a97a65e16bda05a Mon Sep 17 00:00:00 2001 From: Keegan McAllister Date: Fri, 20 Feb 2015 21:39:03 -0800 Subject: [PATCH 29/39] Add a second, more vexing section on recursive macros Fixes #22423. --- src/doc/trpl/advanced-macros.md | 47 +++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/doc/trpl/advanced-macros.md b/src/doc/trpl/advanced-macros.md index aff365051a4ea..9a4cc57a1f721 100644 --- a/src/doc/trpl/advanced-macros.md +++ b/src/doc/trpl/advanced-macros.md @@ -192,6 +192,53 @@ To keep this system simple and correct, `#[macro_use] extern crate ...` may only appear at the root of your crate, not inside `mod`. This ensures that `$crate` is a single identifier. +# The deep end + +The introductory chapter mentioned recursive macros, but it did not give the +full story. Recursive macros are useful for another reason: Each recursive +invocation gives you another opportunity to pattern-match the macro's +arguments. + +As an extreme example, it is possible, though hardly advisable, to implement +the [Bitwise Cyclic Tag](http://esolangs.org/wiki/Bitwise_Cyclic_Tag) automaton +within Rust's macro system. + +```rust +#![feature(trace_macros)] + +macro_rules! bct { + // cmd 0: d ... => ... + (0, $($ps:tt),* ; $_d:tt) + => (bct!($($ps),*, 0 ; )); + (0, $($ps:tt),* ; $_d:tt, $($ds:tt),*) + => (bct!($($ps),*, 0 ; $($ds),*)); + + // cmd 1p: 1 ... => 1 ... p + (1, $p:tt, $($ps:tt),* ; 1) + => (bct!($($ps),*, 1, $p ; 1, $p)); + (1, $p:tt, $($ps:tt),* ; 1, $($ds:tt),*) + => (bct!($($ps),*, 1, $p ; 1, $($ds),*, $p)); + + // cmd 1p: 0 ... => 0 ... + (1, $p:tt, $($ps:tt),* ; $($ds:tt),*) + => (bct!($($ps),*, 1, $p ; $($ds),*)); + + // halt on empty data string + ( $($ps:tt),* ; ) + => (()); +} + +fn main() { + trace_macros!(true); +# /* just check the definition + bct!(0, 0, 1, 1, 1 ; 1, 0, 1); +# */ +} +``` + +Exercise: use macros to reduce duplication in the above definition of the +`bct!` macro. + # A final note Macros, as currently implemented, are not for the faint of heart. Even From df0865754e56d3d804df3b2bb15d405e344e2015 Mon Sep 17 00:00:00 2001 From: Keegan McAllister Date: Fri, 20 Feb 2015 21:33:17 -0800 Subject: [PATCH 30/39] Tweak wording in the macros guide --- src/doc/trpl/macros.md | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/doc/trpl/macros.md b/src/doc/trpl/macros.md index d0fa735b1dfbd..cf12b4938e271 100644 --- a/src/doc/trpl/macros.md +++ b/src/doc/trpl/macros.md @@ -189,14 +189,12 @@ shorthand for a data type could be valid as either an expression or a pattern. ## Repetition -The repetition behavior can seem somewhat magical, especially when multiple -names are bound at multiple nested levels of repetition. The two rules to keep -in mind are: +The repetition operator follows two principal rules: -1. the behavior of `$(...)*` is to walk through one "layer" of repetitions, for -all of the `$name`s it contains, in lockstep, and +1. `$(...)*` walks through one "layer" of repetitions, for all of the `$name`s + it contains, in lockstep, and 2. each `$name` must be under at least as many `$(...)*`s as it was matched -against. If it is under more, it'll be duplicated, as appropriate. + against. If it is under more, it'll be duplicated, as appropriate. This baroque macro illustrates the duplication of variables from outer repetition levels. @@ -226,6 +224,10 @@ That's most of the matcher syntax. These examples use `$(...)*`, which is a more" match. Both forms optionally include a separator, which can be any token except `+` or `*`. +This system is based on +"[Macro-by-Example](http://www.cs.indiana.edu/ftp/techreports/TR206.pdf)" +(PDF link). + # Hygiene Some languages implement macros using simple text substitution, which leads to @@ -273,19 +275,26 @@ macro, using [a GNU C extension] to emulate Rust's expression blocks. }) ``` -This looks reasonable, but watch what happens in this example: +Here's a simple use case that goes terribly wrong: ```text const char *state = "reticulating splines"; -LOG(state); +LOG(state) ``` -The program will likely segfault, after it tries to execute +This expands to ```text -printf("log(%d): %s\n", state, state); +const char *state = "reticulating splines"; +int state = get_log_state(); +if (state > 0) { + printf("log(%d): %s\n", state, state); +} ``` +The second variable named `state` shadows the first one. This is a problem +because the print statement should refer to both of them. + The equivalent Rust macro has the desired behavior. ```rust From 848a7e692102643d99bb208b5a64199b6d6d87a1 Mon Sep 17 00:00:00 2001 From: Keegan McAllister Date: Fri, 20 Feb 2015 22:08:06 -0800 Subject: [PATCH 31/39] Enhance and move information about macro debugging Fixes #22424. --- src/doc/reference.md | 17 ++++++++++++----- src/doc/trpl/advanced-macros.md | 12 ++---------- src/doc/trpl/macros.md | 19 +++++++++++++++++++ src/doc/trpl/plugins.md | 14 ++++++-------- 4 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index 31524579df7c0..781b40be768c8 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -731,15 +731,20 @@ Rust syntax is restricted in two ways: pairs when they occur at the beginning of, or immediately after, a `$(...)*`; requiring a distinctive token in front can solve the problem. -## Syntax extensions useful for the macro author +## Syntax extensions useful in macros -* `log_syntax!` : print out the arguments at compile time -* `trace_macros!` : supply `true` or `false` to enable or disable macro expansion logging * `stringify!` : turn the identifier argument into a string literal * `concat!` : concatenates a comma-separated list of literals -* `concat_idents!` : create a new identifier by concatenating the arguments -The following attributes are used for quasiquoting in procedural macros: +## Syntax extensions for macro debugging + +* `log_syntax!` : print out the arguments at compile time +* `trace_macros!` : supply `true` or `false` to enable or disable macro expansion logging + +## Quasiquoting + +The following syntax extensions are used for quasiquoting Rust syntax trees, +usually in [procedural macros](book/plugins.html#syntax-extensions): * `quote_expr!` * `quote_item!` @@ -748,6 +753,8 @@ The following attributes are used for quasiquoting in procedural macros: * `quote_tokens!` * `quote_ty!` +Documentation is very limited at the moment. + # Crates and source files Rust is a *compiled* language. Its semantics obey a *phase distinction* diff --git a/src/doc/trpl/advanced-macros.md b/src/doc/trpl/advanced-macros.md index 9a4cc57a1f721..a226e4d0bf911 100644 --- a/src/doc/trpl/advanced-macros.md +++ b/src/doc/trpl/advanced-macros.md @@ -239,19 +239,11 @@ fn main() { Exercise: use macros to reduce duplication in the above definition of the `bct!` macro. -# A final note - -Macros, as currently implemented, are not for the faint of heart. Even -ordinary syntax errors can be more difficult to debug when they occur inside a -macro, and errors caused by parse problems in generated code can be very -tricky. Invoking the `log_syntax!` macro can help elucidate intermediate -states, invoking `trace_macros!(true)` will automatically print those -intermediate states out, and passing the flag `--pretty expanded` as a -command-line argument to the compiler will show the result of expansion. +# Procedural macros If Rust's macro system can't do what you need, you may want to write a [compiler plugin](plugins.html) instead. Compared to `macro_rules!` macros, this is significantly more work, the interfaces are much less stable, -and the warnings about debugging apply ten-fold. In exchange you get the +and bugs can be much harder to track down. In exchange you get the flexibility of running arbitrary Rust code within the compiler. Syntax extension plugins are sometimes called *procedural macros* for this reason. diff --git a/src/doc/trpl/macros.md b/src/doc/trpl/macros.md index cf12b4938e271..ce48a5aeda42c 100644 --- a/src/doc/trpl/macros.md +++ b/src/doc/trpl/macros.md @@ -405,6 +405,25 @@ fn main() { } ``` +# Debugging macro code + +To see the results of expanding macros, run `rustc --pretty expanded`. The +output represents a whole crate, so you can also feed it back in to `rustc`, +which will sometimes produce better error messages than the original +compilation. Note that the `--pretty expanded` output may have a different +meaning if multiple variables of the same name (but different syntax contexts) +are in play in the same scope. In this case `--pretty expanded,hygiene` will +tell you about the syntax contexts. + +`rustc` provides two syntax extensions that help with macro debugging. For now, +they are unstable and require feature gates. + +* `log_syntax!(...)` will print its arguments to standard output, at compile + time, and "expand" to nothing. + +* `trace_macros!(true)` will enable a compiler message every time a macro is + expanded. Use `trace_macros!(false)` later in expansion to turn it off. + # Further reading The [advanced macros chapter][] goes into more detail about macro syntax. It diff --git a/src/doc/trpl/plugins.md b/src/doc/trpl/plugins.md index 79502f3cd17f7..f609a0a918aa7 100644 --- a/src/doc/trpl/plugins.md +++ b/src/doc/trpl/plugins.md @@ -146,14 +146,7 @@ a more involved macro example, see ## Tips and tricks -To see the results of expanding syntax extensions, run -`rustc --pretty expanded`. The output represents a whole crate, so you -can also feed it back in to `rustc`, which will sometimes produce better -error messages than the original compilation. Note that the -`--pretty expanded` output may have a different meaning if multiple -variables of the same name (but different syntax contexts) are in play -in the same scope. In this case `--pretty expanded,hygiene` will tell -you about the syntax contexts. +Some of the [macro debugging tips](macros.html#debugging-macro-code) are applicable. You can use [`syntax::parse`](../syntax/parse/index.html) to turn token trees into higher-level syntax elements like expressions: @@ -184,6 +177,11 @@ and return [`DummyResult`](../syntax/ext/base/struct.DummyResult.html), so that the compiler can continue and find further errors. +To print syntax fragments for debugging, you can use +[`span_note`](../syntax/ext/base/struct.ExtCtxt.html#method.span_note) together +with +[`syntax::print::pprust::*_to_string`](http://doc.rust-lang.org/syntax/print/pprust/index.html#functions). + The example above produced an integer literal using [`AstBuilder::expr_uint`](../syntax/ext/build/trait.AstBuilder.html#tymethod.expr_uint). As an alternative to the `AstBuilder` trait, `libsyntax` provides a set of From 5d7e283ead6305b3b44caf212de23594f3a5dd8a Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 25 Feb 2015 01:35:41 +0100 Subject: [PATCH 32/39] Turn `unsafe_no_drop_flag` back into a gated-feature. Fix #22173 --- src/libsyntax/feature_gate.rs | 4 +++- .../compile-fail/unsafe_no_drop_flag-gate.rs | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/unsafe_no_drop_flag-gate.rs diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 32fd5b49f9a44..c1865ffa9d9a1 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -243,7 +243,9 @@ pub static KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[ ("static_assert", Whitelisted), ("no_debug", Whitelisted), ("omit_gdb_pretty_printer_section", Whitelisted), - ("unsafe_no_drop_flag", Whitelisted), + ("unsafe_no_drop_flag", Gated("unsafe_no_drop_flag", + "unsafe_no_drop_flag has unstable semantics \ + and may be removed in the future")), // used in resolve ("prelude_import", Whitelisted), diff --git a/src/test/compile-fail/unsafe_no_drop_flag-gate.rs b/src/test/compile-fail/unsafe_no_drop_flag-gate.rs new file mode 100644 index 0000000000000..542698fd15295 --- /dev/null +++ b/src/test/compile-fail/unsafe_no_drop_flag-gate.rs @@ -0,0 +1,23 @@ +// Copyright 2015 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. + +pub struct T; + +#[unsafe_no_drop_flag] +//~^ ERROR unsafe_no_drop_flag has unstable semantics and may be removed +pub struct S { + pub x: T, +} + +impl Drop for S { + fn drop(&mut self) {} +} + +pub fn main() {} From 91e00f3bfa1166665700a0c12f1697fbe74cddf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Wed, 25 Feb 2015 05:07:40 +0100 Subject: [PATCH 33/39] unbreak openbsd after nacl intergration --- src/liblibc/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 8d8f6a406f5d4..74a95b3aba056 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -1362,7 +1362,6 @@ pub mod types { use types::os::arch::c95::{c_long}; pub type off_t = i64; pub type dev_t = i32; - pub type ino_t = u64; pub type pid_t = i32; pub type uid_t = u32; pub type gid_t = u32; From f8e4fcb38c2ab0b5180c8fff35ad0454eb0667d7 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 25 Feb 2015 11:45:06 +0530 Subject: [PATCH 34/39] allow(deprecated) for TaskPool (fixup #22783) --- src/libstd/sync/mod.rs | 1 + src/libstd/sync/task_pool.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/libstd/sync/mod.rs b/src/libstd/sync/mod.rs index f3b721438d807..68137601c405c 100644 --- a/src/libstd/sync/mod.rs +++ b/src/libstd/sync/mod.rs @@ -31,6 +31,7 @@ pub use self::barrier::{Barrier, BarrierWaitResult}; pub use self::poison::{PoisonError, TryLockError, TryLockResult, LockResult}; pub use self::future::Future; +#[allow(deprecated)] pub use self::task_pool::TaskPool; pub mod mpsc; diff --git a/src/libstd/sync/task_pool.rs b/src/libstd/sync/task_pool.rs index e01f81452830d..efb6689e7855a 100644 --- a/src/libstd/sync/task_pool.rs +++ b/src/libstd/sync/task_pool.rs @@ -16,6 +16,8 @@ https://crates.io/crates/threadpool")] #![unstable(feature = "std_misc")] +#![allow(deprecated)] + use core::prelude::*; use sync::{Arc, Mutex}; From 9f8a1cb38d4d6dd16291aa0fd9f19e93e5263028 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 25 Feb 2015 12:48:14 +0530 Subject: [PATCH 35/39] Use os::getcwd instead of env in rustbook (fixup #22727) --- src/rustbook/build.rs | 5 +++-- src/rustbook/main.rs | 1 + src/rustbook/test.rs | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/rustbook/build.rs b/src/rustbook/build.rs index 9f35bdaa367e5..f36d97d6d120d 100644 --- a/src/rustbook/build.rs +++ b/src/rustbook/build.rs @@ -11,6 +11,7 @@ //! Implementation of the `build` subcommand, used to compile a book. use std::env; +use std::os; use std::old_io; use std::old_io::{fs, File, BufferedWriter, TempDir, IoResult}; @@ -81,7 +82,7 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> { let src; if env::args().len() < 3 { - src = env::current_dir().unwrap().clone(); + src = os::getcwd().unwrap().clone(); } else { src = Path::new(env::args().nth(2).unwrap().clone()); } @@ -149,7 +150,7 @@ impl Subcommand for Build { } fn usage(&self) {} fn execute(&mut self, term: &mut Term) -> CommandResult<()> { - let cwd = env::current_dir().unwrap(); + let cwd = os::getcwd().unwrap(); let src; let tgt; diff --git a/src/rustbook/main.rs b/src/rustbook/main.rs index 68e4ba54d94c1..b9fc011e8b9a5 100644 --- a/src/rustbook/main.rs +++ b/src/rustbook/main.rs @@ -13,6 +13,7 @@ #![feature(core)] #![feature(old_io)] #![feature(env)] +#![feature(os)] #![feature(old_path)] #![feature(rustdoc)] diff --git a/src/rustbook/test.rs b/src/rustbook/test.rs index bff366163dc2f..727a385a8f028 100644 --- a/src/rustbook/test.rs +++ b/src/rustbook/test.rs @@ -17,7 +17,7 @@ use error::Error; use term::Term; use book; use std::old_io::{Command, File}; -use std::env; +use std::os; struct Test; @@ -35,7 +35,7 @@ impl Subcommand for Test { } fn usage(&self) {} fn execute(&mut self, term: &mut Term) -> CommandResult<()> { - let cwd = env::current_dir().unwrap(); + let cwd = os::getcwd().unwrap(); let src = cwd.clone(); let summary = File::open(&src.join("SUMMARY.md")); From e61a790495f49580fc0ee831bb07e00b4750b04a Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 25 Feb 2015 13:58:58 +0530 Subject: [PATCH 36/39] Fix type inference error (fixup #22739) --- src/libstd/sys/windows/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 6e3b48a8f642e..5bb2a134533ed 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -198,7 +198,7 @@ pub fn set_nonblocking(fd: sock_t, nb: bool) { if unsafe { c::ioctlsocket(fd, c::FIONBIO, &mut set) } != 0 { // The above function should not return an error unless we passed it // invalid parameters. Panic on errors. - Err(last_error()).unwrap(); + panic!("set_nonblocking called with invalid parameters: {}", last_error()); } } From 2470fa155e8a0793d725891da2e6963c762fa674 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 25 Feb 2015 14:11:37 +0530 Subject: [PATCH 37/39] Assert is internal now (fixup #22739) --- src/libstd/sys/unix/pipe.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index 1446600a77ed7..33863d31437f3 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -145,7 +145,7 @@ impl UnixStream { fd: self.fd(), guard: unsafe { self.inner.lock.lock().unwrap() }, }; - assert!(set_nonblocking(self.fd(), true).is_ok()); + set_nonblocking(self.fd(), true); ret } From d54ed567e0714f6fac91b2f7f204a48a059b0f9f Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 25 Feb 2015 14:15:24 +0530 Subject: [PATCH 38/39] path -> PathBuf for osx/dragonfly (fixup #22727) --- src/libstd/sys/unix/os.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 951c091f9f36c..899280aa7094b 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -183,7 +183,7 @@ impl StdError for JoinPathsError { } #[cfg(target_os = "freebsd")] -pub fn current_exe() -> IoResult { +pub fn current_exe() -> io::Result { unsafe { use libc::funcs::bsd44::*; use libc::consts::os::extra::*; @@ -195,16 +195,16 @@ pub fn current_exe() -> IoResult { let err = sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint, ptr::null_mut(), &mut sz, ptr::null_mut(), 0 as libc::size_t); - if err != 0 { return Err(IoError::last_error()); } - if sz == 0 { return Err(IoError::last_error()); } + if err != 0 { return Err(io::Error::last_os_error()); } + if sz == 0 { return Err(io::Error::last_os_error()); } let mut v: Vec = Vec::with_capacity(sz as uint); let err = sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint, v.as_mut_ptr() as *mut libc::c_void, &mut sz, ptr::null_mut(), 0 as libc::size_t); - if err != 0 { return Err(IoError::last_error()); } - if sz == 0 { return Err(IoError::last_error()); } + if err != 0 { return Err(io::Error::last_os_error()); } + if sz == 0 { return Err(io::Error::last_os_error()); } v.set_len(sz as uint - 1); // chop off trailing NUL - Ok(Path::new(v)) + Ok(PathBuf::new::(&OsStringExt::from_vec(v))) } } @@ -227,7 +227,7 @@ pub fn current_exe() -> io::Result { unsafe { let v = rust_current_exe(); if v.is_null() { - Err(IoError::last_error()) + Err(io::Error::last_os_error()) } else { Ok(Path::new(CStr::from_ptr(v).to_bytes().to_vec())) } @@ -240,17 +240,17 @@ pub fn current_exe() -> io::Result { } #[cfg(any(target_os = "macos", target_os = "ios"))] -pub fn current_exe() -> IoResult { +pub fn current_exe() -> io::Result { unsafe { use libc::funcs::extra::_NSGetExecutablePath; let mut sz: u32 = 0; _NSGetExecutablePath(ptr::null_mut(), &mut sz); - if sz == 0 { return Err(IoError::last_error()); } + if sz == 0 { return Err(io::Error::last_os_error()); } let mut v: Vec = Vec::with_capacity(sz as uint); let err = _NSGetExecutablePath(v.as_mut_ptr() as *mut i8, &mut sz); - if err != 0 { return Err(IoError::last_error()); } + if err != 0 { return Err(io::Error::last_os_error()); } v.set_len(sz as uint - 1); // chop off trailing NUL - Ok(Path::new(v)) + Ok(PathBuf::new::(&OsStringExt::from_vec(v))) } } From 357b41bfcfcfd902d842a20f2c5858b8e196495d Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 25 Feb 2015 18:09:53 +0530 Subject: [PATCH 39/39] Path -> PathBuf for Windows test (fixup #22727) --- src/libstd/env.rs | 2 +- src/test/run-pass/env-home-dir.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 5db9f6ef7fdd4..e2849ec92e088 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -927,7 +927,7 @@ mod tests { fn split_paths_windows() { fn check_parse(unparsed: &str, parsed: &[&str]) -> bool { split_paths(unparsed).collect::>() == - parsed.iter().map(|s| Path::new(*s)).collect::>() + parsed.iter().map(|s| PathBuf::new(*s)).collect::>() } assert!(check_parse("", &mut [""])); diff --git a/src/test/run-pass/env-home-dir.rs b/src/test/run-pass/env-home-dir.rs index 2ab6feaf782f3..5d68a25a14ada 100644 --- a/src/test/run-pass/env-home-dir.rs +++ b/src/test/run-pass/env-home-dir.rs @@ -37,14 +37,14 @@ fn main() { assert!(home_dir().is_some()); set_var("HOME", "/home/MountainView"); - assert!(home_dir() == Some(Path::new("/home/MountainView"))); + assert!(home_dir() == Some(PathBuf::new("/home/MountainView"))); remove_var("HOME"); set_var("USERPROFILE", "/home/MountainView"); - assert!(home_dir() == Some(Path::new("/home/MountainView"))); + assert!(home_dir() == Some(PathBuf::new("/home/MountainView"))); set_var("HOME", "/home/MountainView"); set_var("USERPROFILE", "/home/PaloAlto"); - assert!(home_dir() == Some(Path::new("/home/MountainView"))); + assert!(home_dir() == Some(PathBuf::new("/home/MountainView"))); }