From 7c333e99bffd4d93a17b0db3495b30e0a8552b5b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 17 Mar 2015 16:45:56 -0700 Subject: [PATCH 01/18] std: Stabilize `IteratorExt::cloned` This commit stabilizes the `cloned` iterator after tweaking the signature to require that the iterator is over `&T` instead of `U: Deref`. This method has had time to bake for awhile now and it's not clear whether the `Deref` bound is worth it. Additionally, there aren't clear conventions on when to bound and/or implement the `Deref` trait, so for now the conservative route is to require references instead of `U: Deref`. To change this signature to using `Deref` would technically be a backwards-incompatible change, but it is doubtful that any code will actually break in practice. --- src/libcollectionstest/vec_deque.rs | 2 +- src/libcore/iter.rs | 45 ++++++++++++----------------- 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/src/libcollectionstest/vec_deque.rs b/src/libcollectionstest/vec_deque.rs index 38f358c150531..fe752d5a7e190 100644 --- a/src/libcollectionstest/vec_deque.rs +++ b/src/libcollectionstest/vec_deque.rs @@ -360,7 +360,7 @@ fn test_mut_rev_iter_wrap() { assert_eq!(d.pop_front(), Some(1)); d.push_back(4); - assert_eq!(d.iter_mut().rev().cloned().collect::>(), + assert_eq!(d.iter_mut().rev().map(|x| *x).collect::>(), vec![4, 3, 2]); } diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 8ebedb66851d5..4f8b1c21ab2e5 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -65,7 +65,7 @@ use default::Default; use marker; use mem; use num::{ToPrimitive, Int}; -use ops::{Add, Deref, FnMut, RangeFrom}; +use ops::{Add, FnMut, RangeFrom}; use option::Option; use option::Option::{Some, None}; use marker::Sized; @@ -976,12 +976,11 @@ pub trait IteratorExt: Iterator + Sized { (ts, us) } - /// Creates an iterator that clones the elements it yields. Useful for converting an - /// Iterator<&T> to an Iterator. - #[unstable(feature = "core", reason = "recent addition")] - fn cloned(self) -> Cloned where - Self::Item: Deref, - ::Target: Clone, + /// Creates an iterator that clones the elements it yields. Useful for + /// converting an Iterator<&T> to an Iterator. + #[stable(feature = "rust1", since = "1.0.0")] + fn cloned<'a, T: 'a>(self) -> Cloned + where Self: Iterator, T: Clone { Cloned { it: self } } @@ -1279,14 +1278,12 @@ pub struct Cloned { } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Cloned where - I: Iterator, - I::Item: Deref, - ::Target: Clone +impl<'a, I, T: 'a> Iterator for Cloned + where I: Iterator, T: Clone { - type Item = ::Target; + type Item = T; - fn next(&mut self) -> Option<::Item> { + fn next(&mut self) -> Option { self.it.next().cloned() } @@ -1296,28 +1293,22 @@ impl Iterator for Cloned where } #[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Cloned where - I: DoubleEndedIterator, - I::Item: Deref, - ::Target: Clone +impl<'a, I, T: 'a> DoubleEndedIterator for Cloned + where I: DoubleEndedIterator, T: Clone { - fn next_back(&mut self) -> Option<::Item> { + fn next_back(&mut self) -> Option { self.it.next_back().cloned() } } #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Cloned where - I: ExactSizeIterator, - I::Item: Deref, - ::Target: Clone +impl<'a, I, T: 'a> ExactSizeIterator for Cloned + where I: ExactSizeIterator, T: Clone {} #[unstable(feature = "core", reason = "trait is experimental")] -impl RandomAccessIterator for Cloned where - I: RandomAccessIterator, - I::Item: Deref, - ::Target: Clone +impl<'a, I, T: 'a> RandomAccessIterator for Cloned + where I: RandomAccessIterator, T: Clone { #[inline] fn indexable(&self) -> usize { @@ -1325,7 +1316,7 @@ impl RandomAccessIterator for Cloned where } #[inline] - fn idx(&mut self, index: usize) -> Option<::Item> { + fn idx(&mut self, index: usize) -> Option { self.it.idx(index).cloned() } } From 2e8e8ab564891c3d2ffeeb0f8e1a4e850866f74f Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 17 Mar 2015 23:05:44 -0700 Subject: [PATCH 02/18] Ignore stdio mutex poison state Nothing inside of the read/write interface itself can panic, so any poison must have been the result of user code which the lock isn't protecting. --- src/libstd/io/stdio.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 75d047d5c9c85..615607eed1ba5 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -146,7 +146,7 @@ impl Stdin { /// accessing the underlying data. #[stable(feature = "rust1", since = "1.0.0")] pub fn lock(&self) -> StdinLock { - StdinLock { inner: self.inner.lock().unwrap() } + StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) } } /// Locks this handle and reads a line of input into the specified buffer. @@ -249,7 +249,7 @@ impl Stdout { /// returned guard also implements the `Write` trait for writing data. #[stable(feature = "rust1", since = "1.0.0")] pub fn lock(&self) -> StdoutLock { - StdoutLock { inner: self.inner.lock().unwrap() } + StdoutLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) } } } @@ -319,7 +319,7 @@ impl Stderr { /// returned guard also implements the `Write` trait for writing data. #[stable(feature = "rust1", since = "1.0.0")] pub fn lock(&self) -> StderrLock { - StderrLock { inner: self.inner.lock().unwrap() } + StderrLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) } } } From 95a1e98fce4ea06f8a6de001dfdac28c268f9c29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Wed, 18 Mar 2015 10:59:09 +0100 Subject: [PATCH 03/18] openbsd/bitrig threads - remove `pub` from `struct` (visibility has no effect inside functions) - move `pthread_main_np` into function --- src/libstd/sys/unix/thread.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 045082949812b..c5f07c6c75a70 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -130,12 +130,13 @@ pub mod guard { #[cfg(any(target_os = "openbsd", target_os = "bitrig"))] pub unsafe fn current() -> usize { #[repr(C)] - pub struct stack_t { + struct stack_t { ss_sp: *mut libc::c_void, ss_size: libc::size_t, ss_flags: libc::c_int, } extern { + fn pthread_main_np() -> libc::c_uint; fn pthread_stackseg_np(thread: pthread_t, sinfo: *mut stack_t) -> libc::c_uint; } @@ -339,9 +340,6 @@ fn min_stack_size(_: *const libc::pthread_attr_t) -> libc::size_t { } extern { - #[cfg(any(target_os = "bitrig", target_os = "openbsd"))] - fn pthread_main_np() -> libc::c_uint; - fn pthread_self() -> libc::pthread_t; fn pthread_create(native: *mut libc::pthread_t, attr: *const libc::pthread_attr_t, From 2d701e6b1979b7ee0c50c51d1008b7c2138d5ec2 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Tue, 17 Mar 2015 23:00:55 +0200 Subject: [PATCH 04/18] Add {get,set}rlimit and getrusage to libc --- src/liblibc/lib.rs | 300 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 82c54004e9975..7d3268655a33d 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -131,6 +131,7 @@ pub use funcs::bsd43::*; #[cfg(unix)] pub use funcs::posix88::net::*; #[cfg(unix)] pub use funcs::posix01::stat_::*; #[cfg(unix)] pub use funcs::posix01::unistd::*; +#[cfg(unix)] pub use funcs::posix01::resource::*; #[cfg(windows)] pub use funcs::extra::kernel32::*; @@ -223,6 +224,7 @@ pub mod types { pub type pthread_t = c_ulong; #[cfg(target_os = "nacl")] pub type pthread_t = *mut c_void; + pub type rlim_t = u64; #[repr(C)] #[derive(Copy)] pub struct glob_t { @@ -252,7 +254,42 @@ pub mod types { #[derive(Copy)] pub enum timezone {} pub type sighandler_t = size_t; + + #[repr(C)] + #[derive(Copy)] + pub struct rlimit { + pub rlim_cur: rlim_t, + pub rlim_max: rlim_t, + } + } + + pub mod bsd43 { + use types::os::common::posix01::timeval; + use types::os::arch::c95::c_long; + // This is also specified in POSIX 2001, but only has two fields. All implementors + // implement BSD 4.3 version. + #[repr(C)] + #[derive(Copy)] + pub struct rusage { + pub ru_utime: timeval, + pub ru_stime: timeval, + pub ru_maxrss: c_long, + pub ru_ixrss: c_long, + pub ru_idrss: c_long, + pub ru_isrss: c_long, + pub ru_minflt: c_long, + pub ru_majflt: c_long, + pub ru_nswap: c_long, + pub ru_inblock: c_long, + pub ru_oublock: c_long, + pub ru_msgsnd: c_long, + pub ru_msgrcv: c_long, + pub ru_nsignals: c_long, + pub ru_nvcsw: c_long, + pub ru_nivcsw: c_long + } } + pub mod bsd44 { use types::common::c95::{c_void}; use types::os::arch::c95::{c_char, c_int, c_uint}; @@ -734,6 +771,7 @@ pub mod types { use types::os::arch::c99::{uintptr_t}; pub type pthread_t = uintptr_t; + pub type rlim_t = i64; #[repr(C)] #[derive(Copy)] pub struct glob_t { @@ -767,7 +805,40 @@ pub mod types { #[derive(Copy)] pub enum timezone {} pub type sighandler_t = size_t; + + #[repr(C)] + #[derive(Copy)] + pub struct rlimit { + pub rlim_cur: rlim_t, + pub rlim_max: rlim_t, + } + } + + pub mod bsd43 { + use types::os::common::posix01::timeval; + use types::os::arch::c95::c_long; + #[repr(C)] + #[derive(Copy)] + pub struct rusage { + pub ru_utime: timeval, + pub ru_stime: timeval, + pub ru_maxrss: c_long, + pub ru_ixrss: c_long, + pub ru_idrss: c_long, + pub ru_isrss: c_long, + pub ru_minflt: c_long, + pub ru_majflt: c_long, + pub ru_nswap: c_long, + pub ru_inblock: c_long, + pub ru_oublock: c_long, + pub ru_msgsnd: c_long, + pub ru_msgrcv: c_long, + pub ru_nsignals: c_long, + pub ru_nvcsw: c_long, + pub ru_nivcsw: c_long + } } + pub mod bsd44 { use types::common::c95::{c_void}; use types::os::arch::c95::{c_char, c_int, c_uint}; @@ -962,6 +1033,7 @@ pub mod types { use types::os::arch::c99::{uintptr_t}; pub type pthread_t = uintptr_t; + pub type rlim_t = i64; #[repr(C)] #[derive(Copy)] pub struct glob_t { @@ -995,7 +1067,40 @@ pub mod types { #[derive(Copy)] pub enum timezone {} pub type sighandler_t = size_t; + + #[repr(C)] + #[derive(Copy)] + pub struct rlimit { + pub rlim_cur: rlim_t, + pub rlim_max: rlim_t, + } } + + pub mod bsd43 { + use types::os::common::posix01::timeval; + use types::os::arch::c95::c_long; + #[repr(C)] + #[derive(Copy)] + pub struct rusage { + pub ru_utime: timeval, + pub ru_stime: timeval, + pub ru_maxrss: c_long, + pub ru_ixrss: c_long, + pub ru_idrss: c_long, + pub ru_isrss: c_long, + pub ru_minflt: c_long, + pub ru_majflt: c_long, + pub ru_nswap: c_long, + pub ru_inblock: c_long, + pub ru_oublock: c_long, + pub ru_msgsnd: c_long, + pub ru_msgrcv: c_long, + pub ru_nsignals: c_long, + pub ru_nvcsw: c_long, + pub ru_nivcsw: c_long + } + } + pub mod bsd44 { use types::common::c95::{c_void}; use types::os::arch::c95::{c_char, c_int, c_uint}; @@ -1189,6 +1294,7 @@ pub mod types { use types::os::arch::c99::{uintptr_t}; pub type pthread_t = uintptr_t; + pub type rlim_t = u64; #[cfg(target_os = "bitrig")] #[repr(C)] @@ -1241,7 +1347,40 @@ pub mod types { #[derive(Copy)] pub enum timezone {} pub type sighandler_t = size_t; + + #[repr(C)] + #[derive(Copy)] + pub struct rlimit { + pub rlim_cur: rlim_t, + pub rlim_max: rlim_t, + } + } + + pub mod bsd43 { + use types::os::common::posix01::timeval; + use types::os::arch::c95::c_long; + #[repr(C)] + #[derive(Copy)] + pub struct rusage { + pub ru_utime: timeval, + pub ru_stime: timeval, + pub ru_maxrss: c_long, + pub ru_ixrss: c_long, + pub ru_idrss: c_long, + pub ru_isrss: c_long, + pub ru_minflt: c_long, + pub ru_majflt: c_long, + pub ru_nswap: c_long, + pub ru_inblock: c_long, + pub ru_oublock: c_long, + pub ru_msgsnd: c_long, + pub ru_msgrcv: c_long, + pub ru_nsignals: c_long, + pub ru_nvcsw: c_long, + pub ru_nivcsw: c_long + } } + pub mod bsd44 { use types::common::c95::{c_void}; use types::os::arch::c95::{c_char, c_int, c_uint}; @@ -1840,6 +1979,7 @@ pub mod types { use types::os::arch::c99::{uintptr_t}; pub type pthread_t = uintptr_t; + pub type rlim_t = u64; #[repr(C)] #[derive(Copy)] pub struct glob_t { @@ -1873,6 +2013,38 @@ pub mod types { #[derive(Copy)] pub enum timezone {} pub type sighandler_t = size_t; + + #[repr(C)] + #[derive(Copy)] + pub struct rlimit { + pub rlim_cur: rlim_t, + pub rlim_max: rlim_t, + } + } + + pub mod bsd43 { + use types::os::common::posix01::timeval; + use types::os::arch::c95::c_long; + #[repr(C)] + #[derive(Copy)] + pub struct rusage { + pub ru_utime: timeval, + pub ru_stime: timeval, + pub ru_maxrss: c_long, + pub ru_ixrss: c_long, + pub ru_idrss: c_long, + pub ru_isrss: c_long, + pub ru_minflt: c_long, + pub ru_majflt: c_long, + pub ru_nswap: c_long, + pub ru_inblock: c_long, + pub ru_oublock: c_long, + pub ru_msgsnd: c_long, + pub ru_msgrcv: c_long, + pub ru_nsignals: c_long, + pub ru_nvcsw: c_long, + pub ru_nivcsw: c_long + } } pub mod bsd44 { @@ -3024,6 +3196,7 @@ pub mod consts { #[cfg(not(target_os = "nacl"))] pub mod posix01 { use types::os::arch::c95::{c_int, size_t}; + use types::os::common::posix01::rlim_t; pub const F_DUPFD : c_int = 0; pub const F_GETFD : c_int = 1; @@ -3102,10 +3275,36 @@ pub mod consts { pub const CLOCK_REALTIME: c_int = 0; pub const CLOCK_MONOTONIC: c_int = 1; + + pub const RLIMIT_CPU: c_int = 0; + pub const RLIMIT_FSIZE: c_int = 1; + pub const RLIMIT_DATA: c_int = 2; + pub const RLIMIT_STACK: c_int = 3; + pub const RLIMIT_CORE: c_int = 4; + pub const RLIMIT_RSS: c_int = 5; + pub const RLIMIT_NOFILE: c_int = 7; + pub const RLIMIT_AS: c_int = 9; + pub const RLIMIT_NPROC: c_int = 6; + pub const RLIMIT_MEMLOCK: c_int = 8; + pub const RLIMIT_LOCKS: c_int = 10; + pub const RLIMIT_SIGPENDING: c_int = 11; + pub const RLIMIT_MSGQUEUE: c_int = 12; + pub const RLIMIT_NICE: c_int = 13; + pub const RLIMIT_RTPRIO: c_int = 14; + pub const RLIMIT_RTTIME: c_int = 15; + pub const RLIMIT_NLIMITS: c_int = 16; + pub const RLIM_INFINITY: rlim_t = 0xffff_ffff_ffff_ffff; + pub const RLIM_SAVED_MAX: rlim_t = RLIM_INFINITY; + pub const RLIM_SAVED_CUR: rlim_t = RLIM_INFINITY; + + pub const RUSAGE_SELF: c_int = 0; + pub const RUSAGE_CHILDREN: c_int = -1; + pub const RUSAGE_THREAD: c_int = 1; } #[cfg(target_os = "nacl")] pub mod posix01 { use types::os::arch::c95::{c_int, size_t}; + use types::os::common::posix01::rlim_t; pub const F_DUPFD : c_int = 0; pub const F_GETFD : c_int = 1; @@ -3170,6 +3369,32 @@ pub mod consts { pub const CLOCK_REALTIME: c_int = 0; pub const CLOCK_MONOTONIC: c_int = 1; + + pub const RLIMIT_CPU: c_int = 0; + pub const RLIMIT_FSIZE: c_int = 1; + pub const RLIMIT_DATA: c_int = 2; + pub const RLIMIT_STACK: c_int = 3; + pub const RLIMIT_CORE: c_int = 4; + pub const RLIMIT_RSS: c_int = 5; + pub const RLIMIT_NOFILE: c_int = 7; + pub const RLIMIT_AS: c_int = 9; + pub const RLIMIT_NPROC: c_int = 6; + pub const RLIMIT_MEMLOCK: c_int = 8; + pub const RLIMIT_LOCKS: c_int = 10; + pub const RLIMIT_SIGPENDING: c_int = 11; + pub const RLIMIT_MSGQUEUE: c_int = 12; + pub const RLIMIT_NICE: c_int = 13; + pub const RLIMIT_RTPRIO: c_int = 14; + pub const RLIMIT_RTTIME: c_int = 15; + pub const RLIMIT_NLIMITS: c_int = 16; + + pub const RLIM_INFINITY: rlim_t = 0xffff_ffff_ffff_ffff; + pub const RLIM_SAVED_MAX: rlim_t = RLIM_INFINITY; + pub const RLIM_SAVED_CUR: rlim_t = RLIM_INFINITY; + + pub const RUSAGE_SELF: c_int = 0; + pub const RUSAGE_CHILDREN: c_int = -1; + pub const RUSAGE_THREAD: c_int = 1; } pub mod posix08 { } @@ -3632,6 +3857,7 @@ pub mod consts { } pub mod posix01 { use types::os::arch::c95::{c_int, size_t}; + use types::os::common::posix01::rlim_t; pub const F_DUPFD : c_int = 0; pub const F_GETFD : c_int = 1; @@ -3707,6 +3933,29 @@ pub mod consts { pub const CLOCK_REALTIME: c_int = 0; pub const CLOCK_MONOTONIC: c_int = 4; + + pub const RLIMIT_CPU: c_int = 0; + pub const RLIMIT_FSIZE: c_int = 1; + pub const RLIMIT_DATA: c_int = 2; + pub const RLIMIT_STACK: c_int = 3; + pub const RLIMIT_CORE: c_int = 4; + pub const RLIMIT_RSS: c_int = 5; + pub const RLIMIT_MEMLOCK: c_int = 6; + pub const RLIMIT_NPROC: c_int = 7; + pub const RLIMIT_NOFILE: c_int = 8; + pub const RLIMIT_SBSIZE: c_int = 9; + pub const RLIMIT_VMEM: c_int = 10; + pub const RLIMIT_AS: c_int = RLIMIT_VMEM; + pub const RLIMIT_NPTS: c_int = 11; + pub const RLIMIT_SWAP: c_int = 12; + pub const RLIMIT_KQUEUES: c_int = 13; + + pub const RLIM_NLIMITS: rlim_t = 14; + pub const RLIM_INFINITY: rlim_t = 0x7fff_ffff_ffff_ffff; + + pub const RUSAGE_SELF: c_int = 0; + pub const RUSAGE_CHILDREN: c_int = -1; + pub const RUSAGE_THREAD: c_int = 1; } pub mod posix08 { } @@ -4032,6 +4281,7 @@ pub mod consts { } pub mod posix01 { use types::os::arch::c95::{c_int, size_t}; + use types::os::common::posix01::rlim_t; pub const F_DUPFD : c_int = 0; pub const F_GETFD : c_int = 1; @@ -4101,6 +4351,25 @@ pub mod consts { pub const CLOCK_REALTIME : c_int = 0; pub const CLOCK_MONOTONIC : c_int = 3; + + pub const RLIMIT_CPU: c_int = 0; + pub const RLIMIT_FSIZE: c_int = 1; + pub const RLIMIT_DATA: c_int = 2; + pub const RLIMIT_STACK: c_int = 3; + pub const RLIMIT_CORE: c_int = 4; + pub const RLIMIT_RSS: c_int = 5; + pub const RLIMIT_MEMLOCK: c_int = 6; + pub const RLIMIT_NPROC: c_int = 7; + pub const RLIMIT_NOFILE: c_int = 8; + pub const RLIM_NLIMITS: c_int = 9; + + pub const RLIM_INFINITY: rlim_t = 0x7fff_ffff_ffff_ffff; + pub const RLIM_SAVED_MAX: rlim_t = RLIM_INFINITY; + pub const RLIM_SAVED_CUR: rlim_t = RLIM_INFINITY; + + pub const RUSAGE_SELF: c_int = 0; + pub const RUSAGE_CHILDREN: c_int = -1; + pub const RUSAGE_THREAD: c_int = 1; } pub mod posix08 { } @@ -4428,6 +4697,7 @@ pub mod consts { } pub mod posix01 { use types::os::arch::c95::{c_int, size_t}; + use types::os::common::posix01::rlim_t; pub const F_DUPFD : c_int = 0; pub const F_GETFD : c_int = 1; @@ -4488,6 +4758,24 @@ pub mod consts { pub const PTHREAD_CREATE_JOINABLE: c_int = 1; pub const PTHREAD_CREATE_DETACHED: c_int = 2; pub const PTHREAD_STACK_MIN: size_t = 8192; + + pub const RLIMIT_CPU: c_int = 0; + pub const RLIMIT_FSIZE: c_int = 1; + pub const RLIMIT_DATA: c_int = 2; + pub const RLIMIT_STACK: c_int = 3; + pub const RLIMIT_CORE: c_int = 4; + pub const RLIMIT_AS: c_int = 5; + pub const RLIMIT_MEMLOCK: c_int = 6; + pub const RLIMIT_NPROC: c_int = 7; + pub const RLIMIT_NOFILE: c_int = 8; + pub const RLIM_NLIMITS: c_int = 9; + pub const _RLIMIT_POSIX_FLAG: c_int = 0x1000; + + pub const RLIM_INFINITY: rlim_t = 0xffff_ffff_ffff_ffff; + + pub const RUSAGE_SELF: c_int = 0; + pub const RUSAGE_CHILDREN: c_int = -1; + pub const RUSAGE_THREAD: c_int = 1; } pub mod posix08 { } @@ -5348,6 +5636,18 @@ pub mod funcs { -> c_int; } } + + pub mod resource { + use types::os::arch::c95::c_int; + use types::os::common::posix01::rlimit; + use types::os::common::bsd43::rusage; + extern { + pub fn getrlimit(resource: c_int, rlim: *mut rlimit) -> c_int; + pub fn setrlimit(resource: c_int, rlim: *const rlimit) -> c_int; + pub fn getrusage(resource: c_int, usage: *mut rusage) -> c_int; + + } + } } #[cfg(target_os = "windows")] From 07c7bb9938b80dc19078183c966e9545c7dd2863 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Wed, 18 Mar 2015 14:36:23 +0200 Subject: [PATCH 05/18] Make it clear which value is discarded --- src/libcore/result.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 7732ff5f9b995..a5b2fddfd5df6 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -330,7 +330,7 @@ impl Result { /// Convert from `Result` to `Option` /// /// Converts `self` into an `Option`, consuming `self`, - /// and discarding the value, if any. + /// and discarding the success value, if any. /// /// # Examples /// From 21d8c418d2770365716ef2750af72b93f3008c6e Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Wed, 18 Mar 2015 08:15:53 -0700 Subject: [PATCH 06/18] iOS: fallout from 1d5983a --- src/libstd/sys/unix/os.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 75aeafe6e3c90..a5a2f71acb7e0 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -306,12 +306,11 @@ pub fn args() -> Args { // In general it looks like: // res = Vec::new() // let args = [[NSProcessInfo processInfo] arguments] -// for i in range(0, [args count]) +// for i in (0..[args count]) // res.push([args objectAtIndex:i]) // res #[cfg(target_os = "ios")] pub fn args() -> Args { - use iter::range; use mem; #[link(name = "objc")] @@ -341,7 +340,7 @@ pub fn args() -> Args { let args = objc_msgSend(info, arguments_sel); let cnt: int = mem::transmute(objc_msgSend(args, count_sel)); - for i in range(0, cnt) { + for i in (0..cnt) { let tmp = objc_msgSend(args, object_at_sel, i); let utf_c_str: *const libc::c_char = mem::transmute(objc_msgSend(tmp, utf8_sel)); From a51cd6116446d74a336abcb00f5ced3582ec307f Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 18 Mar 2015 09:03:17 -0700 Subject: [PATCH 07/18] Add a test --- src/libstd/io/stdio.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 615607eed1ba5..9b36408aa5116 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -402,3 +402,29 @@ pub fn _print(args: fmt::Arguments) { panic!("failed printing to stdout: {}", e); } } + +#[cfg(test)] +mod test { + use thread; + use super::*; + + #[test] + fn panic_doesnt_poison() { + thread::spawn(|| { + let _a = stdin(); + let _a = _a.lock(); + let _a = stdout(); + let _a = _a.lock(); + let _a = stderr(); + let _a = _a.lock(); + panic!(); + }).join().unwrap_err(); + + let _a = stdin(); + let _a = _a.lock(); + let _a = stdout(); + let _a = _a.lock(); + let _a = stderr(); + let _a = _a.lock(); + } +} From c225824bded695c8bced713f5a4c62fe327277bc Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 18 Mar 2015 09:22:38 -0400 Subject: [PATCH 08/18] Require braces when a closure has an explicit return type. This is a [breaking-change]: instead of a closure like `|| -> i32 22`, prefer `|| -> i32 { 22 }`. Fixes #23420. --- src/libsyntax/parse/mod.rs | 5 +-- src/libsyntax/parse/parser.rs | 36 +++++++++++-------- src/libsyntax/print/pprust.rs | 7 +++- src/test/compile-fail/fn-trait-formatting.rs | 2 +- src/test/compile-fail/liveness-issue-2163.rs | 2 +- src/test/parse-fail/closure-return-syntax.rs | 16 +++++++++ src/test/run-pass/block-explicit-types.rs | 2 +- .../run-pass/borrowck-move-by-capture-ok.rs | 2 +- src/test/run-pass/issue-17816.rs | 2 +- 9 files changed, 52 insertions(+), 22 deletions(-) create mode 100644 src/test/parse-fail/closure-return-syntax.rs diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 82ba873e54b95..968d2fd7e2a47 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -404,7 +404,7 @@ pub fn char_lit(lit: &str) -> (char, isize) { .map(|x| (x, len as isize)) } - let unicode_escape = || -> Option<(char, isize)> + let unicode_escape = || -> Option<(char, isize)> { if lit.as_bytes()[2] == b'{' { let idx = lit.find('}').expect(msg2); let subslice = &lit[3..idx]; @@ -413,7 +413,8 @@ pub fn char_lit(lit: &str) -> (char, isize) { .map(|x| (x, subslice.chars().count() as isize + 4)) } else { esc(6, lit) - }; + } + }; // Unicode escapes return match lit.as_bytes()[1] as char { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index bf2b2c0afe6c3..d76355f9af00d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2101,10 +2101,7 @@ impl<'a> Parser<'a> { } }, token::OpenDelim(token::Brace) => { - self.bump(); - let blk = self.parse_block_tail(lo, DefaultBlock); - return self.mk_expr(blk.span.lo, blk.span.hi, - ExprBlock(blk)); + return self.parse_block_expr(lo, DefaultBlock); }, token::BinOp(token::Or) | token::OrOr => { return self.parse_lambda_expr(CaptureByRef); @@ -3000,19 +2997,30 @@ impl<'a> Parser<'a> { { let lo = self.span.lo; let decl = self.parse_fn_block_decl(); - let body = self.parse_expr(); - let fakeblock = P(ast::Block { - id: ast::DUMMY_NODE_ID, - stmts: vec![], - span: body.span, - expr: Some(body), - rules: DefaultBlock, - }); + let body = match decl.output { + DefaultReturn(_) => { + // If no explicit return type is given, parse any + // expr and wrap it up in a dummy block: + let body_expr = self.parse_expr(); + P(ast::Block { + id: ast::DUMMY_NODE_ID, + stmts: vec![], + span: body_expr.span, + expr: Some(body_expr), + rules: DefaultBlock, + }) + } + _ => { + // If an explicit return type is given, require a + // block to appear (RFC 968). + self.parse_block() + } + }; self.mk_expr( lo, - fakeblock.span.hi, - ExprClosure(capture_clause, decl, fakeblock)) + body.span.hi, + ExprClosure(capture_clause, decl, body)) } pub fn parse_else_expr(&mut self) -> P { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 07303ba51ff70..b58c121c5fd54 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1777,7 +1777,12 @@ impl<'a> State<'a> { try!(self.print_fn_block_args(&**decl)); try!(space(&mut self.s)); - if !body.stmts.is_empty() || !body.expr.is_some() { + let default_return = match decl.output { + ast::DefaultReturn(..) => true, + _ => false + }; + + if !default_return || !body.stmts.is_empty() || body.expr.is_none() { try!(self.print_block_unclosed(&**body)); } else { // we extract the block, so as not to create another set of boxes diff --git a/src/test/compile-fail/fn-trait-formatting.rs b/src/test/compile-fail/fn-trait-formatting.rs index d682ef7d70c9d..35c551931366d 100644 --- a/src/test/compile-fail/fn-trait-formatting.rs +++ b/src/test/compile-fail/fn-trait-formatting.rs @@ -26,7 +26,7 @@ fn main() { //~| found `Box` //~| expected () //~| found box - let _: () = (box || -> isize unimplemented!()) as Box isize>; + let _: () = (box || -> isize { unimplemented!() }) as Box isize>; //~^ ERROR mismatched types //~| expected `()` //~| found `Box isize>` diff --git a/src/test/compile-fail/liveness-issue-2163.rs b/src/test/compile-fail/liveness-issue-2163.rs index 69bceec8c3225..7c94e33b47b38 100644 --- a/src/test/compile-fail/liveness-issue-2163.rs +++ b/src/test/compile-fail/liveness-issue-2163.rs @@ -13,6 +13,6 @@ use std::vec::Vec; fn main() { let a: Vec = Vec::new(); a.iter().all(|_| -> bool { - //~^ ERROR mismatched types + //~^ ERROR not all control paths return a value }); } diff --git a/src/test/parse-fail/closure-return-syntax.rs b/src/test/parse-fail/closure-return-syntax.rs new file mode 100644 index 0000000000000..da6245597f8f4 --- /dev/null +++ b/src/test/parse-fail/closure-return-syntax.rs @@ -0,0 +1,16 @@ +// 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. + +// Test that we cannot parse a closure with an explicit return type +// unless it uses braces. + +fn main() { + let x = || -> i32 22; //~ ERROR expected `{`, found `22` +} diff --git a/src/test/run-pass/block-explicit-types.rs b/src/test/run-pass/block-explicit-types.rs index 54b650d762bf4..835d356d8aaa1 100644 --- a/src/test/run-pass/block-explicit-types.rs +++ b/src/test/run-pass/block-explicit-types.rs @@ -10,5 +10,5 @@ pub fn main() { fn as_buf(s: String, f: F) -> T where F: FnOnce(String) -> T { f(s) } - as_buf("foo".to_string(), |foo: String| -> () println!("{}", foo) ); + as_buf("foo".to_string(), |foo: String| -> () { println!("{}", foo) }); } diff --git a/src/test/run-pass/borrowck-move-by-capture-ok.rs b/src/test/run-pass/borrowck-move-by-capture-ok.rs index 269063bbd05b6..4364391cf0c60 100644 --- a/src/test/run-pass/borrowck-move-by-capture-ok.rs +++ b/src/test/run-pass/borrowck-move-by-capture-ok.rs @@ -14,6 +14,6 @@ pub fn main() { let bar: Box<_> = box 3; - let h = || -> int *bar; + let h = || -> int { *bar }; assert_eq!(h(), 3); } diff --git a/src/test/run-pass/issue-17816.rs b/src/test/run-pass/issue-17816.rs index a976eccf89ec4..8e3cb414566c7 100644 --- a/src/test/run-pass/issue-17816.rs +++ b/src/test/run-pass/issue-17816.rs @@ -14,7 +14,7 @@ use std::marker::PhantomData; fn main() { struct Symbol<'a, F: Fn(Vec<&'a str>) -> &'a str> { function: F, marker: PhantomData<&'a ()> } - let f = |x: Vec<&str>| -> &str "foobar"; + let f = |x: Vec<&str>| -> &str { "foobar" }; let sym = Symbol { function: f, marker: PhantomData }; (sym.function)(vec![]); } From da96d22d3a8bd4ad74e797b823dd10a34d88991e Mon Sep 17 00:00:00 2001 From: Johannes Oertel Date: Wed, 18 Mar 2015 22:34:40 +0100 Subject: [PATCH 09/18] Rename should_fail to should_panic in docs --- src/doc/reference.md | 2 +- src/doc/trpl/functions.md | 2 +- src/doc/trpl/testing.md | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index 3fae49bfc6d3e..92573d7921773 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -2068,7 +2068,7 @@ type int8_t = i8; item](#language-items) for more details. - `test` - indicates that this function is a test function, to only be compiled in case of `--test`. -- `should_fail` - indicates that this test function should panic, inverting the success condition. +- `should_panic` - indicates that this test function should panic, inverting the success condition. - `cold` - The function is unlikely to be executed, so optimize it (and calls to it) differently. diff --git a/src/doc/trpl/functions.md b/src/doc/trpl/functions.md index ca1385fde9c74..8e8ee8d63d626 100644 --- a/src/doc/trpl/functions.md +++ b/src/doc/trpl/functions.md @@ -179,7 +179,7 @@ Because this function will cause a crash, it will never return, and so it has the type '`!`', which is read "diverges." A diverging function can be used as any type: -```should_fail +```should_panic # fn diverges() -> ! { # panic!("This function never returns!"); # } diff --git a/src/doc/trpl/testing.md b/src/doc/trpl/testing.md index 537e100d7d830..72e9ec9f7509a 100644 --- a/src/doc/trpl/testing.md +++ b/src/doc/trpl/testing.md @@ -129,11 +129,11 @@ $ echo $? This is useful if you want to integrate `cargo test` into other tooling. -We can invert our test's failure with another attribute: `should_fail`: +We can invert our test's failure with another attribute: `should_panic`: ```rust #[test] -#[should_fail] +#[should_panic] fn it_works() { assert!(false); } @@ -163,13 +163,13 @@ equality: ```rust #[test] -#[should_fail] +#[should_panic] fn it_works() { assert_eq!("Hello", "world"); } ``` -Does this test pass or fail? Because of the `should_fail` attribute, it +Does this test pass or fail? Because of the `should_panic` attribute, it passes: ```bash @@ -189,15 +189,15 @@ running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured ``` -`should_fail` tests can be fragile, as it's hard to guarantee that the test +`should_panic` tests can be fragile, as it's hard to guarantee that the test didn't fail for an unexpected reason. To help with this, an optional `expected` -parameter can be added to the `should_fail` attribute. The test harness will +parameter can be added to the `should_panic` attribute. The test harness will make sure that the failure message contains the provided text. A safer version of the example above would be: ``` #[test] -#[should_fail(expected = "assertion failed")] +#[should_panic(expected = "assertion failed")] fn it_works() { assert_eq!("Hello", "world"); } From 351721cde6534d0a20bda8cbacc0019fca6caf3f Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 18 Mar 2015 19:00:51 -0400 Subject: [PATCH 10/18] Small formatting fixes to fmt.rs --- src/libcollections/fmt.rs | 45 ++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/libcollections/fmt.rs b/src/libcollections/fmt.rs index 1deb08ad0d1c4..fbd07e48a84db 100644 --- a/src/libcollections/fmt.rs +++ b/src/libcollections/fmt.rs @@ -16,7 +16,7 @@ //! This macro is implemented in the compiler to emit calls to this module in //! order to format arguments at runtime into strings and streams. //! -//! ## Usage +//! # Usage //! //! The `format!` macro is intended to be familiar to those coming from C's //! printf/fprintf functions or Python's `str.format` function. In its current @@ -41,7 +41,7 @@ //! will then parse the format string and determine if the list of arguments //! provided is suitable to pass to this format string. //! -//! ### Positional parameters +//! ## Positional parameters //! //! Each formatting argument is allowed to specify which value argument it's //! referencing, and if omitted it is assumed to be "the next argument". For @@ -54,7 +54,7 @@ //! iterator over the argument. Each time a "next argument" specifier is seen, //! the iterator advances. This leads to behavior like this: //! -//! ```rust +//! ``` //! format!("{1} {} {0} {}", 1, 2); // => "2 1 1 2" //! ``` //! @@ -68,7 +68,7 @@ //! compile-time error. You may refer to the same argument more than once in the //! format string, although it must always be referred to with the same type. //! -//! ### Named parameters +//! ## Named parameters //! //! Rust itself does not have a Python-like equivalent of named parameters to a //! function, but the `format!` macro is a syntax extension which allows it to @@ -91,7 +91,7 @@ //! arguments which have names. Like with positional parameters, it is illegal //! to provide named parameters that are unused by the format string. //! -//! ### Argument types +//! ## Argument types //! //! Each argument's type is dictated by the format string. It is a requirement //! that every argument is only ever referred to by one type. For example, this @@ -116,7 +116,7 @@ //! {:.*} {0} //! ``` //! -//! ### Formatting traits +//! ## Formatting traits //! //! When requesting that an argument be formatted with a particular type, you //! are actually requesting that an argument ascribes to a particular trait. @@ -142,7 +142,7 @@ //! When implementing a format trait for your own type, you will have to //! implement a method of the signature: //! -//! ```rust +//! ``` //! # use std::fmt; //! # struct Foo; // our custom type //! # impl fmt::Display for Foo { @@ -166,7 +166,7 @@ //! An example of implementing the formatting traits would look //! like: //! -//! ```rust +//! ``` //! use std::fmt; //! use std::f64; //! use std::num::Float; @@ -211,7 +211,7 @@ //! } //! ``` //! -//! #### fmt::Display vs fmt::Debug +//! ### fmt::Display vs fmt::Debug //! //! These two formatting traits have distinct purposes: //! @@ -231,7 +231,7 @@ //! assert_eq!(format!("{} {:?}", "foo\n", "bar\n"), "foo\n \"bar\\n\""); //! ``` //! -//! ### Related macros +//! ## Related macros //! //! There are a number of related macros in the `format!` family. The ones that //! are currently implemented are: @@ -245,7 +245,7 @@ //! format_args! // described below. //! ``` //! -//! #### `write!` +//! ### `write!` //! //! This and `writeln` are two macros which are used to emit the format string //! to a specified stream. This is used to prevent intermediate allocations of @@ -253,24 +253,25 @@ //! function is actually invoking the `write` function defined in this module. //! Example usage is: //! -//! ```rust +//! ``` //! # #![allow(unused_must_use)] //! let mut w = Vec::new(); //! write!(&mut w, "Hello {}!", "world"); //! ``` //! -//! #### `print!` +//! ### `print!` //! //! This and `println` emit their output to stdout. Similarly to the `write!` //! macro, the goal of these macros is to avoid intermediate allocations when //! printing output. Example usage is: //! -//! ```rust +//! ``` //! print!("Hello {}!", "world"); //! println!("I have a newline {}", "character at the end"); //! ``` //! -//! #### `format_args!` +//! ### `format_args!` +//! //! This is a curious macro which is used to safely pass around //! an opaque object describing the format string. This object //! does not require any heap allocations to create, and it only @@ -303,7 +304,7 @@ //! it would internally pass around this structure until it has been determined //! where output should go to. //! -//! ## Syntax +//! # Syntax //! //! The syntax for the formatting language used is drawn from other languages, //! so it should not be too alien. Arguments are formatted with python-like @@ -326,14 +327,14 @@ //! parameter := integer '$' //! ``` //! -//! ## Formatting Parameters +//! # Formatting Parameters //! //! Each argument being formatted can be transformed by a number of formatting //! parameters (corresponding to `format_spec` in the syntax above). These //! parameters affect the string representation of what's being formatted. This //! syntax draws heavily from Python's, so it may seem a bit familiar. //! -//! ### Fill/Alignment +//! ## Fill/Alignment //! //! The fill character is provided normally in conjunction with the `width` //! parameter. This indicates that if the value being formatted is smaller than @@ -345,7 +346,7 @@ //! * `^` - the argument is center-aligned in `width` columns //! * `>` - the argument is right-aligned in `width` columns //! -//! ### Sign/#/0 +//! ## Sign/#/0 //! //! These can all be interpreted as flags for a particular formatter. //! @@ -368,7 +369,7 @@ //! same format would yield `-0000001` for the integer `-1`. Notice that //! the negative version has one fewer zero than the positive version. //! -//! ### Width +//! ## Width //! //! This is a parameter for the "minimum width" that the format should take up. //! If the value's string does not fill up this many characters, then the @@ -384,7 +385,7 @@ //! parameters by using the `2$` syntax indicating that the second argument is a //! `usize` specifying the width. //! -//! ### Precision +//! ## Precision //! //! For non-numeric types, this can be considered a "maximum width". If the //! resulting string is longer than this width, then it is truncated down to @@ -395,7 +396,7 @@ //! For floating-point types, this indicates how many digits after the decimal //! point should be printed. //! -//! ## Escaping +//! # Escaping //! //! The literal characters `{` and `}` may be included in a string by preceding //! them with the same character. For example, the `{` character is escaped with From 8a8b2cecbc1fab7ffa4a20efb6dc4deed876571e Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 18 Mar 2015 19:15:26 -0400 Subject: [PATCH 11/18] Document {:.*} Fixes #22927 --- src/libcollections/fmt.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/libcollections/fmt.rs b/src/libcollections/fmt.rs index fbd07e48a84db..d2abb59ffabc5 100644 --- a/src/libcollections/fmt.rs +++ b/src/libcollections/fmt.rs @@ -105,11 +105,18 @@ //! hexadecimal as well as an //! octal. //! -//! There are various parameters which do require a particular type, however. -//! Namely if the syntax `{:.*}` is used, then the number of characters to print -//! precedes the actual object being formatted, and the number of characters -//! must have the type `usize`. Although a `usize` can be printed with `{}`, it is -//! illegal to reference an argument as such. For example this is another +//! There are various parameters which do require a particular type, however. Namely, the `{:.*}` +//! syntax, which sets the number of numbers after the decimal in floating-point types: +//! +//! ``` +//! let formatted_number = format!("{:.*}", 2, 1.234567); +//! +//! assert_eq!("1.23", formatted_number) +//! ``` +//! +//! If this syntax is used, then the number of characters to print precedes the actual object being +//! formatted, and the number of characters must have the type `usize`. Although a `usize` can be +//! printed with `{}`, it is illegal to reference an argument as such. For example this is another //! invalid format string: //! //! ```text From 835c9bbbf049de2b6b37b3f2cf14b44de21c2ec5 Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 18 Mar 2015 19:36:23 -0400 Subject: [PATCH 12/18] Update ast.rs Typo --- src/libsyntax/ast.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 5c2757153521c..5a32045db4adc 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1155,7 +1155,7 @@ pub enum Lit_ { LitByte(u8), /// A character literal (`'a'`) LitChar(char), - /// An integer liteal (`1u8`) + /// An integer literal (`1u8`) LitInt(u64, LitIntType), /// A float literal (`1f64` or `1E10f64`) LitFloat(InternedString, FloatTy), From 592e7ffdf8894c928d8661cca32b0b2395762ec2 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 18 Mar 2015 16:44:37 -0700 Subject: [PATCH 13/18] core: Inline most cell methods. This is a significant performance problem in Servo. --- src/libcore/cell.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 4f77a20c7cac8..e3a7f23851cde 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -168,6 +168,7 @@ impl Cell { /// let c = Cell::new(5); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn new(value: T) -> Cell { Cell { value: UnsafeCell::new(value), @@ -237,6 +238,7 @@ unsafe impl Send for Cell where T: Send {} #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Cell { + #[inline] fn clone(&self) -> Cell { Cell::new(self.get()) } @@ -245,6 +247,7 @@ impl Clone for Cell { #[stable(feature = "rust1", since = "1.0.0")] impl Default for Cell { #[stable(feature = "rust1", since = "1.0.0")] + #[inline] fn default() -> Cell { Cell::new(Default::default()) } @@ -252,6 +255,7 @@ impl Default for Cell { #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for Cell { + #[inline] fn eq(&self, other: &Cell) -> bool { self.get() == other.get() } @@ -295,6 +299,7 @@ impl RefCell { /// let c = RefCell::new(5); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn new(value: T) -> RefCell { RefCell { value: UnsafeCell::new(value), @@ -314,6 +319,7 @@ impl RefCell { /// let five = c.into_inner(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn into_inner(self) -> T { // Since this function takes `self` (the `RefCell`) by value, the // compiler statically verifies that it is not currently borrowed. @@ -327,6 +333,7 @@ impl RefCell { /// The returned value can be dispatched on to determine if a call to /// `borrow` or `borrow_mut` would succeed. #[unstable(feature = "std_misc")] + #[inline] pub fn borrow_state(&self) -> BorrowState { match self.borrow.get() { WRITING => BorrowState::Writing, @@ -344,6 +351,7 @@ impl RefCell { #[unstable(feature = "core", reason = "may be renamed or removed")] #[deprecated(since = "1.0.0", reason = "dispatch on `cell.borrow_state()` instead")] + #[inline] pub fn try_borrow<'a>(&'a self) -> Option> { match BorrowRef::new(&self.borrow) { Some(b) => Some(Ref { _value: unsafe { &*self.value.get() }, _borrow: b }), @@ -387,6 +395,7 @@ impl RefCell { /// assert!(result.is_err()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn borrow<'a>(&'a self) -> Ref<'a, T> { match BorrowRef::new(&self.borrow) { Some(b) => Ref { @@ -406,6 +415,7 @@ impl RefCell { #[unstable(feature = "core", reason = "may be renamed or removed")] #[deprecated(since = "1.0.0", reason = "dispatch on `cell.borrow_state()` instead")] + #[inline] pub fn try_borrow_mut<'a>(&'a self) -> Option> { match BorrowRefMut::new(&self.borrow) { Some(b) => Some(RefMut { _value: unsafe { &mut *self.value.get() }, _borrow: b }), @@ -448,6 +458,7 @@ impl RefCell { /// assert!(result.is_err()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> { match BorrowRefMut::new(&self.borrow) { Some(b) => RefMut { @@ -475,6 +486,7 @@ unsafe impl Send for RefCell where T: Send {} #[stable(feature = "rust1", since = "1.0.0")] impl Clone for RefCell { + #[inline] fn clone(&self) -> RefCell { RefCell::new(self.borrow().clone()) } @@ -483,6 +495,7 @@ impl Clone for RefCell { #[stable(feature = "rust1", since = "1.0.0")] impl Default for RefCell { #[stable(feature = "rust1", since = "1.0.0")] + #[inline] fn default() -> RefCell { RefCell::new(Default::default()) } @@ -490,6 +503,7 @@ impl Default for RefCell { #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for RefCell { + #[inline] fn eq(&self, other: &RefCell) -> bool { *self.borrow() == *other.borrow() } @@ -500,6 +514,7 @@ struct BorrowRef<'b> { } impl<'b> BorrowRef<'b> { + #[inline] fn new(borrow: &'b Cell) -> Option> { match borrow.get() { WRITING => None, @@ -513,6 +528,7 @@ impl<'b> BorrowRef<'b> { #[unsafe_destructor] impl<'b> Drop for BorrowRef<'b> { + #[inline] fn drop(&mut self) { let borrow = self._borrow.get(); debug_assert!(borrow != WRITING && borrow != UNUSED); @@ -521,6 +537,7 @@ impl<'b> Drop for BorrowRef<'b> { } impl<'b> Clone for BorrowRef<'b> { + #[inline] fn clone(&self) -> BorrowRef<'b> { // Since this Ref exists, we know the borrow flag // is not set to WRITING. @@ -561,6 +578,7 @@ impl<'b, T> Deref for Ref<'b, T> { /// use of `r.borrow().clone()` to clone the contents of a `RefCell`. #[unstable(feature = "core", reason = "likely to be moved to a method, pending language changes")] +#[inline] pub fn clone_ref<'b, T:Clone>(orig: &Ref<'b, T>) -> Ref<'b, T> { Ref { _value: orig._value, @@ -574,6 +592,7 @@ struct BorrowRefMut<'b> { #[unsafe_destructor] impl<'b> Drop for BorrowRefMut<'b> { + #[inline] fn drop(&mut self) { let borrow = self._borrow.get(); debug_assert!(borrow == WRITING); @@ -582,6 +601,7 @@ impl<'b> Drop for BorrowRefMut<'b> { } impl<'b> BorrowRefMut<'b> { + #[inline] fn new(borrow: &'b Cell) -> Option> { match borrow.get() { UNUSED => { @@ -674,6 +694,7 @@ impl UnsafeCell { /// let uc = UnsafeCell::new(5); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn new(value: T) -> UnsafeCell { UnsafeCell { value: value } } From f8c63d00e2c0cd4ab1178eb72e2f799840608eae Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 18 Mar 2015 19:49:39 -0400 Subject: [PATCH 14/18] Document include! Fixes #22309 --- src/libstd/macros.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index e1ef30627948d..f4a7e8b1b9824 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -404,4 +404,18 @@ pub mod builtin { /// ``` #[macro_export] macro_rules! cfg { ($cfg:tt) => ({ /* compiler built-in */ }) } + + /// Parse the current given file as an expression. + /// + /// This is generally a bad idea, because it's going to behave unhygenically. + /// + /// # Examples + /// + /// ```ignore + /// fn foo() { + /// include!("/path/to/a/file") + /// } + /// ``` + #[macro_export] + macro_rules! include { ($cfg:tt) => ({ /* compiler built-in */ }) } } From d943d9b801e7621c08aab912b5ade24a80865191 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 18 Mar 2015 18:06:10 +0530 Subject: [PATCH 15/18] Address huon's comments --- src/libsyntax/ast.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 5c2757153521c..936fbd627862f 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -215,8 +215,8 @@ pub struct Lifetime { pub name: Name } -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] /// A lifetime definition, eg `'a: 'b+'c+'d` +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct LifetimeDef { pub lifetime: Lifetime, pub bounds: Vec From 70bf02994a97b92f7284eac70c143893eca936a8 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 18 Mar 2015 20:24:22 -0400 Subject: [PATCH 16/18] Note ::foo::bar() in the crates guide Fixes #21589 --- src/doc/trpl/crates-and-modules.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/doc/trpl/crates-and-modules.md b/src/doc/trpl/crates-and-modules.md index f6f6046b9b458..65ff42ffdcef4 100644 --- a/src/doc/trpl/crates-and-modules.md +++ b/src/doc/trpl/crates-and-modules.md @@ -562,6 +562,11 @@ place in the hierarchy instead. There's one more special form of `use`: you can people like to think of `self` as `.` and `super` as `..`, from many shells' display for the current directory and the parent directory. +Outside of `use`, paths are relative: `foo::bar()` refers to a function inside +of `foo` relative to where we are. If that's prefixed with `::`, as in +`::foo::bar()`, it refers to a different `foo`, an absolute path from your +crate root. + Also, note that we `pub use`d before we declared our `mod`s. Rust requires that `use` declarations go first. From c20c652a9211d538dcb8b264b0b9c7479684b4d9 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 19 Mar 2015 00:56:37 +0530 Subject: [PATCH 17/18] Space and punctuation fixes --- src/libsyntax/ast.rs | 55 +++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 936fbd627862f..f2fc453cd328f 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -590,6 +590,7 @@ pub enum Pat_ { /// A PatIdent may either be a new bound variable, /// or a nullary enum (in which case the third field /// is None). + /// /// In the nullary enum case, the parser can't determine /// which it is. The resolver determines this, and /// records this pattern's NodeId in an auxiliary @@ -786,18 +787,22 @@ pub enum Expr_ { /// An array (`[a, b, c, d]`) ExprVec(Vec>), /// A function call + /// /// The first field resolves to the function itself, /// and the second field is the list of arguments ExprCall(P, Vec>), /// A method call (`x.foo::(a, b, c, d)`) - /// The `SpannedIdent` is the identifier for the method name + /// + /// The `SpannedIdent` is the identifier for the method name. /// The vector of `Ty`s are the ascripted type parameters for the method - /// (within the angle brackets) + /// (within the angle brackets). + /// /// The first element of the vector of `Expr`s is the expression that evaluates /// to the object on which the method is being called on (the receiver), /// and the remaining elements are the rest of the arguments. + /// /// Thus, `x.foo::(a, b, c, d)` is represented as - /// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])` + /// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])`. ExprMethodCall(SpannedIdent, Vec>, Vec>), /// A tuple (`(a, b, c ,d)`) ExprTup(Vec>), @@ -810,32 +815,41 @@ pub enum Expr_ { /// A cast (`foo as f64`) ExprCast(P, P), /// An `if` block, with an optional else block + /// /// `if expr { block } else { expr }` ExprIf(P, P, Option>), /// An `if let` expression with an optional else block + /// /// `if let pat = expr { block } else { expr }` - /// This is desugared to a `match` expression + /// + /// This is desugared to a `match` expression. ExprIfLet(P, P, P, Option>), // FIXME #6993: change to Option ... or not, if these are hygienic. /// A while loop, with an optional label + /// /// `'label: while expr { block }` ExprWhile(P, P, Option), // FIXME #6993: change to Option ... or not, if these are hygienic. /// A while-let loop, with an optional label + /// /// `'label: while let pat = expr { block }` - /// This is desugared to a combination of `loop` and `match` expressions + /// + /// This is desugared to a combination of `loop` and `match` expressions. ExprWhileLet(P, P, P, Option), // FIXME #6993: change to Option ... or not, if these are hygienic. /// A for loop, with an optional label + /// /// `'label: for pat in expr { block }` - /// This is desugared to a combination of `loop` and `match` expressions + /// + /// This is desugared to a combination of `loop` and `match` expressions. ExprForLoop(P, P, P, Option), /// Conditionless loop (can be exited with break, continue, or return) + /// /// `'label: loop { block }` // FIXME #6993: change to Option ... or not, if these are hygienic. ExprLoop(P, Option), /// A `match` block, with a source that indicates whether or not it is - /// the result of a desugaring, and if so, which kind + /// the result of a desugaring, and if so, which kind. ExprMatch(P, Vec, MatchSource), /// A closure (for example, `move |a, b, c| {a + b + c}`) ExprClosure(CaptureClause, P, P), @@ -845,12 +859,14 @@ pub enum Expr_ { /// An assignment (`a = foo()`) ExprAssign(P, P), /// An assignment with an operator - /// For example, `a += 1` + /// + /// For example, `a += 1`. ExprAssignOp(BinOp, P, P), /// Access of a named struct field (`obj.foo`) ExprField(P, SpannedIdent), /// Access of an unnamed field of a struct or tuple-struct - /// For example, `foo.0` + /// + /// For example, `foo.0`. ExprTupField(P, Spanned), /// An indexing operation (`foo[2]`) ExprIndex(P, P), @@ -858,7 +874,9 @@ pub enum Expr_ { ExprRange(Option>, Option>), /// Variable reference, possibly containing `::` and/or type - /// parameters, e.g. foo::bar::. Optionally "qualified", + /// parameters, e.g. foo::bar::. + /// + /// Optionally "qualified", /// e.g. ` as SomeTrait>::SomeType`. ExprPath(Option, Path), @@ -878,13 +896,15 @@ pub enum Expr_ { ExprMac(Mac), /// A struct literal expression. + /// /// For example, `Foo {x: 1, y: 2}`, or - /// `Foo {x: 1, .. base}`, where `base` is the `Option` + /// `Foo {x: 1, .. base}`, where `base` is the `Option`. ExprStruct(Path, Vec, Option>), /// A vector literal constructed from one repeated element. + /// /// For example, `[1u8; 5]`. The first expression is the element - /// to be repeated; the second is the number of times to repeat it + /// to be repeated; the second is the number of times to repeat it. ExprRepeat(P, P), /// No-op: used solely so we can pretty-print faithfully @@ -1092,6 +1112,7 @@ pub type Mac = Spanned; /// Represents a macro invocation. The Path indicates which macro /// is being invoked, and the vector of token-trees contains the source /// of the macro invocation. +/// /// There's only one flavor, now, so this could presumably be simplified. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum Mac_ { @@ -1105,6 +1126,7 @@ pub enum StrStyle { /// A regular string, like `"foo"` CookedStr, /// A raw string, like `r##"foo"##` + /// /// The uint is the number of `#` symbols used RawStr(usize) } @@ -1459,7 +1481,7 @@ impl Arg { } } -/// represents the header (not the body) of a function declaration +/// Represents the header (not the body) of a function declaration #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct FnDecl { pub inputs: Vec, @@ -1505,7 +1527,9 @@ pub enum FunctionRetTy { /// Functions with return type `!`that always /// raise an error or exit (i.e. never return to the caller) NoReturn(Span), - /// Return type is not specified. Functions default to `()` and + /// Return type is not specified. + /// + /// Functions default to `()` and /// closures default to inference. Span points to where return /// type would be inserted. DefaultReturn(Span), @@ -1645,6 +1669,7 @@ pub struct Attribute_ { } /// TraitRef's appear in impls. +/// /// resolve maps each TraitRef's ref_id to its defining trait; that's all /// that the ref_id is for. The impl_id maps to the "self type" of this impl. /// If this impl is an ItemImpl, the impl_id is redundant (it could be the @@ -1745,6 +1770,7 @@ pub struct Item { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum Item_ { /// An`extern crate` item, with optional original crate name, + /// /// e.g. `extern crate foo` or `extern crate "foo-bar" as foo` ItemExternCrate(Option<(InternedString, StrStyle)>), /// A `use` or `pub use` item @@ -1773,6 +1799,7 @@ pub enum Item_ { Vec>), // Default trait implementations + /// // `impl Trait for .. {}` ItemDefaultImpl(Unsafety, TraitRef), /// An implementation, eg `impl Trait for Foo { .. }` From 6f930b99b0dbd548abb7bdd9eb9472d166f66811 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 19 Mar 2015 07:24:13 +0530 Subject: [PATCH 18/18] Rm unused feature --- src/compiletest/compiletest.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 5ef93cb569ec5..7fbe772b7f5bd 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -19,7 +19,6 @@ #![feature(unboxed_closures)] #![feature(std_misc)] #![feature(test)] -#![feature(core)] #![feature(path_ext)] #![deny(warnings)]