From 1e77e29d2896017e522ed3fc85dca07c1bd466b9 Mon Sep 17 00:00:00 2001 From: Chris Wong Date: Thu, 11 Dec 2014 20:40:44 +1300 Subject: [PATCH 01/58] Don't preserve line breaks in inline code Closes #19323. --- src/doc/rust.css | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/doc/rust.css b/src/doc/rust.css index 9656d17721e..128d75468e6 100644 --- a/src/doc/rust.css +++ b/src/doc/rust.css @@ -1,5 +1,5 @@ /** - * Copyright 2013 The Rust Project Developers. See the COPYRIGHT + * Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT * file at the top-level directory of this distribution and at * http://rust-lang.org/COPYRIGHT. * With elements taken from Bootstrap v3.0.2 (MIT licensed). @@ -209,7 +209,6 @@ pre { code { padding: 0 2px; color: #8D1A38; - white-space: pre-wrap; } pre code { padding: 0; From c0e8dc6dce5d847b7bf53b306d6d842e3a223c28 Mon Sep 17 00:00:00 2001 From: elszben Date: Tue, 16 Dec 2014 19:15:05 +0100 Subject: [PATCH 02/58] Added example to TempDir --- src/libstd/io/tempfile.rs | 53 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/libstd/io/tempfile.rs b/src/libstd/io/tempfile.rs index f3a11939995..334ee9e1e1b 100644 --- a/src/libstd/io/tempfile.rs +++ b/src/libstd/io/tempfile.rs @@ -23,6 +23,59 @@ use sync::atomic; /// A wrapper for a path to temporary directory implementing automatic /// scope-based deletion. +/// +/// # Examples +/// +/// ``` +/// # fn main() {} +/// # fn foo () { +/// use std::io::TempDir; +/// +/// { +/// // create a temporary directory +/// let tmpdir = match TempDir::new("mysuffix") { +/// Ok(dir) => dir, +/// Err(e) => panic!("couldn't create temporary directory: {}", e) +/// }; +/// +/// // get the path of the temporary directory without affecting the wrapper +/// let tmppath = tmpdir.path(); +/// +/// println!("The path of temporary directory is {}", tmppath.as_str().unwrap()); +/// +/// // the temporary directory is automatically removed when tmpdir goes +/// // out of scope at the end of the block +/// } +/// { +/// // create a temporary directory, this time using a custom path +/// let tmpdir = match TempDir::new_in(&Path::new("/tmp/best/custom/path"), "mysuffix") { +/// Ok(dir) => dir, +/// Err(e) => panic!("couldn't create temporary directory: {}", e) +/// }; +/// +/// // get the path of the temporary directory and disable automatic deletion in the wrapper +/// let tmppath = tmpdir.into_inner(); +/// +/// println!("The path of the not-so-temporary directory is {}", tmppath.as_str().unwrap()); +/// +/// // the temporary directory is not removed here +/// // because the directory is detached from the wrapper +/// } +/// { +/// // create a temporary directory +/// let tmpdir = match TempDir::new("mysuffix") { +/// Ok(dir) => dir, +/// Err(e) => panic!("couldn't create temporary directory: {}", e) +/// }; +/// +/// // close the temporary directory manually and check the result +/// match tmpdir.close() { +/// Ok(_) => println!("success!"), +/// Err(e) => panic!("couldn't remove temporary directory: {}", e) +/// }; +/// } +/// # } +/// ``` pub struct TempDir { path: Option, disarmed: bool From 6875eb574802c4ea7da5b83bfc690bd1118be364 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 16 Dec 2014 20:51:55 -0500 Subject: [PATCH 03/58] Improve Arc documentation, and Rc docs a bit Take the docs from Rc, apply them to Arc, and fix some line lengths. --- src/liballoc/arc.rs | 386 ++++++++++++++++++++++++++++++++++++-------- src/liballoc/rc.rs | 31 ++-- 2 files changed, 329 insertions(+), 88 deletions(-) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 1f1909fd33c..4d2d545aec0 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -10,8 +10,61 @@ #![stable] -//! Concurrency-enabled mechanisms for sharing mutable and/or immutable state -//! between tasks. +//! Threadsafe reference-counted boxes (the `Arc` type). +//! +//! The `Arc` type provides shared ownership of an immutable value. Destruction is +//! deterministic, and will occur as soon as the last owner is gone. It is marked as `Send` because +//! it uses atomic reference counting. +//! +//! If you do not need thread-safety, and just need shared ownership, consider the [`Rc` +//! type](../rc/struct.Rc.html). It is the same as `Arc`, but does not use atomics, making it +//! both thread-unsafe as well as significantly faster when updating the reference count. +//! +//! The `downgrade` method can be used to create a non-owning `Weak` pointer to the box. A +//! `Weak` pointer can be upgraded to an `Arc` pointer, but will return `None` if the value +//! has already been dropped. +//! +//! For example, a tree with parent pointers can be represented by putting the nodes behind strong +//! `Arc` pointers, and then storing the parent pointers as `Weak` pointers. +//! +//! # Examples +//! +//! Sharing some immutable data between tasks: +//! +//! ``` +//! use std::sync::Arc; +//! +//! let five = Arc::new(5i); +//! +//! for i in range(0u, 10) { +//! let five = five.clone(); +//! +//! spawn(move || { +//! println!("{}", five); +//! }); +//! } +//! ``` +//! +//! Sharing mutable data safely between tasks with a `Mutex`: +//! +//! ``` +//! use std::sync::Arc; +//! use std::sync::Mutex; +//! +//! let five = Arc::new(Mutex::new(5i)); +//! +//! for _ in range(0u, 10) { +//! let five = five.clone(); +//! +//! spawn(move || { +//! let mut number = five.lock(); +//! +//! number += 1; +//! +//! println!("{}", *number); // prints 6 +//! }); +//! } +//! ``` use core::atomic; use core::clone::Clone; @@ -32,9 +85,8 @@ use heap::deallocate; /// /// # Example /// -/// In this example, a large vector of floats is shared between several tasks. -/// With simple pipes, without `Arc`, a copy would have to be made for each -/// task. +/// In this example, a large vector of floats is shared between several tasks. With simple pipes, +/// without `Arc`, a copy would have to be made for each task. /// /// ```rust /// use std::sync::Arc; @@ -64,8 +116,8 @@ pub struct Arc { /// A weak pointer to an `Arc`. /// -/// Weak pointers will not keep the data inside of the `Arc` alive, and can be -/// used to break cycles between `Arc` pointers. +/// Weak pointers will not keep the data inside of the `Arc` alive, and can be used to break cycles +/// between `Arc` pointers. #[unsafe_no_drop_flag] #[experimental = "Weak pointers may not belong in this module."] pub struct Weak { @@ -81,7 +133,15 @@ struct ArcInner { } impl Arc { - /// Creates an atomically reference counted wrapper. + /// Constructs a new `Arc`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5i); + /// ``` #[inline] #[stable] pub fn new(data: T) -> Arc { @@ -95,11 +155,17 @@ impl Arc { Arc { _ptr: unsafe { mem::transmute(x) } } } - /// Downgrades a strong pointer to a weak pointer. + /// Downgrades the `Arc` to a `Weak` reference. /// - /// Weak pointers will not keep the data alive. Once all strong references - /// to the underlying data have been dropped, the data itself will be - /// destroyed. + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5i); + /// + /// let weak_five = five.downgrade(); + /// ``` #[experimental = "Weak pointers may not belong in this module."] pub fn downgrade(&self) -> Weak { // See the clone() impl for why this is relaxed @@ -111,11 +177,10 @@ impl Arc { impl Arc { #[inline] fn inner(&self) -> &ArcInner { - // This unsafety is ok because while this arc is alive we're guaranteed - // that the inner pointer is valid. Furthermore, we know that the - // `ArcInner` structure itself is `Sync` because the inner data is - // `Sync` as well, so we're ok loaning out an immutable pointer to - // these contents. + // This unsafety is ok because while this arc is alive we're guaranteed that the inner + // pointer is valid. Furthermore, we know that the `ArcInner` structure itself is `Sync` + // because the inner data is `Sync` as well, so we're ok loaning out an immutable pointer + // to these contents. unsafe { &*self._ptr } } } @@ -132,22 +197,28 @@ pub fn strong_count(this: &Arc) -> uint { this.inner().strong.load(atomic: #[unstable = "waiting on stability of Clone"] impl Clone for Arc { - /// Duplicate an atomically reference counted wrapper. + /// Makes a clone of the `Arc`. /// - /// The resulting two `Arc` objects will point to the same underlying data - /// object. However, one of the `Arc` objects can be sent to another task, - /// allowing them to share the underlying data. + /// This increases the strong reference count. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5i); + /// + /// five.clone(); + /// ``` #[inline] fn clone(&self) -> Arc { - // Using a relaxed ordering is alright here, as knowledge of the - // original reference prevents other threads from erroneously deleting - // the object. + // Using a relaxed ordering is alright here, as knowledge of the original reference + // prevents other threads from erroneously deleting the object. // - // As explained in the [Boost documentation][1], Increasing the - // reference counter can always be done with memory_order_relaxed: New - // references to an object can only be formed from an existing - // reference, and passing an existing reference from one thread to - // another must already provide any required synchronization. + // As explained in the [Boost documentation][1], Increasing the reference counter can + // always be done with memory_order_relaxed: New references to an object can only be formed + // from an existing reference, and passing an existing reference from one thread to another + // must already provide any required synchronization. // // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html) self.inner().strong.fetch_add(1, atomic::Relaxed); @@ -164,26 +235,33 @@ impl Deref for Arc { } impl Arc { - /// Acquires a mutable pointer to the inner contents by guaranteeing that - /// the reference count is one (no sharing is possible). + /// Make a mutable reference from the given `Arc`. /// - /// This is also referred to as a copy-on-write operation because the inner - /// data is cloned if the reference count is greater than one. + /// This is also referred to as a copy-on-write operation because the inner data is cloned if + /// the reference count is greater than one. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let mut five = Arc::new(5i); + /// + /// let mut_five = five.make_unique(); + /// ``` #[inline] #[experimental] pub fn make_unique(&mut self) -> &mut T { - // Note that we hold a strong reference, which also counts as - // a weak reference, so we only clone if there is an - // additional reference of either kind. + // Note that we hold a strong reference, which also counts as a weak reference, so we only + // clone if there is an additional reference of either kind. if self.inner().strong.load(atomic::SeqCst) != 1 || self.inner().weak.load(atomic::SeqCst) != 1 { *self = Arc::new((**self).clone()) } - // This unsafety is ok because we're guaranteed that the pointer - // returned is the *only* pointer that will ever be returned to T. Our - // reference count is guaranteed to be 1 at this point, and we required - // the Arc itself to be `mut`, so we're returning the only possible - // reference to the inner data. + // This unsafety is ok because we're guaranteed that the pointer returned is the *only* + // pointer that will ever be returned to T. Our reference count is guaranteed to be 1 at + // this point, and we required the Arc itself to be `mut`, so we're returning the only + // possible reference to the inner data. let inner = unsafe { &mut *self._ptr }; &mut inner.data } @@ -192,38 +270,59 @@ impl Arc { #[unsafe_destructor] #[experimental = "waiting on stability of Drop"] impl Drop for Arc { + /// Drops the `Arc`. + /// + /// This will decrement the strong reference count. If the strong reference count becomes zero + /// and the only other references are `Weak` ones, `drop`s the inner value. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// { + /// let five = Arc::new(5i); + /// + /// // stuff + /// + /// drop(five); // explict drop + /// } + /// { + /// let five = Arc::new(5i); + /// + /// // stuff + /// + /// } // implicit drop + /// ``` fn drop(&mut self) { - // This structure has #[unsafe_no_drop_flag], so this drop glue may run - // more than once (but it is guaranteed to be zeroed after the first if - // it's run more than once) + // This structure has #[unsafe_no_drop_flag], so this drop glue may run more than once (but + // it is guaranteed to be zeroed after the first if it's run more than once) if self._ptr.is_null() { return } - // Because `fetch_sub` is already atomic, we do not need to synchronize - // with other threads unless we are going to delete the object. This - // same logic applies to the below `fetch_sub` to the `weak` count. + // Because `fetch_sub` is already atomic, we do not need to synchronize with other threads + // unless we are going to delete the object. This same logic applies to the below + // `fetch_sub` to the `weak` count. if self.inner().strong.fetch_sub(1, atomic::Release) != 1 { return } - // This fence is needed to prevent reordering of use of the data and - // deletion of the data. Because it is marked `Release`, the - // decreasing of the reference count synchronizes with this `Acquire` - // fence. This means that use of the data happens before decreasing - // the reference count, which happens before this fence, which - // happens before the deletion of the data. + // This fence is needed to prevent reordering of use of the data and deletion of the data. + // Because it is marked `Release`, the decreasing of the reference count synchronizes with + // this `Acquire` fence. This means that use of the data happens before decreasing the + // reference count, which happens before this fence, which happens before the deletion of + // the data. // // As explained in the [Boost documentation][1], // - // It is important to enforce any possible access to the object in - // one thread (through an existing reference) to *happen before* - // deleting the object in a different thread. This is achieved by a - // "release" operation after dropping a reference (any access to the - // object through this reference must obviously happened before), - // and an "acquire" operation before deleting the object. + // > It is important to enforce any possible access to the object in one thread (through an + // > existing reference) to *happen before* deleting the object in a different thread. This + // > is achieved by a "release" operation after dropping a reference (any access to the + // > object through this reference must obviously happened before), and an "acquire" + // > operation before deleting the object. // // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html) atomic::fence(atomic::Acquire); - // Destroy the data at this time, even though we may not free the box - // allocation itself (there may still be weak pointers lying around). + // Destroy the data at this time, even though we may not free the box allocation itself + // (there may still be weak pointers lying around). unsafe { drop(ptr::read(&self.inner().data)); } if self.inner().weak.fetch_sub(1, atomic::Release) == 1 { @@ -236,14 +335,26 @@ impl Drop for Arc { #[experimental = "Weak pointers may not belong in this module."] impl Weak { - /// Attempts to upgrade this weak reference to a strong reference. + /// Upgrades a weak reference to a strong reference. /// - /// This method will not upgrade this reference if the strong reference count has already - /// reached 0, but if there are still other active strong references this function will return - /// a new strong reference to the data. + /// Upgrades the `Weak` reference to an `Arc`, if possible. + /// + /// Returns `None` if there were no strong references and the data was destroyed. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5i); + /// + /// let weak_five = five.downgrade(); + /// + /// let strong_five: Option> = weak_five.upgrade(); + /// ``` pub fn upgrade(&self) -> Option> { - // We use a CAS loop to increment the strong count instead of a - // fetch_add because once the count hits 0 is must never be above 0. + // We use a CAS loop to increment the strong count instead of a fetch_add because once the + // count hits 0 is must never be above 0. let inner = self.inner(); loop { let n = inner.strong.load(atomic::SeqCst); @@ -262,6 +373,19 @@ impl Weak { #[experimental = "Weak pointers may not belong in this module."] impl Clone for Weak { + /// Makes a clone of the `Weak`. + /// + /// This increases the weak reference count. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let weak_five = Arc::new(5i).downgrade(); + /// + /// weak_five.clone(); + /// ``` #[inline] fn clone(&self) -> Weak { // See comments in Arc::clone() for why this is relaxed @@ -273,13 +397,37 @@ impl Clone for Weak { #[unsafe_destructor] #[experimental = "Weak pointers may not belong in this module."] impl Drop for Weak { + /// Drops the `Weak`. + /// + /// This will decrement the weak reference count. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// { + /// let five = Arc::new(5i); + /// let weak_five = five.downgrade(); + /// + /// // stuff + /// + /// drop(weak_five); // explict drop + /// } + /// { + /// let five = Arc::new(5i); + /// let weak_five = five.downgrade(); + /// + /// // stuff + /// + /// } // implicit drop + /// ``` fn drop(&mut self) { // see comments above for why this check is here if self._ptr.is_null() { return } - // If we find out that we were the last weak pointer, then its time to - // deallocate the data entirely. See the discussion in Arc::drop() about - // the memory orderings + // If we find out that we were the last weak pointer, then its time to deallocate the data + // entirely. See the discussion in Arc::drop() about the memory orderings if self.inner().weak.fetch_sub(1, atomic::Release) == 1 { atomic::fence(atomic::Acquire); unsafe { deallocate(self._ptr as *mut u8, size_of::>(), @@ -290,18 +438,114 @@ impl Drop for Weak { #[unstable = "waiting on PartialEq"] impl PartialEq for Arc { + /// Equality for two `Arc`s. + /// + /// Two `Arc`s are equal if their inner value are equal. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5i); + /// + /// five == Arc::new(5i); + /// ``` fn eq(&self, other: &Arc) -> bool { *(*self) == *(*other) } + + /// Inequality for two `Arc`s. + /// + /// Two `Arc`s are unequal if their inner value are unequal. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5i); + /// + /// five != Arc::new(5i); + /// ``` fn ne(&self, other: &Arc) -> bool { *(*self) != *(*other) } } #[unstable = "waiting on PartialOrd"] impl PartialOrd for Arc { + /// Partial comparison for two `Arc`s. + /// + /// The two are compared by calling `partial_cmp()` on their inner values. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5i); + /// + /// five.partial_cmp(&Arc::new(5i)); + /// ``` fn partial_cmp(&self, other: &Arc) -> Option { (**self).partial_cmp(&**other) } + + /// Less-than comparison for two `Arc`s. + /// + /// The two are compared by calling `<` on their inner values. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5i); + /// + /// five < Arc::new(5i); + /// ``` fn lt(&self, other: &Arc) -> bool { *(*self) < *(*other) } + + /// 'Less-than or equal to' comparison for two `Arc`s. + /// + /// The two are compared by calling `<=` on their inner values. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5i); + /// + /// five <= Arc::new(5i); + /// ``` fn le(&self, other: &Arc) -> bool { *(*self) <= *(*other) } - fn ge(&self, other: &Arc) -> bool { *(*self) >= *(*other) } + + /// Greater-than comparison for two `Arc`s. + /// + /// The two are compared by calling `>` on their inner values. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5i); + /// + /// five > Arc::new(5i); + /// ``` fn gt(&self, other: &Arc) -> bool { *(*self) > *(*other) } + + /// 'Greater-than or equal to' comparison for two `Arc`s. + /// + /// The two are compared by calling `>=` on their inner values. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5i); + /// + /// five >= Arc::new(5i); + /// ``` + fn ge(&self, other: &Arc) -> bool { *(*self) >= *(*other) } } #[unstable = "waiting on Ord"] impl Ord for Arc { diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 217c898e661..4e2fbc82b4a 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -167,12 +167,12 @@ struct RcBox { /// An immutable reference-counted pointer type. /// -/// See the [module level documentation](../index.html) for more. +/// See the [module level documentation](../index.html) for more details. #[unsafe_no_drop_flag] #[stable] pub struct Rc { - // FIXME #12808: strange names to try to avoid interfering with - // field accesses of the contained type via Deref + // FIXME #12808: strange names to try to avoid interfering with field accesses of the contained + // type via Deref _ptr: *mut RcBox, _nosend: marker::NoSend, _noshare: marker::NoSync @@ -192,11 +192,9 @@ impl Rc { pub fn new(value: T) -> Rc { unsafe { Rc { - // there is an implicit weak pointer owned by all the - // strong pointers, which ensures that the weak - // destructor never frees the allocation while the - // strong destructor is running, even if the weak - // pointer is stored inside the strong one. + // there is an implicit weak pointer owned by all the strong pointers, which + // ensures that the weak destructor never frees the allocation while the strong + // destructor is running, even if the weak pointer is stored inside the strong one. _ptr: transmute(box RcBox { value: value, strong: Cell::new(1), @@ -340,11 +338,10 @@ impl Rc { if !is_unique(self) { *self = Rc::new((**self).clone()) } - // This unsafety is ok because we're guaranteed that the pointer - // returned is the *only* pointer that will ever be returned to T. Our - // reference count is guaranteed to be 1 at this point, and we required - // the `Rc` itself to be `mut`, so we're returning the only possible - // reference to the inner value. + // This unsafety is ok because we're guaranteed that the pointer returned is the *only* + // pointer that will ever be returned to T. Our reference count is guaranteed to be 1 at + // this point, and we required the `Rc` itself to be `mut`, so we're returning the only + // possible reference to the inner value. let inner = unsafe { &mut *self._ptr }; &mut inner.value } @@ -398,8 +395,8 @@ impl Drop for Rc { if self.strong() == 0 { ptr::read(&**self); // destroy the contained object - // remove the implicit "strong weak" pointer now - // that we've destroyed the contents. + // remove the implicit "strong weak" pointer now that we've destroyed the + // contents. self.dec_weak(); if self.weak() == 0 { @@ -677,8 +674,8 @@ impl Drop for Weak { unsafe { if !self._ptr.is_null() { self.dec_weak(); - // the weak count starts at 1, and will only go to - // zero if all the strong pointers have disappeared. + // the weak count starts at 1, and will only go to zero if all the strong pointers + // have disappeared. if self.weak() == 0 { deallocate(self._ptr as *mut u8, size_of::>(), min_align_of::>()) From c910252769370a1bc039ec25ed918d81669d28ad Mon Sep 17 00:00:00 2001 From: elszben Date: Wed, 17 Dec 2014 07:21:29 +0100 Subject: [PATCH 04/58] Replaced wrapper functions with no_run and as_str().unwrap() with display() --- src/libstd/io/tempfile.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/libstd/io/tempfile.rs b/src/libstd/io/tempfile.rs index 334ee9e1e1b..c2b4d5a1fa9 100644 --- a/src/libstd/io/tempfile.rs +++ b/src/libstd/io/tempfile.rs @@ -26,9 +26,7 @@ use sync::atomic; /// /// # Examples /// -/// ``` -/// # fn main() {} -/// # fn foo () { +/// ```no_run /// use std::io::TempDir; /// /// { @@ -41,7 +39,7 @@ use sync::atomic; /// // get the path of the temporary directory without affecting the wrapper /// let tmppath = tmpdir.path(); /// -/// println!("The path of temporary directory is {}", tmppath.as_str().unwrap()); +/// println!("The path of temporary directory is {}", tmppath.display()); /// /// // the temporary directory is automatically removed when tmpdir goes /// // out of scope at the end of the block @@ -56,7 +54,7 @@ use sync::atomic; /// // get the path of the temporary directory and disable automatic deletion in the wrapper /// let tmppath = tmpdir.into_inner(); /// -/// println!("The path of the not-so-temporary directory is {}", tmppath.as_str().unwrap()); +/// println!("The path of the not-so-temporary directory is {}", tmppath.display()); /// /// // the temporary directory is not removed here /// // because the directory is detached from the wrapper @@ -74,7 +72,6 @@ use sync::atomic; /// Err(e) => panic!("couldn't remove temporary directory: {}", e) /// }; /// } -/// # } /// ``` pub struct TempDir { path: Option, From bada7df64b8ca85a1708336db896e52d9b4ce626 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 17 Dec 2014 21:27:04 +0200 Subject: [PATCH 05/58] doc: remove extraneous line --- src/doc/guide.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/doc/guide.md b/src/doc/guide.md index da111cbe6b4..b0cc12cd4b6 100644 --- a/src/doc/guide.md +++ b/src/doc/guide.md @@ -31,7 +31,6 @@ below.) If you're on Windows, please download either the [32-bit installer](https://static.rust-lang.org/dist/rust-nightly-i686-pc-windows-gnu.exe) - or the [64-bit installer](https://static.rust-lang.org/dist/rust-nightly-x86_64-pc-windows-gnu.exe) and run it. From 1afa8acca8d9c548da99ef30d3a13c0d086203f3 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Sun, 14 Dec 2014 09:48:56 -0500 Subject: [PATCH 06/58] Use #[deriving(Copy)] for InvariantLifetime --- src/libcore/kinds.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libcore/kinds.rs b/src/libcore/kinds.rs index 69f65e23389..d31ff81091c 100644 --- a/src/libcore/kinds.rs +++ b/src/libcore/kinds.rs @@ -256,11 +256,9 @@ pub mod marker { /// and this pointer is itself stored in an inherently mutable /// location (such as a `Cell`). #[lang="invariant_lifetime"] - #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)] + #[deriving(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct InvariantLifetime<'a>; - impl<'a> Copy for InvariantLifetime<'a> {} - /// A type which is considered "not sendable", meaning that it cannot /// be safely sent between tasks, even if it is owned. This is /// typically embedded in other types, such as `Gc`, to ensure that From 1a996f93c3e205fa62004686a17f26bd4484cc87 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 17 Dec 2014 19:14:59 -0500 Subject: [PATCH 07/58] Remove wrong `&str + String` and `&[T] + Vec` implementations --- src/libcollections/string.rs | 8 -------- src/libcollections/vec.rs | 9 --------- 2 files changed, 17 deletions(-) diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index ba89fc133c4..8334f126100 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -885,14 +885,6 @@ impl<'a> Add<&'a str, String> for String { } } -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot -impl<'a> Add for &'a str { - fn add(self, mut other: String) -> String { - other.push_str(self); - other - } -} - impl ops::Slice for String { #[inline] fn as_slice_<'a>(&'a self) -> &'a str { diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 75a389a7c95..091c0081eb3 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1335,15 +1335,6 @@ impl<'a, T: Clone> Add<&'a [T], Vec> for Vec { } } -#[cfg(not(stage0))] // NOTE(stage0): Remove impl after a snapshot -impl<'a, T: Clone> Add, Vec> for &'a [T] { - #[inline] - fn add(self, mut rhs: Vec) -> Vec { - rhs.push_all(self); - rhs - } -} - #[unsafe_destructor] impl Drop for Vec { fn drop(&mut self) { From 5806519bd49e1ebcd78ee5370bd6c9ffad236577 Mon Sep 17 00:00:00 2001 From: bluss Date: Thu, 18 Dec 2014 02:01:37 +0100 Subject: [PATCH 08/58] doc: Small changes to ownership guide. Disambiguate maximally by using 'and' instead of '&' next to discussion about references. As a bonus, fix the spelling of the car too. --- src/doc/guide-ownership.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/guide-ownership.md b/src/doc/guide-ownership.md index 1a469704143..bf750ecaa8f 100644 --- a/src/doc/guide-ownership.md +++ b/src/doc/guide-ownership.md @@ -324,7 +324,7 @@ fn main() { let f = Foo { x: y }; // -+ f goes into scope // stuff // | // | -} // -+ f & y go out of scope +} // -+ f and y go out of scope ``` Our `f` lives within the scope of `y`, so everything works. What if it didn't? @@ -342,7 +342,7 @@ fn main() { let y = &5i; // ---+ y goes into scope let f = Foo { x: y }; // ---+ f goes into scope x = &f.x; // | | error here - } // ---+ f & y go out of scope + } // ---+ f and y go out of scope // | println!("{}", x); // | } // -+ x goes out of scope @@ -395,7 +395,7 @@ struct Wheel { } fn main() { - let car = Car { name: "DeLorian".to_string() }; + let car = Car { name: "DeLorean".to_string() }; for _ in range(0u, 4) { Wheel { size: 360, owner: car }; @@ -431,7 +431,7 @@ struct Wheel { } fn main() { - let car = Car { name: "DeLorian".to_string() }; + let car = Car { name: "DeLorean".to_string() }; let car_owner = Rc::new(car); From 11a94f2ac737642d08a77630ff88ebcc4b12c59c Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 17 Dec 2014 21:00:04 -0500 Subject: [PATCH 09/58] remove l10n --- mk/docs.mk | 34 ---------------------------------- src/doc/README.md | 46 ---------------------------------------------- src/doc/po4a.conf | 28 ---------------------------- 3 files changed, 108 deletions(-) delete mode 100644 src/doc/po4a.conf diff --git a/mk/docs.mk b/mk/docs.mk index 6d1a3bfa7a3..9a924916ec8 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -216,36 +216,6 @@ endef $(foreach docname,$(DOCS),$(eval $(call DEF_DOC,$(docname)))) -# Localized documentation - -# FIXME: I (huonw) haven't actually been able to test properly, since -# e.g. (by default) I'm doing an out-of-tree build (#12763), but even -# adjusting for that, the files are too old(?) and are rejected by -# po4a. -# -# As such, I've attempted to get it working as much as possible (and -# switching from pandoc to rustdoc), but preserving the old behaviour -# (e.g. only running on the guide) -.PHONY: l10n-mds -l10n-mds: $(D)/po4a.conf \ - $(foreach lang,$(L10N_LANG),$(D)/po/$(lang)/*.md.po) - $(warning WARNING: localized documentation is experimental) - po4a --copyright-holder="The Rust Project Developers" \ - --package-name="Rust" \ - --package-version="$(CFG_RELEASE)" \ - -M UTF-8 -L UTF-8 \ - $(D)/po4a.conf - -define DEF_L10N_DOC -DOC_L10N_TARGETS += doc/l10n/$(1)/$(2).html -doc/l10n/$(1)/$(2).html: l10n-mds $$(HTML_DEPS) $$(RUSTDOC_DEPS_$(2)) - @$$(call E, rustdoc: $$@) - $$(RUSTDOC) $$(RUSTDOC_HTML_OPTS) $$(RUSTDOC_FLAGS_$(1)) doc/l10n/$(1)/$(2).md -endef - -$(foreach lang,$(L10N_LANGS),$(eval $(call DEF_L10N_DOC,$(lang),guide))) - - ###################################################################### # Rustdoc (libstd/extra) ###################################################################### @@ -294,7 +264,3 @@ endif docs: $(DOC_TARGETS) compiler-docs: $(COMPILER_DOC_TARGETS) - -docs-l10n: $(DOC_L10N_TARGETS) - -.PHONY: docs-l10n diff --git a/src/doc/README.md b/src/doc/README.md index 50222973509..3b12ffe8f11 100644 --- a/src/doc/README.md +++ b/src/doc/README.md @@ -6,12 +6,6 @@ document converter, is required to generate docs as HTML from Rust's source code. -[po4a](http://po4a.alioth.debian.org/) is required for generating translated -docs from the master (English) docs. - -[GNU gettext](http://www.gnu.org/software/gettext/) is required for managing -the translation data. - ## Building To generate all the docs, just run `make docs` from the root of the repository. @@ -44,43 +38,3 @@ The syntax for pandoc flavored markdown can be found at: A nice quick reference (for non-pandoc markdown) is at: - http://kramdown.gettalong.org/quickref.html - -## Notes for translators - -Notice: The procedure described below is a work in progress. We are working on -translation system but the procedure contains some manual operations for now. - -To start the translation for a new language, see `po4a.conf` at first. - -To generate `.pot` and `.po` files, do something like: - -~~~~ -po4a --copyright-holder="The Rust Project Developers" \ - --package-name="Rust" \ - --package-version="0.13.0" \ - -M UTF-8 -L UTF-8 \ - src/doc/po4a.conf -~~~~ - -(the version number must be changed if it is not `0.13.0` now.) - -Now you can translate documents with `.po` files, commonly used with gettext. If -you are not familiar with gettext-based translation, please read the online -manual linked from http://www.gnu.org/software/gettext/ . We use UTF-8 as the -file encoding of `.po` files. - -When you want to make a commit, do the command below before staging your -change: - -~~~~ -for f in src/doc/po/**/*.po; do - msgattrib --translated $f -o $f.strip - if [ -e $f.strip ]; then - mv $f.strip $f - else - rm $f - fi -done -~~~~ - -This removes untranslated entries from `.po` files to save disk space. diff --git a/src/doc/po4a.conf b/src/doc/po4a.conf deleted file mode 100644 index 80f8b748814..00000000000 --- a/src/doc/po4a.conf +++ /dev/null @@ -1,28 +0,0 @@ -# Add here a list of target languages; po4a will automatically -# generates .po for them and build .md when translated, eg: -# [po4a_langs] es fr it pt_BR -[po4a_langs] ja -[po4a_paths] doc/po/$master.pot $lang:src/doc/po/$lang/$master.po - -# Add here below all source documents to be translated -[type: text] src/doc/complement-bugreport.md $lang:doc/l10n/$lang/complement-bugreport.md -[type: text] src/doc/complement-design-faq.md $lang:doc/l10n/$lang/complement-design-faq.md -[type: text] src/doc/complement-lang-faq.md $lang:doc/l10n/$lang/complement-lang-faq.md -[type: text] src/doc/complement-project-faq.md $lang:doc/l10n/$lang/complement-project-faq.md -[type: text] src/doc/guide-container.md $lang:doc/l10n/$lang/guide-container.md -[type: text] src/doc/guide-ffi.md $lang:doc/l10n/$lang/guide-ffi.md -[type: text] src/doc/guide-ownership.md $lang:doc/l10n/$lang/guide-ownership.md -[type: text] src/doc/guide-macros.md $lang:doc/l10n/$lang/guide-macros.md -[type: text] src/doc/guide-plugin.md $lang:doc/l10n/$lang/guide-plugin.md -[type: text] src/doc/guide-pointers.md $lang:doc/l10n/$lang/guide-pointers.md -[type: text] src/doc/guide-strings.md $lang:doc/l10n/$lang/guide-strings.md -[type: text] src/doc/guide-tasks.md $lang:doc/l10n/$lang/guide-tasks.md -[type: text] src/doc/guide-testing.md $lang:doc/l10n/$lang/guide-testing.md -[type: text] src/doc/guide-unsafe.md $lang:doc/l10n/$lang/guide-unsafe.md -[type: text] src/doc/guide-crates.md $lang:doc/l10n/$lang/guide-crates.md -[type: text] src/doc/guide-error-handling.md $lang:doc/l10n/$lang/guide-error-handling.md -[type: text] src/doc/guide.md $lang:doc/l10n/$lang/guide.md -[type: text] src/doc/index.md $lang:doc/l10n/$lang/index.md -[type: text] src/doc/intro.md $lang:doc/l10n/$lang/intro.md -[type: text] src/doc/rust.md $lang:doc/l10n/$lang/rust.md -[type: text] src/doc/rustdoc.md $lang:doc/l10n/$lang/rustdoc.md From eee209d9e2dde700a3958f3e539eff02b63f50bd Mon Sep 17 00:00:00 2001 From: James Miller Date: Tue, 16 Dec 2014 12:21:08 +1300 Subject: [PATCH 10/58] Only count nested returns when the outer return is reachable This narrows the definition of nested returns such that only when the outer return has a chance of being executed (due to the inner return being conditional) do we mark the function as having nested returns. Fixes #19684 --- src/librustc/middle/cfg/mod.rs | 7 +++ src/librustc/middle/graph.rs | 37 ++++++++++++ src/librustc_driver/lib.rs | 2 +- src/librustc_trans/trans/base.rs | 94 ++++++++++++++++-------------- src/librustc_trans/trans/common.rs | 3 + 5 files changed, 99 insertions(+), 44 deletions(-) diff --git a/src/librustc/middle/cfg/mod.rs b/src/librustc/middle/cfg/mod.rs index bc512a73a4b..0e9bd42a23a 100644 --- a/src/librustc/middle/cfg/mod.rs +++ b/src/librustc/middle/cfg/mod.rs @@ -49,4 +49,11 @@ impl CFG { blk: &ast::Block) -> CFG { construct::construct(tcx, blk) } + + pub fn node_is_reachable(&self, id: ast::NodeId) -> bool { + for node in self.graph.depth_traverse(self.entry) { + if node.id == id { return true } + } + return false; + } } diff --git a/src/librustc/middle/graph.rs b/src/librustc/middle/graph.rs index 4c03ed2a480..4397f03a642 100644 --- a/src/librustc/middle/graph.rs +++ b/src/librustc/middle/graph.rs @@ -34,6 +34,7 @@ use std::fmt::{Formatter, Error, Show}; use std::uint; +use std::collections::BitvSet; pub struct Graph { nodes: Vec> , @@ -294,6 +295,42 @@ impl Graph { } } } + + pub fn depth_traverse<'a>(&'a self, start: NodeIndex) -> DepthFirstTraversal<'a, N, E> { + DepthFirstTraversal { + graph: self, + stack: vec![start], + visited: BitvSet::new() + } + } +} + +pub struct DepthFirstTraversal<'g, N:'g, E:'g> { + graph: &'g Graph, + stack: Vec, + visited: BitvSet +} + +impl<'g, N, E> Iterator<&'g N> for DepthFirstTraversal<'g, N, E> { + fn next(&mut self) -> Option<&'g N> { + while self.stack.len() > 0 { + let idx = self.stack.pop().unwrap(); + if self.visited.contains(&idx.node_id()) { + continue; + } + self.visited.insert(idx.node_id()); + self.graph.each_outgoing_edge(idx, |_, e| -> bool { + if !self.visited.contains(&e.target().node_id()) { + self.stack.push(e.target()); + } + true + }); + + return Some(self.graph.node_data(idx)); + } + + return None; + } } pub fn each_edge_index(max_edge_index: EdgeIndex, mut f: F) where diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index b0f8b3bdbe7..82d3edfa5e0 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -472,7 +472,7 @@ pub fn list_metadata(sess: &Session, path: &Path, /// The diagnostic emitter yielded to the procedure should be used for reporting /// errors of the compiler. pub fn monitor(f: F) { - static STACK_SIZE: uint = 32000000; // 32MB + static STACK_SIZE: uint = 8 * 1024 * 1024; // 8MB let (tx, rx) = channel(); let w = io::ChanWriter::new(tx); diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 83779ffbe16..1a82a7131a7 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -38,6 +38,7 @@ use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param}; use llvm; use metadata::{csearch, encoder, loader}; use middle::astencode; +use middle::cfg; use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem}; use middle::subst; use middle::weak_lang_items; @@ -1305,47 +1306,33 @@ pub fn make_return_slot_pointer<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>, } } -struct CheckForNestedReturnsVisitor { +struct FindNestedReturn { found: bool, - in_return: bool } -impl CheckForNestedReturnsVisitor { - fn explicit() -> CheckForNestedReturnsVisitor { - CheckForNestedReturnsVisitor { found: false, in_return: false } - } - fn implicit() -> CheckForNestedReturnsVisitor { - CheckForNestedReturnsVisitor { found: false, in_return: true } +impl FindNestedReturn { + fn new() -> FindNestedReturn { + FindNestedReturn { found: false } } } -impl<'v> Visitor<'v> for CheckForNestedReturnsVisitor { +impl<'v> Visitor<'v> for FindNestedReturn { fn visit_expr(&mut self, e: &ast::Expr) { match e.node { ast::ExprRet(..) => { - if self.in_return { - self.found = true; - } else { - self.in_return = true; - visit::walk_expr(self, e); - self.in_return = false; - } + self.found = true; } _ => visit::walk_expr(self, e) } } } -fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool { - match tcx.map.find(id) { +fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option) { + let blk = match tcx.map.find(id) { Some(ast_map::NodeItem(i)) => { match i.node { ast::ItemFn(_, _, _, _, ref blk) => { - let mut explicit = CheckForNestedReturnsVisitor::explicit(); - let mut implicit = CheckForNestedReturnsVisitor::implicit(); - visit::walk_item(&mut explicit, &*i); - visit::walk_expr_opt(&mut implicit, &blk.expr); - explicit.found || implicit.found + blk } _ => tcx.sess.bug("unexpected item variant in has_nested_returns") } @@ -1355,11 +1342,7 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool { ast::ProvidedMethod(ref m) => { match m.node { ast::MethDecl(_, _, _, _, _, _, ref blk, _) => { - let mut explicit = CheckForNestedReturnsVisitor::explicit(); - let mut implicit = CheckForNestedReturnsVisitor::implicit(); - visit::walk_method_helper(&mut explicit, &**m); - visit::walk_expr_opt(&mut implicit, &blk.expr); - explicit.found || implicit.found + blk } ast::MethMac(_) => tcx.sess.bug("unexpanded macro") } @@ -1379,11 +1362,7 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool { ast::MethodImplItem(ref m) => { match m.node { ast::MethDecl(_, _, _, _, _, _, ref blk, _) => { - let mut explicit = CheckForNestedReturnsVisitor::explicit(); - let mut implicit = CheckForNestedReturnsVisitor::implicit(); - visit::walk_method_helper(&mut explicit, &**m); - visit::walk_expr_opt(&mut implicit, &blk.expr); - explicit.found || implicit.found + blk } ast::MethMac(_) => tcx.sess.bug("unexpanded macro") } @@ -1397,24 +1376,47 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool { Some(ast_map::NodeExpr(e)) => { match e.node { ast::ExprClosure(_, _, _, ref blk) => { - let mut explicit = CheckForNestedReturnsVisitor::explicit(); - let mut implicit = CheckForNestedReturnsVisitor::implicit(); - visit::walk_expr(&mut explicit, e); - visit::walk_expr_opt(&mut implicit, &blk.expr); - explicit.found || implicit.found + blk } _ => tcx.sess.bug("unexpected expr variant in has_nested_returns") } } - - Some(ast_map::NodeVariant(..)) | Some(ast_map::NodeStructCtor(..)) => false, + Some(ast_map::NodeVariant(..)) | Some(ast_map::NodeStructCtor(..)) => return (ast::DUMMY_NODE_ID, None), // glue, shims, etc - None if id == ast::DUMMY_NODE_ID => false, + None if id == ast::DUMMY_NODE_ID => return (ast::DUMMY_NODE_ID, None), _ => tcx.sess.bug(format!("unexpected variant in has_nested_returns: {}", tcx.map.path_to_string(id)).as_slice()) + }; + + (blk.id, Some(cfg::CFG::new(tcx, &**blk))) +} + +fn has_nested_returns(tcx: &ty::ctxt, cfg: &cfg::CFG, blk_id: ast::NodeId) -> bool { + for n in cfg.graph.depth_traverse(cfg.entry) { + match tcx.map.find(n.id) { + Some(ast_map::NodeExpr(ex)) => { + if let ast::ExprRet(Some(ref ret_expr)) = ex.node { + let mut visitor = FindNestedReturn::new(); + visit::walk_expr(&mut visitor, &**ret_expr); + if visitor.found { + return true; + } + } + } + Some(ast_map::NodeBlock(blk)) if blk.id == blk_id => { + let mut visitor = FindNestedReturn::new(); + visit::walk_expr_opt(&mut visitor, &blk.expr); + if visitor.found { + return true; + } + } + _ => {} + } } + + return false; } // NB: must keep 4 fns in sync: @@ -1453,7 +1455,12 @@ pub fn new_fn_ctxt<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>, ty::FnDiverging => false }; let debug_context = debuginfo::create_function_debug_context(ccx, id, param_substs, llfndecl); - let nested_returns = has_nested_returns(ccx.tcx(), id); + let (blk_id, cfg) = build_cfg(ccx.tcx(), id); + let nested_returns = if let Some(ref cfg) = cfg { + has_nested_returns(ccx.tcx(), cfg, blk_id) + } else { + false + }; let mut fcx = FunctionContext { llfn: llfndecl, @@ -1472,7 +1479,8 @@ pub fn new_fn_ctxt<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>, block_arena: block_arena, ccx: ccx, debug_context: debug_context, - scopes: RefCell::new(Vec::new()) + scopes: RefCell::new(Vec::new()), + cfg: cfg }; if has_env { diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 83938fa3357..c8a628a33e7 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -18,6 +18,7 @@ use session::Session; use llvm; use llvm::{ValueRef, BasicBlockRef, BuilderRef, ContextRef}; use llvm::{True, False, Bool}; +use middle::cfg; use middle::def; use middle::infer; use middle::lang_items::LangItem; @@ -264,6 +265,8 @@ pub struct FunctionContext<'a, 'tcx: 'a> { // Cleanup scopes. pub scopes: RefCell>>, + + pub cfg: Option, } impl<'a, 'tcx> FunctionContext<'a, 'tcx> { From fb3e871734957d83aab0cc55d45be7d75d6a7b15 Mon Sep 17 00:00:00 2001 From: James Miller Date: Tue, 16 Dec 2014 12:35:59 +1300 Subject: [PATCH 11/58] Add some documentation --- src/librustc_trans/trans/base.rs | 10 ++++++++++ src/librustc_trans/trans/controlflow.rs | 9 +++++++++ src/librustc_trans/trans/expr.rs | 20 +++++++++++++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 1a82a7131a7..87f9d4c447f 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -1393,6 +1393,16 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option) (blk.id, Some(cfg::CFG::new(tcx, &**blk))) } +// Checks for the presence of "nested returns" in a function. +// Nested returns are when the inner expression of a return expression +// (the 'expr' in 'return expr') contains a return expression. Only cases +// where the outer return is actually reachable are considered. Implicit +// returns from the end of blocks are considered as well. +// +// This check is needed to handle the case where the inner expression is +// part of a larger expression that may have already partially-filled the +// return slot alloca. This can cause errors related to clean-up due to +// the clobbering of the existing value in the return slot. fn has_nested_returns(tcx: &ty::ctxt, cfg: &cfg::CFG, blk_id: ast::NodeId) -> bool { for n in cfg.graph.depth_traverse(cfg.entry) { match tcx.map.find(n.id) { diff --git a/src/librustc_trans/trans/controlflow.rs b/src/librustc_trans/trans/controlflow.rs index a1574aa2f0e..e55da561c94 100644 --- a/src/librustc_trans/trans/controlflow.rs +++ b/src/librustc_trans/trans/controlflow.rs @@ -112,8 +112,17 @@ pub fn trans_block<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, if dest != expr::Ignore { let block_ty = node_id_type(bcx, b.id); + if b.expr.is_none() || type_is_zero_size(bcx.ccx(), block_ty) { dest = expr::Ignore; + } else if b.expr.is_some() { + // If the block has an expression, but that expression isn't reachable, + // don't save into the destination given, ignore it. + if let Some(ref cfg) = bcx.fcx.cfg { + if !cfg.node_is_reachable(b.expr.as_ref().unwrap().id) { + dest = expr::Ignore; + } + } } } diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 690e7cf81f5..0307412ce74 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -928,7 +928,25 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, controlflow::trans_cont(bcx, expr.id, label_opt) } ast::ExprRet(ref ex) => { - controlflow::trans_ret(bcx, ex.as_ref().map(|e| &**e)) + // Check to see if the return expression itself is reachable. + // This can occur when the inner expression contains a return + let reachable = if let Some(ref cfg) = bcx.fcx.cfg { + cfg.node_is_reachable(expr.id) + } else { + true + }; + + if reachable { + controlflow::trans_ret(bcx, ex.as_ref().map(|e| &**e)) + } else { + // If it's not reachable, just translate the inner expression + // directly. This avoids having to manage a return slot when + // it won't actually be used anyway. + if let &Some(ref x) = ex { + bcx = trans_into(bcx, &**x, Ignore); + } + bcx + } } ast::ExprWhile(ref cond, ref body, _) => { controlflow::trans_while(bcx, expr.id, &**cond, &**body) From 9115b319c31d644f01387c9fe3eff9a498941090 Mon Sep 17 00:00:00 2001 From: James Miller Date: Tue, 16 Dec 2014 13:09:35 +1300 Subject: [PATCH 12/58] Fix formatting issues --- src/librustc_trans/trans/base.rs | 3 ++- src/librustc_trans/trans/controlflow.rs | 2 +- src/librustc_trans/trans/expr.rs | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 87f9d4c447f..2cfcce2a961 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -1381,7 +1381,8 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option) _ => tcx.sess.bug("unexpected expr variant in has_nested_returns") } } - Some(ast_map::NodeVariant(..)) | Some(ast_map::NodeStructCtor(..)) => return (ast::DUMMY_NODE_ID, None), + Some(ast_map::NodeVariant(..)) | + Some(ast_map::NodeStructCtor(..)) => return (ast::DUMMY_NODE_ID, None), // glue, shims, etc None if id == ast::DUMMY_NODE_ID => return (ast::DUMMY_NODE_ID, None), diff --git a/src/librustc_trans/trans/controlflow.rs b/src/librustc_trans/trans/controlflow.rs index e55da561c94..550cf93b314 100644 --- a/src/librustc_trans/trans/controlflow.rs +++ b/src/librustc_trans/trans/controlflow.rs @@ -112,7 +112,7 @@ pub fn trans_block<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, if dest != expr::Ignore { let block_ty = node_id_type(bcx, b.id); - + if b.expr.is_none() || type_is_zero_size(bcx.ccx(), block_ty) { dest = expr::Ignore; } else if b.expr.is_some() { diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 0307412ce74..6cefda59737 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -944,7 +944,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // it won't actually be used anyway. if let &Some(ref x) = ex { bcx = trans_into(bcx, &**x, Ignore); - } + } bcx } } From b4f54f96df60337cb939f6f753a1cc6181e70f4b Mon Sep 17 00:00:00 2001 From: James Miller Date: Wed, 17 Dec 2014 13:24:35 +1300 Subject: [PATCH 13/58] Minor fixes --- src/librustc/middle/cfg/mod.rs | 5 +---- src/librustc/middle/graph.rs | 6 ++---- src/librustc_trans/trans/base.rs | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/librustc/middle/cfg/mod.rs b/src/librustc/middle/cfg/mod.rs index 0e9bd42a23a..04f86d0a9ba 100644 --- a/src/librustc/middle/cfg/mod.rs +++ b/src/librustc/middle/cfg/mod.rs @@ -51,9 +51,6 @@ impl CFG { } pub fn node_is_reachable(&self, id: ast::NodeId) -> bool { - for node in self.graph.depth_traverse(self.entry) { - if node.id == id { return true } - } - return false; + self.graph.depth_traverse(self.entry).any(|node| node.id == id) } } diff --git a/src/librustc/middle/graph.rs b/src/librustc/middle/graph.rs index 4397f03a642..3ba72801e2b 100644 --- a/src/librustc/middle/graph.rs +++ b/src/librustc/middle/graph.rs @@ -313,12 +313,10 @@ pub struct DepthFirstTraversal<'g, N:'g, E:'g> { impl<'g, N, E> Iterator<&'g N> for DepthFirstTraversal<'g, N, E> { fn next(&mut self) -> Option<&'g N> { - while self.stack.len() > 0 { - let idx = self.stack.pop().unwrap(); - if self.visited.contains(&idx.node_id()) { + while let Some(idx) = self.stack.pop() { + if self.visited.insert(idx.node_id()) { continue; } - self.visited.insert(idx.node_id()); self.graph.each_outgoing_edge(idx, |_, e| -> bool { if !self.visited.contains(&e.target().node_id()) { self.stack.push(e.target()); diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 2cfcce2a961..5b90dec8323 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -1468,7 +1468,7 @@ pub fn new_fn_ctxt<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>, let debug_context = debuginfo::create_function_debug_context(ccx, id, param_substs, llfndecl); let (blk_id, cfg) = build_cfg(ccx.tcx(), id); let nested_returns = if let Some(ref cfg) = cfg { - has_nested_returns(ccx.tcx(), cfg, blk_id) + has_nested_returns(ccx.tcx(), cfg, blk_id) } else { false }; From 9bb5380d80dc961fc3bd7edd13d6584f5cc48b66 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Wed, 17 Dec 2014 20:12:41 -0800 Subject: [PATCH 14/58] Stability: tweak rules for trait impls There is currently no way to specify the stability level for a trait impl produced by `deriving`. This patch is a stopgap solution that: * Turns of stability inheritance for trait impls, and * Uses the stability level of the *trait* if no level is directly specified. That is, manual trait impls may still provide a directly stability level, but `deriving` will use the level of the trait. While not a perfect solution, it should be good enough for 1.0 API stabilization, as we will like *remove* any unwanted impls outright. --- src/librustc/middle/stability.rs | 70 +++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 19 deletions(-) diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index ca8029fdfca..c4a5fd2f14a 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -43,7 +43,8 @@ struct Annotator { impl Annotator { // Determine the stability for a node based on its attributes and inherited // stability. The stability is recorded in the index and used as the parent. - fn annotate(&mut self, id: NodeId, attrs: &Vec, f: F) where + fn annotate(&mut self, id: NodeId, use_parent: bool, + attrs: &Vec, f: F) where F: FnOnce(&mut Annotator), { match attr::find_stability(attrs.as_slice()) { @@ -60,7 +61,9 @@ impl Annotator { } } None => { - self.parent.clone().map(|stab| self.index.local.insert(id, stab)); + if use_parent { + self.parent.clone().map(|stab| self.index.local.insert(id, stab)); + } f(self); } } @@ -69,11 +72,24 @@ impl Annotator { impl<'v> Visitor<'v> for Annotator { fn visit_item(&mut self, i: &Item) { - self.annotate(i.id, &i.attrs, |v| visit::walk_item(v, i)); + // FIXME (#18969): the following is a hack around the fact + // that we cannot currently annotate the stability of + // `deriving`. Basically, we do *not* allow stability + // inheritance on trait implementations, so that derived + // implementations appear to be unannotated. This then allows + // derived implementations to be automatically tagged with the + // stability of the trait. This is WRONG, but expedient to get + // libstd stabilized for the 1.0 release. + let use_parent = match i.node { + ast::ItemImpl(_, _, Some(_), _, _) => false, + _ => true, + }; + + self.annotate(i.id, use_parent, &i.attrs, |v| visit::walk_item(v, i)); if let ast::ItemStruct(ref sd, _) = i.node { sd.ctor_id.map(|id| { - self.annotate(id, &i.attrs, |_| {}) + self.annotate(id, true, &i.attrs, |_| {}) }); } } @@ -82,7 +98,7 @@ impl<'v> Visitor<'v> for Annotator { _: &'v Block, _: Span, _: NodeId) { if let FkMethod(_, _, meth) = fk { // Methods are not already annotated, so we annotate it - self.annotate(meth.id, &meth.attrs, |_| {}); + self.annotate(meth.id, true, &meth.attrs, |_| {}); } // Items defined in a function body have no reason to have // a stability attribute, so we don't recurse. @@ -101,15 +117,17 @@ impl<'v> Visitor<'v> for Annotator { TypeTraitItem(ref typedef) => (typedef.ty_param.id, &typedef.attrs), }; - self.annotate(id, attrs, |v| visit::walk_trait_item(v, t)); + self.annotate(id, true, attrs, |v| visit::walk_trait_item(v, t)); } fn visit_variant(&mut self, var: &Variant, g: &'v Generics) { - self.annotate(var.node.id, &var.node.attrs, |v| visit::walk_variant(v, var, g)) + self.annotate(var.node.id, true, &var.node.attrs, + |v| visit::walk_variant(v, var, g)) } fn visit_struct_field(&mut self, s: &StructField) { - self.annotate(s.node.id, &s.node.attrs, |v| visit::walk_struct_field(v, s)); + self.annotate(s.node.id, true, &s.node.attrs, + |v| visit::walk_struct_field(v, s)); } } @@ -123,7 +141,8 @@ impl Index { }, parent: None }; - annotator.annotate(ast::CRATE_NODE_ID, &krate.attrs, |v| visit::walk_crate(v, krate)); + annotator.annotate(ast::CRATE_NODE_ID, true, &krate.attrs, + |v| visit::walk_crate(v, krate)); annotator.index } } @@ -135,16 +154,29 @@ pub fn lookup(tcx: &ty::ctxt, id: DefId) -> Option { match ty::trait_item_of_item(tcx, id) { Some(ty::MethodTraitItemId(trait_method_id)) if trait_method_id != id => { - lookup(tcx, trait_method_id) - } - _ if is_local(id) => { - tcx.stability.borrow().local.get(&id.node).cloned() - } - _ => { - let stab = csearch::get_stability(&tcx.sess.cstore, id); - let mut index = tcx.stability.borrow_mut(); - (*index).extern_cache.insert(id, stab.clone()); - stab + return lookup(tcx, trait_method_id) } + _ => {} } + + let item_stab = if is_local(id) { + tcx.stability.borrow().local.get(&id.node).cloned() + } else { + let stab = csearch::get_stability(&tcx.sess.cstore, id); + let mut index = tcx.stability.borrow_mut(); + (*index).extern_cache.insert(id, stab.clone()); + stab + }; + + item_stab.or_else(|| { + if let Some(trait_id) = ty::trait_id_of_impl(tcx, id) { + // FIXME (#18969): for the time being, simply use the + // stability of the trait to determine the stability of any + // unmarked impls for it. See FIXME above for more details. + + lookup(tcx, trait_id) + } else { + None + } + }) } From 5722410f72d0698f6ad9ba668e2282ff0bac5043 Mon Sep 17 00:00:00 2001 From: James Miller Date: Thu, 18 Dec 2014 17:43:50 +1300 Subject: [PATCH 15/58] Fix logic error and add unreachable after returns --- src/librustc/middle/graph.rs | 2 +- src/librustc_trans/trans/expr.rs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc/middle/graph.rs b/src/librustc/middle/graph.rs index 3ba72801e2b..45bdf1c89cf 100644 --- a/src/librustc/middle/graph.rs +++ b/src/librustc/middle/graph.rs @@ -314,7 +314,7 @@ pub struct DepthFirstTraversal<'g, N:'g, E:'g> { impl<'g, N, E> Iterator<&'g N> for DepthFirstTraversal<'g, N, E> { fn next(&mut self) -> Option<&'g N> { while let Some(idx) = self.stack.pop() { - if self.visited.insert(idx.node_id()) { + if !self.visited.insert(idx.node_id()) { continue; } self.graph.each_outgoing_edge(idx, |_, e| -> bool { diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 6cefda59737..b185e8098e4 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -945,6 +945,10 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, if let &Some(ref x) = ex { bcx = trans_into(bcx, &**x, Ignore); } + // Mark the end of the block as unreachable. Once we get to + // a return expression, there's no more we should be doing + // after this. + Unreachable(bcx); bcx } } From 6746b94f78b8a0f97fe2f75059d4de49c5481d77 Mon Sep 17 00:00:00 2001 From: Valerii Hiora Date: Thu, 18 Dec 2014 10:27:44 +0200 Subject: [PATCH 16/58] iOS: fallout of `marker::NoCopy` removal --- src/libstd/rand/os.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs index 6bccef07131..b7ed697dc56 100644 --- a/src/libstd/rand/os.rs +++ b/src/libstd/rand/os.rs @@ -170,7 +170,6 @@ mod imp { extern crate libc; use io::{IoResult}; - use kinds::marker; use mem; use os; use rand::Rng; From 85196bfca82bbed163b3ab539af0ebe8c3ee2b1d Mon Sep 17 00:00:00 2001 From: Valerii Hiora Date: Thu, 18 Dec 2014 10:33:20 +0200 Subject: [PATCH 17/58] Fixed deprecation warnings on Unicode literals --- src/libserialize/json.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index c811a16e2b1..bd64f5aded5 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -2760,9 +2760,9 @@ mod tests { fn test_write_char() { check_encoder_for_simple!('a', "\"a\""); check_encoder_for_simple!('\t', "\"\\t\""); - check_encoder_for_simple!('\u00a0', "\"\u00a0\""); - check_encoder_for_simple!('\uabcd', "\"\uabcd\""); - check_encoder_for_simple!('\U0010ffff', "\"\U0010ffff\""); + check_encoder_for_simple!('\u{00a0}', "\"\u{00a0}\""); + check_encoder_for_simple!('\u{abcd}', "\"\u{abcd}\""); + check_encoder_for_simple!('\u{10ffff}', "\"\u{10ffff}\""); } #[test] From 0e9b12b9cc7d2b005c07b12313c6008ba667d3d6 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 18 Dec 2014 12:37:20 +0100 Subject: [PATCH 18/58] Add regression test for Issue 19811. Fix #19811. --- src/test/run-pass/issue-19811-escape-unicode.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/test/run-pass/issue-19811-escape-unicode.rs diff --git a/src/test/run-pass/issue-19811-escape-unicode.rs b/src/test/run-pass/issue-19811-escape-unicode.rs new file mode 100644 index 00000000000..23400859e54 --- /dev/null +++ b/src/test/run-pass/issue-19811-escape-unicode.rs @@ -0,0 +1,17 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let mut escaped = String::from_str(""); + for c in '\u{10401}'.escape_unicode() { + escaped.push(c); + } + assert_eq!("\\u{10401}", escaped); +} From 11d9175a90b90bfe019b34d1a98a6edceda7a6b2 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Thu, 18 Dec 2014 06:39:01 -0800 Subject: [PATCH 19/58] serialize: keep libserialize in sync with rustc-serialize to simplify merging --- src/libserialize/json.rs | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index c811a16e2b1..25edf81f9df 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -2016,7 +2016,6 @@ macro_rules! read_primitive { impl ::Decoder for Decoder { fn read_nil(&mut self) -> DecodeResult<()> { - debug!("read_nil"); expect!(self.pop(), Null) } @@ -2034,7 +2033,6 @@ impl ::Decoder for Decoder { fn read_f32(&mut self) -> DecodeResult { self.read_f64().map(|x| x as f32) } fn read_f64(&mut self) -> DecodeResult { - debug!("read_f64"); match self.pop() { Json::I64(f) => Ok(f as f64), Json::U64(f) => Ok(f as f64), @@ -2053,7 +2051,6 @@ impl ::Decoder for Decoder { } fn read_bool(&mut self) -> DecodeResult { - debug!("read_bool"); expect!(self.pop(), Boolean) } @@ -2071,14 +2068,12 @@ impl ::Decoder for Decoder { } fn read_str(&mut self) -> DecodeResult { - debug!("read_str"); expect!(self.pop(), String) } fn read_enum(&mut self, name: &str, f: F) -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { - debug!("read_enum({})", name); f(self) } @@ -2086,7 +2081,6 @@ impl ::Decoder for Decoder { mut f: F) -> DecodeResult where F: FnMut(&mut Decoder, uint) -> DecodeResult, { - debug!("read_enum_variant(names={})", names); let name = match self.pop() { Json::String(s) => s, Json::Object(mut o) => { @@ -2129,14 +2123,12 @@ impl ::Decoder for Decoder { fn read_enum_variant_arg(&mut self, idx: uint, f: F) -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { - debug!("read_enum_variant_arg(idx={})", idx); f(self) } fn read_enum_struct_variant(&mut self, names: &[&str], f: F) -> DecodeResult where F: FnMut(&mut Decoder, uint) -> DecodeResult, { - debug!("read_enum_struct_variant(names={})", names); self.read_enum_variant(names, f) } @@ -2148,14 +2140,12 @@ impl ::Decoder for Decoder { -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { - debug!("read_enum_struct_variant_field(name={}, idx={})", name, idx); self.read_enum_variant_arg(idx, f) } fn read_struct(&mut self, name: &str, len: uint, f: F) -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { - debug!("read_struct(name={}, len={})", name, len); let value = try!(f(self)); self.pop(); Ok(value) @@ -2168,7 +2158,6 @@ impl ::Decoder for Decoder { -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { - debug!("read_struct_field(name={}, idx={})", name, idx); let mut obj = try!(expect!(self.pop(), Object)); let value = match obj.remove(&name.to_string()) { @@ -2193,7 +2182,6 @@ impl ::Decoder for Decoder { fn read_tuple(&mut self, tuple_len: uint, f: F) -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { - debug!("read_tuple()"); self.read_seq(move |d, len| { if len == tuple_len { f(d) @@ -2206,7 +2194,6 @@ impl ::Decoder for Decoder { fn read_tuple_arg(&mut self, idx: uint, f: F) -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { - debug!("read_tuple_arg(idx={})", idx); self.read_seq_elt(idx, f) } @@ -2217,7 +2204,6 @@ impl ::Decoder for Decoder { -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { - debug!("read_tuple_struct(name={})", name); self.read_tuple(len, f) } @@ -2227,14 +2213,12 @@ impl ::Decoder for Decoder { -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { - debug!("read_tuple_struct_arg(idx={})", idx); self.read_tuple_arg(idx, f) } fn read_option(&mut self, mut f: F) -> DecodeResult where F: FnMut(&mut Decoder, bool) -> DecodeResult, { - debug!("read_option()"); match self.pop() { Json::Null => f(self, false), value => { self.stack.push(value); f(self, true) } @@ -2244,7 +2228,6 @@ impl ::Decoder for Decoder { fn read_seq(&mut self, f: F) -> DecodeResult where F: FnOnce(&mut Decoder, uint) -> DecodeResult, { - debug!("read_seq()"); let array = try!(expect!(self.pop(), Array)); let len = array.len(); for v in array.into_iter().rev() { @@ -2256,14 +2239,12 @@ impl ::Decoder for Decoder { fn read_seq_elt(&mut self, idx: uint, f: F) -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { - debug!("read_seq_elt(idx={})", idx); f(self) } fn read_map(&mut self, f: F) -> DecodeResult where F: FnOnce(&mut Decoder, uint) -> DecodeResult, { - debug!("read_map()"); let obj = try!(expect!(self.pop(), Object)); let len = obj.len(); for (key, value) in obj.into_iter() { @@ -2276,14 +2257,12 @@ impl ::Decoder for Decoder { fn read_map_elt_key(&mut self, idx: uint, f: F) -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { - debug!("read_map_elt_key(idx={})", idx); f(self) } fn read_map_elt_val(&mut self, idx: uint, f: F) -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { - debug!("read_map_elt_val(idx={})", idx); f(self) } @@ -2445,9 +2424,7 @@ mod tests { use super::ParserError::*; use super::DecoderError::*; use super::JsonEvent::*; - use super::ParserState::*; use super::StackElement::*; - use super::InternalStackElement::*; use super::{PrettyEncoder, Json, from_str, DecodeResult, DecoderError, JsonEvent, Parser, StackElement, Stack, Encoder, Decoder}; use std::{i64, u64, f32, f64, io}; @@ -2682,8 +2659,6 @@ mod tests { } fn with_str_writer(f: F) -> string::String where F: FnOnce(&mut io::Writer){ - use std::str; - let mut m = Vec::new(); f(&mut m as &mut io::Writer); string::String::from_utf8(m).unwrap() @@ -2760,9 +2735,9 @@ mod tests { fn test_write_char() { check_encoder_for_simple!('a', "\"a\""); check_encoder_for_simple!('\t', "\"\\t\""); - check_encoder_for_simple!('\u00a0', "\"\u00a0\""); - check_encoder_for_simple!('\uabcd', "\"\uabcd\""); - check_encoder_for_simple!('\U0010ffff', "\"\U0010ffff\""); + check_encoder_for_simple!('\u{00a0}', "\"\u{00a0}\""); + check_encoder_for_simple!('\u{abcd}', "\"\u{abcd}\""); + check_encoder_for_simple!('\u{10ffff}', "\"\u{10ffff}\""); } #[test] From d729c966bb8f1a0fe06f432e5c9c9aa2f03c4820 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Thu, 18 Dec 2014 07:02:25 -0800 Subject: [PATCH 20/58] serialize: silence some warnings --- src/libserialize/json.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 25edf81f9df..a04f56793f8 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -2071,7 +2071,7 @@ impl ::Decoder for Decoder { expect!(self.pop(), String) } - fn read_enum(&mut self, name: &str, f: F) -> DecodeResult where + fn read_enum(&mut self, _name: &str, f: F) -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { f(self) @@ -2120,7 +2120,7 @@ impl ::Decoder for Decoder { f(self, idx) } - fn read_enum_variant_arg(&mut self, idx: uint, f: F) -> DecodeResult where + fn read_enum_variant_arg(&mut self, _idx: uint, f: F) -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { f(self) @@ -2134,7 +2134,7 @@ impl ::Decoder for Decoder { fn read_enum_struct_variant_field(&mut self, - name: &str, + _name: &str, idx: uint, f: F) -> DecodeResult where @@ -2143,7 +2143,7 @@ impl ::Decoder for Decoder { self.read_enum_variant_arg(idx, f) } - fn read_struct(&mut self, name: &str, len: uint, f: F) -> DecodeResult where + fn read_struct(&mut self, _name: &str, _len: uint, f: F) -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { let value = try!(f(self)); @@ -2153,7 +2153,7 @@ impl ::Decoder for Decoder { fn read_struct_field(&mut self, name: &str, - idx: uint, + _idx: uint, f: F) -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, @@ -2198,7 +2198,7 @@ impl ::Decoder for Decoder { } fn read_tuple_struct(&mut self, - name: &str, + _name: &str, len: uint, f: F) -> DecodeResult where @@ -2236,7 +2236,7 @@ impl ::Decoder for Decoder { f(self, len) } - fn read_seq_elt(&mut self, idx: uint, f: F) -> DecodeResult where + fn read_seq_elt(&mut self, _idx: uint, f: F) -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { f(self) @@ -2254,13 +2254,13 @@ impl ::Decoder for Decoder { f(self, len) } - fn read_map_elt_key(&mut self, idx: uint, f: F) -> DecodeResult where + fn read_map_elt_key(&mut self, _idx: uint, f: F) -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { f(self) } - fn read_map_elt_val(&mut self, idx: uint, f: F) -> DecodeResult where + fn read_map_elt_val(&mut self, _idx: uint, f: F) -> DecodeResult where F: FnOnce(&mut Decoder) -> DecodeResult, { f(self) From 3d6babee9de8448823f99879e951d379b70a8a34 Mon Sep 17 00:00:00 2001 From: Philip Munksgaard Date: Thu, 18 Dec 2014 16:22:10 +0100 Subject: [PATCH 21/58] Use `-perm /a+x` instead of `-perm +a+x` in calls to find The use of `+a+x` is deprecated. Fixes #19981. --- mk/tests.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mk/tests.mk b/mk/tests.mk index 3340f9b4969..61fd736ef35 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -299,7 +299,7 @@ tidy: | xargs -n 10 $(CFG_PYTHON) $(S)src/etc/tidy.py $(Q)echo $(ALL_HS) \ | xargs -n 10 $(CFG_PYTHON) $(S)src/etc/tidy.py - $(Q)find $(S)src -type f -perm +a+x \ + $(Q)find $(S)src -type f -perm /a+x \ -not -name '*.rs' -and -not -name '*.py' \ -and -not -name '*.sh' \ | grep '^$(S)src/jemalloc' -v \ From 01aa4ca7d8da7e2dabc91aa3de4616109c93a9d2 Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner Date: Wed, 17 Dec 2014 21:16:18 -0500 Subject: [PATCH 22/58] Clean up `collections::binary_heap` --- src/libcollections/binary_heap.rs | 52 +++++++++++++++++-------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index 94211592698..7af40dea058 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -241,7 +241,7 @@ impl BinaryHeap { /// } /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn iter<'a>(&'a self) -> Items<'a, T> { + pub fn iter(&self) -> Items { Items { iter: self.data.iter() } } @@ -282,8 +282,8 @@ impl BinaryHeap { /// assert_eq!(heap.top(), Some(&5i)); /// /// ``` - pub fn top<'a>(&'a self) -> Option<&'a T> { - if self.is_empty() { None } else { Some(&self.data[0]) } + pub fn top(&self) -> Option<&T> { + self.data.get(0) } /// Returns the number of elements the queue can hold without reallocating. @@ -394,9 +394,9 @@ impl BinaryHeap { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn push(&mut self, item: T) { + let old_len = self.len(); self.data.push(item); - let new_len = self.len() - 1; - self.siftup(0, new_len); + self.siftup(0, old_len); } /// Pushes an item onto a queue then pops the greatest item off the queue in @@ -417,10 +417,16 @@ impl BinaryHeap { /// assert_eq!(heap.top(), Some(&3i)); /// ``` pub fn push_pop(&mut self, mut item: T) -> T { - if !self.is_empty() && *self.top().unwrap() > item { - swap(&mut item, &mut self.data[0]); - self.siftdown(0); + match self.data.get_mut(0) { + None => return item, + Some(top) => if *top > item { + swap(&mut item, top); + } else { + return item; + }, } + + self.siftdown(0); item } @@ -467,7 +473,7 @@ impl BinaryHeap { /// println!("{}", x); /// } /// ``` - pub fn into_vec(self) -> Vec { let BinaryHeap{data: v} = self; v } + pub fn into_vec(self) -> Vec { self.data } /// Consumes the `BinaryHeap` and returns a vector in sorted /// (ascending) order. @@ -484,15 +490,14 @@ impl BinaryHeap { /// let vec = heap.into_sorted_vec(); /// assert_eq!(vec, vec![1i, 2, 3, 4, 5, 6, 7]); /// ``` - pub fn into_sorted_vec(self) -> Vec { - let mut q = self; - let mut end = q.len(); + pub fn into_sorted_vec(mut self) -> Vec { + let mut end = self.len(); while end > 1 { end -= 1; - q.data.swap(0, end); - q.siftdown_range(0, end) + self.data.swap(0, end); + self.siftdown_range(0, end) } - q.into_vec() + self.into_vec() } // The implementations of siftup and siftdown use unsafe blocks in @@ -559,13 +564,13 @@ impl BinaryHeap { } /// `BinaryHeap` iterator. -pub struct Items <'a, T:'a> { +pub struct Items<'a, T: 'a> { iter: slice::Items<'a, T>, } impl<'a, T> Iterator<&'a T> for Items<'a, T> { #[inline] - fn next(&mut self) -> Option<(&'a T)> { self.iter.next() } + fn next(&mut self) -> Option<&'a T> { self.iter.next() } #[inline] fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } @@ -573,7 +578,7 @@ impl<'a, T> Iterator<&'a T> for Items<'a, T> { impl<'a, T> DoubleEndedIterator<&'a T> for Items<'a, T> { #[inline] - fn next_back(&mut self) -> Option<(&'a T)> { self.iter.next_back() } + fn next_back(&mut self) -> Option<&'a T> { self.iter.next_back() } } impl<'a, T> ExactSizeIterator<&'a T> for Items<'a, T> {} @@ -600,8 +605,7 @@ impl ExactSizeIterator for MoveItems {} impl FromIterator for BinaryHeap { fn from_iter>(iter: Iter) -> BinaryHeap { - let vec: Vec = iter.collect(); - BinaryHeap::from_vec(vec) + BinaryHeap::from_vec(iter.collect()) } } @@ -796,20 +800,20 @@ mod tests { #[test] fn test_empty_pop() { - let mut heap: BinaryHeap = BinaryHeap::new(); + let mut heap = BinaryHeap::::new(); assert!(heap.pop().is_none()); } #[test] fn test_empty_top() { - let empty: BinaryHeap = BinaryHeap::new(); + let empty = BinaryHeap::::new(); assert!(empty.top().is_none()); } #[test] fn test_empty_replace() { - let mut heap: BinaryHeap = BinaryHeap::new(); - heap.replace(5).is_none(); + let mut heap = BinaryHeap::::new(); + assert!(heap.replace(5).is_none()); } #[test] From 15d54549d7311893eacd43d7d6cb527ac2acf944 Mon Sep 17 00:00:00 2001 From: th0114nd Date: Thu, 18 Dec 2014 14:47:43 -0500 Subject: [PATCH 23/58] Put quotes around "as", because it's a keyword. --- src/doc/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index 3d4791e916e..88330536d45 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -934,7 +934,7 @@ kinds of view items: ```{.ebnf .gram} extern_crate_decl : "extern" "crate" crate_name -crate_name: ident | ( string_lit as ident ) +crate_name: ident | ( string_lit "as" ident ) ``` An _`extern crate` declaration_ specifies a dependency on an external crate. From edb39b8b336278ca8b437c974d2da25d68e9e549 Mon Sep 17 00:00:00 2001 From: th0114nd Date: Thu, 18 Dec 2014 17:55:34 -0500 Subject: [PATCH 24/58] Boolean literals are not Number literals The current indentation level would indicate that Boolean literals are on the same level as Integer and Float literals under Number literals, unindenting moves it to the same scope as Character and string literals, Byte and byte string literals, and Number literals under Literals. --- src/doc/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index 3d4791e916e..9e4c01771d9 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -518,7 +518,7 @@ This last example is different because it is not possible to use the suffix syntax with a floating point literal ending in a period. `2.f64` would attempt to call a method named `f64` on `2`. -##### Boolean literals +#### Boolean literals The two values of the boolean type are written `true` and `false`. From 1b42e890bf99d37a9e6447912c75c5b5e4695c4e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 18 Dec 2014 19:13:32 -0800 Subject: [PATCH 25/58] std: Remove public bool,tuple,unit modules This commit modifies rustdoc to not require these empty modules to be public in the standard library. The modules still remain as a location to attach documentation to, but the modules themselves are now private (don't have to commit to an API). The documentation for the standard library now shows all of the primitive types on the main index page. --- src/libcore/lib.rs | 7 +-- src/libcore/{tuple/mod.rs => tuple.rs} | 2 - src/librustdoc/clean/mod.rs | 23 +++------ src/{libcore => libstd}/bool.rs | 3 +- src/libstd/lib.rs | 11 +++-- src/libstd/prelude.rs | 6 +-- src/libstd/tuple.rs | 66 ++++++++++++++++++++++++++ src/{libcore/tuple => libstd}/unit.rs | 3 +- src/test/compile-fail/issue-9957.rs | 2 +- 9 files changed, 86 insertions(+), 37 deletions(-) rename src/libcore/{tuple/mod.rs => tuple.rs} (99%) rename src/{libcore => libstd}/bool.rs (80%) create mode 100644 src/libstd/tuple.rs rename src/{libcore/tuple => libstd}/unit.rs (91%) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 729cb69193e..9b6622a7127 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -107,7 +107,6 @@ pub mod default; pub mod any; pub mod atomic; -pub mod bool; pub mod borrow; pub mod cell; pub mod char; @@ -120,15 +119,11 @@ pub mod result; pub mod simd; pub mod slice; pub mod str; -pub mod tuple; pub mod hash; -// FIXME #15320: primitive documentation needs top-level modules, this -// should be `core::tuple::unit`. -#[path = "tuple/unit.rs"] -pub mod unit; pub mod fmt; // note: does not need to be public +mod tuple; mod array; #[doc(hidden)] diff --git a/src/libcore/tuple/mod.rs b/src/libcore/tuple.rs similarity index 99% rename from src/libcore/tuple/mod.rs rename to src/libcore/tuple.rs index 5ea84f7db91..4984c8de3bf 100644 --- a/src/libcore/tuple/mod.rs +++ b/src/libcore/tuple.rs @@ -62,12 +62,10 @@ //! assert_eq!(d, (0u32, 0.0f32)); //! ``` -#![doc(primitive = "tuple")] #![stable] #[unstable = "this is just a documentation module and should not be part \ of the public api"] -pub use unit; use clone::Clone; use cmp::*; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d640f055388..9a75890e283 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -163,33 +163,24 @@ impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> { }; let mut tmp = Vec::new(); for child in m.items.iter_mut() { - let inner = match child.inner { - ModuleItem(ref mut m) => m, + match child.inner { + ModuleItem(..) => {} _ => continue, - }; + } let prim = match PrimitiveType::find(child.attrs.as_slice()) { Some(prim) => prim, None => continue, }; primitives.push(prim); - let mut i = Item { + tmp.push(Item { source: Span::empty(), name: Some(prim.to_url_str().to_string()), - attrs: Vec::new(), - visibility: None, + attrs: child.attrs.clone(), + visibility: Some(ast::Public), stability: None, def_id: ast_util::local_def(prim.to_node_id()), inner: PrimitiveItem(prim), - }; - // Push one copy to get indexed for the whole crate, and push a - // another copy in the proper location which will actually get - // documented. The first copy will also serve as a redirect to - // the other copy. - tmp.push(i.clone()); - i.visibility = Some(ast::Public); - i.attrs = child.attrs.clone(); - inner.items.push(i); - + }); } m.items.extend(tmp.into_iter()); } diff --git a/src/libcore/bool.rs b/src/libstd/bool.rs similarity index 80% rename from src/libcore/bool.rs rename to src/libstd/bool.rs index 9d2ea816fdf..bbaab5ee3db 100644 --- a/src/libcore/bool.rs +++ b/src/libstd/bool.rs @@ -11,6 +11,5 @@ //! The boolean type #![doc(primitive = "bool")] -#![unstable = "this module is purely for documentation and it will likely be \ - removed from the public api"] +#![stable] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index e99aba9b673..d34fcc9011b 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -137,7 +137,6 @@ extern crate rustrt; // NB: These reexports are in the order they should be listed in rustdoc pub use core::any; -pub use core::bool; pub use core::borrow; pub use core::cell; pub use core::clone; @@ -152,10 +151,6 @@ pub use core::mem; pub use core::ptr; pub use core::raw; pub use core::simd; -pub use core::tuple; -// FIXME #15320: primitive documentation needs top-level modules, this -// should be `std::tuple::unit`. -pub use core::unit; pub use core::result; pub use core::option; @@ -246,6 +241,12 @@ pub mod comm; pub mod rt; mod failure; +// Documentation for primitive types + +mod bool; +mod unit; +mod tuple; + // A curious inner-module that's not exported that contains the binding // 'std' so that macro-expanded references to std::error and such // can be resolved within libstd. diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 8b6575b6bc1..f77627711a7 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -81,9 +81,9 @@ #[doc(no_inline)] pub use io::{Buffer, Writer, Reader, Seek, BufferPrelude}; #[doc(no_inline)] pub use str::{Str, StrVector, StrPrelude}; #[doc(no_inline)] pub use str::{StrAllocating, UnicodeStrPrelude}; -#[doc(no_inline)] pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4}; -#[doc(no_inline)] pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8}; -#[doc(no_inline)] pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12}; +#[doc(no_inline)] pub use core::prelude::{Tuple1, Tuple2, Tuple3, Tuple4}; +#[doc(no_inline)] pub use core::prelude::{Tuple5, Tuple6, Tuple7, Tuple8}; +#[doc(no_inline)] pub use core::prelude::{Tuple9, Tuple10, Tuple11, Tuple12}; #[doc(no_inline)] pub use slice::AsSlice; #[doc(no_inline)] pub use slice::{VectorVector, PartialEqSliceExt}; #[doc(no_inline)] pub use slice::{CloneSliceExt, OrdSliceExt, SliceExt}; diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs new file mode 100644 index 00000000000..5cd60d6e153 --- /dev/null +++ b/src/libstd/tuple.rs @@ -0,0 +1,66 @@ +// Copyright 2012 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. + +//! Operations on tuples +//! +//! To access a single element of a tuple one can use the following +//! methods: +//! +//! * `valN` - returns a value of _N_-th element +//! * `refN` - returns a reference to _N_-th element +//! * `mutN` - returns a mutable reference to _N_-th element +//! +//! Indexing starts from zero, so `val0` returns first value, `val1` +//! returns second value, and so on. In general, a tuple with _S_ +//! elements provides aforementioned methods suffixed with numbers +//! from `0` to `S-1`. Traits which contain these methods are +//! implemented for tuples with up to 12 elements. +//! +//! If every type inside a tuple implements one of the following +//! traits, then a tuple itself also implements it. +//! +//! * `Clone` +//! * `PartialEq` +//! * `Eq` +//! * `PartialOrd` +//! * `Ord` +//! * `Default` +//! +//! # Examples +//! +//! Using methods: +//! +//! ``` +//! #[allow(deprecated)] +//! # fn main() { +//! let pair = ("pi", 3.14f64); +//! assert_eq!(pair.val0(), "pi"); +//! assert_eq!(pair.val1(), 3.14f64); +//! # } +//! ``` +//! +//! Using traits implemented for tuples: +//! +//! ``` +//! use std::default::Default; +//! +//! let a = (1i, 2i); +//! let b = (3i, 4i); +//! assert!(a != b); +//! +//! let c = b.clone(); +//! assert!(b == c); +//! +//! let d : (u32, f32) = Default::default(); +//! assert_eq!(d, (0u32, 0.0f32)); +//! ``` + +#![doc(primitive = "tuple")] +#![stable] diff --git a/src/libcore/tuple/unit.rs b/src/libstd/unit.rs similarity index 91% rename from src/libcore/tuple/unit.rs rename to src/libstd/unit.rs index 7f89f0e5ae3..012b175b031 100644 --- a/src/libcore/tuple/unit.rs +++ b/src/libstd/unit.rs @@ -9,8 +9,7 @@ // except according to those terms. #![doc(primitive = "unit")] -#![unstable = "this module is purely for documentation and it will likely be \ - removed from the public api"] +#![stable] //! The `()` type, sometimes called "unit" or "nil". //! diff --git a/src/test/compile-fail/issue-9957.rs b/src/test/compile-fail/issue-9957.rs index a90a1ac1a75..573d847cbe3 100644 --- a/src/test/compile-fail/issue-9957.rs +++ b/src/test/compile-fail/issue-9957.rs @@ -11,5 +11,5 @@ pub extern crate core; //~ ERROR: `pub` visibility is not allowed fn main() { - pub use std::bool; //~ ERROR: imports in functions are never reachable + pub use std::uint; //~ ERROR: imports in functions are never reachable } From ce10c0114fca9d9e19a40fca184344db9273a161 Mon Sep 17 00:00:00 2001 From: Alexis Beingessner Date: Mon, 8 Dec 2014 20:12:35 -0500 Subject: [PATCH 26/58] clean up ptr docs --- src/libcore/intrinsics.rs | 34 +++++++------ src/libcore/ptr.rs | 100 ++++++++++++++++++++++++++++---------- 2 files changed, 94 insertions(+), 40 deletions(-) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index ece2ac6975e..294a7b71a87 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -220,7 +220,7 @@ extern "rust-intrinsic" { /// Both types must have the same size and alignment, and this guarantee /// is enforced at compile-time. /// - /// # Example + /// # Examples /// /// ```rust /// use std::mem; @@ -250,14 +250,20 @@ extern "rust-intrinsic" { /// integer, since the conversion would throw away aliasing information. pub fn offset(dst: *const T, offset: int) -> *const T; - /// Copies data from one location to another. - /// - /// Copies `count` elements (not bytes) from `src` to `dst`. The source + /// Copies `count * size_of` bytes from `src` to `dst`. The source /// and destination may *not* overlap. /// /// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`. /// - /// # Example + /// # Safety + /// + /// Beyond requiring that both regions of memory be allocated, it is Undefined Behaviour + /// for source and destination to overlap. Care must also be taken with the ownership of + /// `src` and `dst`. This method semantically moves the values of `src` into `dst`. + /// However it does not drop the contents of `dst`, or prevent the contents of `src` + /// from being dropped or used. + /// + /// # Examples /// /// A safe swap function: /// @@ -281,22 +287,22 @@ extern "rust-intrinsic" { /// } /// } /// ``` - /// - /// # Safety Note - /// - /// If the source and destination overlap then the behavior of this - /// function is undefined. #[unstable] pub fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: uint); - /// Copies data from one location to another. - /// - /// Copies `count` elements (not bytes) from `src` to `dst`. The source + /// Copies `count * size_of` bytes from `src` to `dst`. The source /// and destination may overlap. /// /// `copy_memory` is semantically equivalent to C's `memmove`. /// - /// # Example + /// # Safety + /// + /// Care must be taken with the ownership of `src` and `dst`. + /// This method semantically moves the values of `src` into `dst`. + /// However it does not drop the contents of `dst`, or prevent the contents of `src` + /// from being dropped or used. + /// + /// # Examples /// /// Efficiently create a Rust vector from an unsafe buffer: /// diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 3f6ac49786d..0944536b49b 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -97,13 +97,20 @@ use cmp::{PartialEq, Eq, PartialOrd, Equiv}; use cmp::Ordering; use cmp::Ordering::{Less, Equal, Greater}; -pub use intrinsics::copy_memory; +// FIXME #19649: instrinsic docs don't render, so these have no docs :( + +#[unstable] pub use intrinsics::copy_nonoverlapping_memory; + +#[unstable] +pub use intrinsics::copy_memory; + +#[experimental = "uncertain about naming and semantics"] pub use intrinsics::set_memory; -/// Create a null pointer. +/// Creates a null raw pointer. /// -/// # Example +/// # Examples /// /// ``` /// use std::ptr; @@ -115,9 +122,9 @@ pub use intrinsics::set_memory; #[unstable = "may need a different name after pending changes to pointer types"] pub fn null() -> *const T { 0 as *const T } -/// Create an unsafe mutable null pointer. +/// Creates a null mutable raw pointer. /// -/// # Example +/// # Examples /// /// ``` /// use std::ptr; @@ -129,7 +136,12 @@ pub fn null() -> *const T { 0 as *const T } #[unstable = "may need a different name after pending changes to pointer types"] pub fn null_mut() -> *mut T { 0 as *mut T } -/// Zeroes out `count * size_of::` bytes of memory at `dst` +/// Zeroes out `count * size_of::` bytes of memory at `dst`. `count` may be `0`. +/// +/// # Safety +/// +/// Beyond accepting a raw pointer, this is unsafe because it will not drop the contents of `dst`, +/// and may be used to create invalid instances of `T`. #[inline] #[experimental = "uncertain about naming and semantics"] #[allow(experimental)] @@ -137,8 +149,13 @@ pub unsafe fn zero_memory(dst: *mut T, count: uint) { set_memory(dst, 0, count); } -/// Swap the values at two mutable locations of the same type, without -/// deinitialising either. They may overlap. +/// Swaps the values at two mutable locations of the same type, without +/// deinitialising either. They may overlap, unlike `mem::swap` which is otherwise +/// equivalent. +/// +/// # Safety +/// +/// This is only unsafe because it accepts a raw pointer. #[inline] #[unstable] pub unsafe fn swap(x: *mut T, y: *mut T) { @@ -156,8 +173,13 @@ pub unsafe fn swap(x: *mut T, y: *mut T) { mem::forget(tmp); } -/// Replace the value at a mutable location with a new one, returning the old -/// value, without deinitialising either. +/// Replaces the value at `dest` with `src`, returning the old +/// value, without dropping either. +/// +/// # Safety +/// +/// This is only unsafe because it accepts a raw pointer. +/// Otherwise, this operation is identical to `mem::replace`. #[inline] #[unstable] pub unsafe fn replace(dest: *mut T, mut src: T) -> T { @@ -165,7 +187,17 @@ pub unsafe fn replace(dest: *mut T, mut src: T) -> T { src } -/// Reads the value from `*src` and returns it. +/// Reads the value from `src` without dropping it. This leaves the +/// memory in `src` unchanged. +/// +/// # Safety +/// +/// Beyond accepting a raw pointer, this is unsafe because it semantically +/// moves the value out of `src` without preventing further usage of `src`. +/// If `T` is not `Copy`, then care must be taken to ensure that the value at +/// `src` is not used before the data is overwritten again (e.g. with `write`, +/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use +/// because it will attempt to drop the value previously at `*src`. #[inline(always)] #[unstable] pub unsafe fn read(src: *const T) -> T { @@ -174,8 +206,11 @@ pub unsafe fn read(src: *const T) -> T { tmp } -/// Reads the value from `*src` and nulls it out. -/// This currently prevents destructors from executing. +/// Reads the value from `src` and nulls it out without dropping it. +/// +/// # Safety +/// +/// This is unsafe for the same reasons that `read` is unsafe. #[inline(always)] #[experimental] #[allow(experimental)] @@ -189,12 +224,17 @@ pub unsafe fn read_and_zero(dest: *mut T) -> T { tmp } -/// Unsafely overwrite a memory location with the given value without destroying +/// Overwrites a memory location with the given value without reading or dropping /// the old value. /// -/// This operation is unsafe because it does not destroy the previous value -/// contained at the location `dst`. This could leak allocations or resources, -/// so care must be taken to previously deallocate the value at `dst`. +/// # Safety +/// +/// Beyond accepting a raw pointer, this operation is unsafe because it does +/// not drop the contents of `dst`. This could leak allocations or resources, +/// so care must be taken not to overwrite an object that should be dropped. +/// +/// This is appropriate for initializing uninitialized memory, or overwritting memory +/// that has previously been `read` from. #[inline] #[unstable] pub unsafe fn write(dst: *mut T, src: T) { @@ -203,39 +243,47 @@ pub unsafe fn write(dst: *mut T, src: T) { /// Methods on raw pointers pub trait RawPtr { - /// Returns the null pointer. + /// Returns a null raw pointer. fn null() -> Self; - /// Returns true if the pointer is equal to the null pointer. + /// Returns true if the pointer is null. fn is_null(&self) -> bool; - /// Returns true if the pointer is not equal to the null pointer. + /// Returns true if the pointer is not null. fn is_not_null(&self) -> bool { !self.is_null() } - /// Returns the value of this pointer (ie, the address it points to) + /// Returns the address of the pointer. fn to_uint(&self) -> uint; /// Returns `None` if the pointer is null, or else returns a reference to the /// value wrapped in `Some`. /// - /// # Safety Notes + /// # Safety /// /// While this method and its mutable counterpart are useful for null-safety, /// it is important to note that this is still an unsafe operation because /// the returned value could be pointing to invalid memory. unsafe fn as_ref<'a>(&self) -> Option<&'a T>; - /// Calculates the offset from a pointer. The offset *must* be in-bounds of - /// the object, or one-byte-past-the-end. `count` is in units of T; e.g. a + /// Calculates the offset from a pointer. `count` is in units of T; e.g. a /// `count` of 3 represents a pointer offset of `3 * sizeof::()` bytes. + /// + /// # Safety + /// + /// The offset must be in-bounds of the object, or one-byte-past-the-end. Otherwise + /// `offset` invokes Undefined Behaviour, regardless of whether the pointer is used. unsafe fn offset(self, count: int) -> Self; } /// Methods on mutable raw pointers pub trait RawMutPtr{ /// Returns `None` if the pointer is null, or else returns a mutable reference - /// to the value wrapped in `Some`. As with `as_ref`, this is unsafe because - /// it cannot verify the validity of the returned pointer. + /// to the value wrapped in `Some`. + /// + /// # Safety + /// + /// As with `as_ref`, this is unsafe because it cannot verify the validity + /// of the returned pointer. unsafe fn as_mut<'a>(&self) -> Option<&'a mut T>; } From b0481147184a8ee70f066423dc077ffa0bd821b5 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 19 Dec 2014 09:48:28 +0100 Subject: [PATCH 27/58] debuginfo: Create debuginfo for for-loop variables again. --- src/librustc_trans/trans/controlflow.rs | 3 ++ src/librustc_trans/trans/debuginfo.rs | 37 +++++++++++++++++++ .../debuginfo/lexical-scope-in-for-loop.rs | 1 - 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/librustc_trans/trans/controlflow.rs b/src/librustc_trans/trans/controlflow.rs index a1574aa2f0e..e1b04fde98d 100644 --- a/src/librustc_trans/trans/controlflow.rs +++ b/src/librustc_trans/trans/controlflow.rs @@ -277,6 +277,7 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, debug!("iterator type is {}, datum type is {}", ppaux::ty_to_string(bcx.tcx(), iterator_type), ppaux::ty_to_string(bcx.tcx(), iterator_datum.ty)); + let lliterator = load_ty(bcx, iterator_datum.val, iterator_datum.ty); // Create our basic blocks and set up our loop cleanups. @@ -356,6 +357,8 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, llpayload, binding_cleanup_scope_id); + debuginfo::create_for_loop_var_metadata(body_bcx_in, pat); + // Codegen the body. body_bcx_out = trans_block(body_bcx_out, body, expr::Ignore); body_bcx_out = diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index e9730f7af0e..018cf7a02a3 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -1051,6 +1051,43 @@ pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) { }) } +/// Creates debug information for the given for-loop variable. +/// +/// Adds the created metadata nodes directly to the crate's IR. +pub fn create_for_loop_var_metadata(bcx: Block, pat: &ast::Pat) { + if fn_should_be_ignored(bcx.fcx) { + return; + } + + let def_map = &bcx.tcx().def_map; + + pat_util::pat_bindings(def_map, pat, |_, node_id, span, spanned_ident| { + let datum = match bcx.fcx.lllocals.borrow().get(&node_id).cloned() { + Some(datum) => datum, + None => { + bcx.sess().span_bug(span, + format!("no entry in lllocals table for {}", + node_id).as_slice()); + } + }; + + if unsafe { llvm::LLVMIsAAllocaInst(datum.val) } == ptr::null_mut() { + bcx.sess().span_bug(span, "debuginfo::create_for_loop_var_metadata() - \ + Referenced variable location is not an alloca!"); + } + + let scope_metadata = scope_metadata(bcx.fcx, node_id, span); + + declare_local(bcx, + spanned_ident.node, + datum.ty, + scope_metadata, + DirectVariable { alloca: datum.val }, + LocalVariable, + span); + }) +} + pub fn get_cleanup_debug_loc_for_ast_node<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, node_id: ast::NodeId, node_span: Span, diff --git a/src/test/debuginfo/lexical-scope-in-for-loop.rs b/src/test/debuginfo/lexical-scope-in-for-loop.rs index bcaebb5c153..7636ffdb07d 100644 --- a/src/test/debuginfo/lexical-scope-in-for-loop.rs +++ b/src/test/debuginfo/lexical-scope-in-for-loop.rs @@ -9,7 +9,6 @@ // except according to those terms. // ignore-android: FIXME(#10381) -// ignore-test: Not sure what is going on here --pcwalton // min-lldb-version: 310 // compile-flags:-g From 14a5992ef614a76cd36972191ea4507a3d3daccb Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Thu, 18 Dec 2014 18:31:29 -0800 Subject: [PATCH 28/58] Allow marker types to have unsized parameters Tweak CovariantType, ContravariantType, and InvariantType to allow their type parameter to be unsized. --- src/libcore/kinds.rs | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/libcore/kinds.rs b/src/libcore/kinds.rs index 69f65e23389..bf1a7ec2999 100644 --- a/src/libcore/kinds.rs +++ b/src/libcore/kinds.rs @@ -91,7 +91,8 @@ pub trait Sync for Sized? { /// implemented using unsafe code. In that case, you may want to embed /// some of the marker types below into your type. pub mod marker { - use super::Copy; + use super::{Copy,Sized}; + use clone::Clone; /// A marker type whose type parameter `T` is considered to be /// covariant with respect to the type itself. This is (typically) @@ -131,10 +132,13 @@ pub mod marker { /// (for example, `S<&'static int>` is a subtype of `S<&'a int>` /// for some lifetime `'a`, but not the other way around). #[lang="covariant_type"] - #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)] - pub struct CovariantType; + #[deriving(PartialEq, Eq, PartialOrd, Ord)] + pub struct CovariantType; - impl Copy for CovariantType {} + impl Copy for CovariantType {} + impl Clone for CovariantType { + fn clone(&self) -> CovariantType { *self } + } /// A marker type whose type parameter `T` is considered to be /// contravariant with respect to the type itself. This is (typically) @@ -176,10 +180,13 @@ pub mod marker { /// function requires arguments of type `T`, it must also accept /// arguments of type `U`, hence such a conversion is safe. #[lang="contravariant_type"] - #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)] - pub struct ContravariantType; + #[deriving(PartialEq, Eq, PartialOrd, Ord)] + pub struct ContravariantType; - impl Copy for ContravariantType {} + impl Copy for ContravariantType {} + impl Clone for ContravariantType { + fn clone(&self) -> ContravariantType { *self } + } /// A marker type whose type parameter `T` is considered to be /// invariant with respect to the type itself. This is (typically) @@ -203,10 +210,13 @@ pub mod marker { /// never written, but in fact `Cell` uses unsafe code to achieve /// interior mutability. #[lang="invariant_type"] - #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)] - pub struct InvariantType; + #[deriving(PartialEq, Eq, PartialOrd, Ord)] + pub struct InvariantType; - impl Copy for InvariantType {} + impl Copy for InvariantType {} + impl Clone for InvariantType { + fn clone(&self) -> InvariantType { *self } + } /// As `CovariantType`, but for lifetime parameters. Using /// `CovariantLifetime<'a>` indicates that it is ok to substitute From 3bb91aa28fd36173a87dd9dd47e120d5223042e2 Mon Sep 17 00:00:00 2001 From: Philip Munksgaard Date: Thu, 18 Dec 2014 13:10:41 +0100 Subject: [PATCH 29/58] Add a check for uninferred type parameter This fixes #19978. The bug was introduced by 570325d, where if the type of an Fn has not been inferred (strs[0] is "_") we slice from 1 to 0. We now explicitly check if `strs[0]` is a single element tuple. --- src/librustc/util/ppaux.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 13b5c262bf7..b534823c2c5 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -543,7 +543,11 @@ pub fn parameterized<'tcx>(cx: &ctxt<'tcx>, if cx.lang_items.fn_trait_kind(did).is_some() { format!("{}({}){}", base, - strs[0][1 .. strs[0].len() - (strs[0].ends_with(",)") as uint+1)], + if strs[0].starts_with("(") && strs[0].ends_with(",)") { + strs[0][1 .. strs[0].len() - 2] // Remove '(' and ',)' + } else { + strs[0][] + }, if &*strs[1] == "()" { String::new() } else { format!(" -> {}", strs[1]) }) } else if strs.len() > 0 { format!("{}<{}>", base, strs.connect(", ")) From 34a6fcf19566e5015c1ef4c144a408a2f182cf4d Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 19 Dec 2014 11:37:49 +0100 Subject: [PATCH 30/58] debuginfo: Clean the debuginfo module up a bit. --- src/librustc_trans/trans/debuginfo.rs | 160 ++++++++++++++------------ 1 file changed, 87 insertions(+), 73 deletions(-) diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 018cf7a02a3..1091a684b23 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -182,7 +182,6 @@ //! comparatively expensive to construct, though, `ty::type_id()` is still used //! additionally as an optimization for cases where the exact same type has been //! seen before (which is most of the time). -use self::FunctionDebugContextRepr::*; use self::VariableAccess::*; use self::VariableKind::*; use self::MemberOffset::*; @@ -681,12 +680,8 @@ impl<'tcx> CrateDebugContext<'tcx> { } } -pub struct FunctionDebugContext { - repr: FunctionDebugContextRepr, -} - -enum FunctionDebugContextRepr { - DebugInfo(Box), +pub enum FunctionDebugContext { + RegularContext(Box), DebugInfoDisabled, FunctionWithoutDebugInfo, } @@ -696,13 +691,13 @@ impl FunctionDebugContext { cx: &CrateContext, span: Span) -> &'a FunctionDebugContextData { - match self.repr { - DebugInfo(box ref data) => data, - DebugInfoDisabled => { + match *self { + FunctionDebugContext::RegularContext(box ref data) => data, + FunctionDebugContext::DebugInfoDisabled => { cx.sess().span_bug(span, FunctionDebugContext::debuginfo_disabled_message()); } - FunctionWithoutDebugInfo => { + FunctionDebugContext::FunctionWithoutDebugInfo => { cx.sess().span_bug(span, FunctionDebugContext::should_be_ignored_message()); } @@ -846,6 +841,8 @@ pub fn create_global_var_metadata(cx: &CrateContext, /// Creates debug information for the given local variable. /// +/// This function assumes that there's a datum for each pattern component of the +/// local in `bcx.fcx.lllocals`. /// Adds the created metadata nodes directly to the crate's IR. pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) { if fn_should_be_ignored(bcx.fcx) { @@ -854,11 +851,10 @@ pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) { let cx = bcx.ccx(); let def_map = &cx.tcx().def_map; + let locals = bcx.fcx.lllocals.borrow(); - pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, path1| { - let var_ident = path1.node; - - let datum = match bcx.fcx.lllocals.borrow().get(&node_id).cloned() { + pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, var_ident| { + let datum = match locals.get(&node_id) { Some(datum) => datum, None => { bcx.sess().span_bug(span, @@ -867,10 +863,15 @@ pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) { } }; + if unsafe { llvm::LLVMIsAAllocaInst(datum.val) } == ptr::null_mut() { + cx.sess().span_bug(span, "debuginfo::create_local_var_metadata() - \ + Referenced variable location is not an alloca!"); + } + let scope_metadata = scope_metadata(bcx.fcx, node_id, span); declare_local(bcx, - var_ident, + var_ident.node, datum.ty, scope_metadata, DirectVariable { alloca: datum.val }, @@ -983,7 +984,7 @@ pub fn create_match_binding_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // for the binding. For ByRef bindings that's a `T*` but for ByMove bindings we // actually have `T**`. So to get the actual variable we need to dereference once // more. For ByCopy we just use the stack slot we created for the binding. - let var_type = match binding.trmode { + let var_access = match binding.trmode { TrByCopy(llbinding) => DirectVariable { alloca: llbinding }, @@ -1000,27 +1001,31 @@ pub fn create_match_binding_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, variable_ident, binding.ty, scope_metadata, - var_type, + var_access, LocalVariable, binding.span); } /// Creates debug information for the given function argument. /// +/// This function assumes that there's a datum for each pattern component of the +/// argument in `bcx.fcx.lllocals`. /// Adds the created metadata nodes directly to the crate's IR. pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) { if fn_should_be_ignored(bcx.fcx) { return; } - let fcx = bcx.fcx; - let cx = fcx.ccx; + let def_map = &bcx.tcx().def_map; + let scope_metadata = bcx + .fcx + .debug_context + .get_ref(bcx.ccx(), arg.pat.span) + .fn_metadata; + let locals = bcx.fcx.lllocals.borrow(); - let def_map = &cx.tcx().def_map; - let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata; - - pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, path1| { - let llarg = match bcx.fcx.lllocals.borrow().get(&node_id).cloned() { + pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, var_ident| { + let datum = match locals.get(&node_id) { Some(v) => v, None => { bcx.sess().span_bug(span, @@ -1029,23 +1034,27 @@ pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) { } }; - if unsafe { llvm::LLVMIsAAllocaInst(llarg.val) } == ptr::null_mut() { - cx.sess().span_bug(span, "debuginfo::create_argument_metadata() - \ - Referenced variable location is not an alloca!"); + if unsafe { llvm::LLVMIsAAllocaInst(datum.val) } == ptr::null_mut() { + bcx.sess().span_bug(span, "debuginfo::create_argument_metadata() - \ + Referenced variable location is not an alloca!"); } let argument_index = { - let counter = &fcx.debug_context.get_ref(cx, span).argument_counter; + let counter = &bcx + .fcx + .debug_context + .get_ref(bcx.ccx(), span) + .argument_counter; let argument_index = counter.get(); counter.set(argument_index + 1); argument_index }; declare_local(bcx, - path1.node, - llarg.ty, + var_ident.node, + datum.ty, scope_metadata, - DirectVariable { alloca: llarg.val }, + DirectVariable { alloca: datum.val }, ArgumentVariable(argument_index), span); }) @@ -1053,6 +1062,8 @@ pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) { /// Creates debug information for the given for-loop variable. /// +/// This function assumes that there's a datum for each pattern component of the +/// loop variable in `bcx.fcx.lllocals`. /// Adds the created metadata nodes directly to the crate's IR. pub fn create_for_loop_var_metadata(bcx: Block, pat: &ast::Pat) { if fn_should_be_ignored(bcx.fcx) { @@ -1060,9 +1071,10 @@ pub fn create_for_loop_var_metadata(bcx: Block, pat: &ast::Pat) { } let def_map = &bcx.tcx().def_map; + let locals = bcx.fcx.lllocals.borrow(); - pat_util::pat_bindings(def_map, pat, |_, node_id, span, spanned_ident| { - let datum = match bcx.fcx.lllocals.borrow().get(&node_id).cloned() { + pat_util::pat_bindings(def_map, pat, |_, node_id, span, var_ident| { + let datum = match locals.get(&node_id) { Some(datum) => datum, None => { bcx.sess().span_bug(span, @@ -1079,7 +1091,7 @@ pub fn create_for_loop_var_metadata(bcx: Block, pat: &ast::Pat) { let scope_metadata = scope_metadata(bcx.fcx, node_id, span); declare_local(bcx, - spanned_ident.node, + var_ident.node, datum.ty, scope_metadata, DirectVariable { alloca: datum.val }, @@ -1156,13 +1168,13 @@ pub fn get_cleanup_debug_loc_for_ast_node<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, pub fn set_source_location(fcx: &FunctionContext, node_id: ast::NodeId, span: Span) { - match fcx.debug_context.repr { - DebugInfoDisabled => return, - FunctionWithoutDebugInfo => { + match fcx.debug_context { + FunctionDebugContext::DebugInfoDisabled => return, + FunctionDebugContext::FunctionWithoutDebugInfo => { set_debug_location(fcx.ccx, UnknownLocation); return; } - DebugInfo(box ref function_debug_context) => { + FunctionDebugContext::RegularContext(box ref function_debug_context) => { let cx = fcx.ccx; debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span)); @@ -1199,8 +1211,8 @@ pub fn clear_source_location(fcx: &FunctionContext) { /// switches source location emitting on and must therefore be called before the /// first real statement/expression of the function is translated. pub fn start_emitting_source_locations(fcx: &FunctionContext) { - match fcx.debug_context.repr { - DebugInfo(box ref data) => { + match fcx.debug_context { + FunctionDebugContext::RegularContext(box ref data) => { data.source_locations_enabled.set(true) }, _ => { /* safe to ignore */ } @@ -1218,7 +1230,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, param_substs: &Substs<'tcx>, llfn: ValueRef) -> FunctionDebugContext { if cx.sess().opts.debuginfo == NoDebugInfo { - return FunctionDebugContext { repr: DebugInfoDisabled }; + return FunctionDebugContext::DebugInfoDisabled; } // Clear the debug location so we don't assign them in the function prelude. @@ -1228,7 +1240,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, if fn_ast_id == ast::DUMMY_NODE_ID { // This is a function not linked to any source location, so don't // generate debuginfo for it. - return FunctionDebugContext { repr: FunctionWithoutDebugInfo }; + return FunctionDebugContext::FunctionWithoutDebugInfo; } let empty_generics = ast_util::empty_generics(); @@ -1238,7 +1250,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let (ident, fn_decl, generics, top_level_block, span, has_path) = match fnitem { ast_map::NodeItem(ref item) => { if contains_nodebug_attribute(item.attrs.as_slice()) { - return FunctionDebugContext { repr: FunctionWithoutDebugInfo }; + return FunctionDebugContext::FunctionWithoutDebugInfo; } match item.node { @@ -1255,9 +1267,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, match **item { ast::MethodImplItem(ref method) => { if contains_nodebug_attribute(method.attrs.as_slice()) { - return FunctionDebugContext { - repr: FunctionWithoutDebugInfo - }; + return FunctionDebugContext::FunctionWithoutDebugInfo; } (method.pe_ident(), @@ -1296,9 +1306,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, match **trait_method { ast::ProvidedMethod(ref method) => { if contains_nodebug_attribute(method.attrs.as_slice()) { - return FunctionDebugContext { - repr: FunctionWithoutDebugInfo - }; + return FunctionDebugContext::FunctionWithoutDebugInfo; } (method.pe_ident(), @@ -1319,7 +1327,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ast_map::NodeForeignItem(..) | ast_map::NodeVariant(..) | ast_map::NodeStructCtor(..) => { - return FunctionDebugContext { repr: FunctionWithoutDebugInfo }; + return FunctionDebugContext::FunctionWithoutDebugInfo; } _ => cx.sess().bug(format!("create_function_debug_context: \ unexpected sort of node: {}", @@ -1328,7 +1336,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // This can be the case for functions inlined from another crate if span == codemap::DUMMY_SP { - return FunctionDebugContext { repr: FunctionWithoutDebugInfo }; + return FunctionDebugContext::FunctionWithoutDebugInfo; } let loc = span_start(cx, span); @@ -1395,22 +1403,23 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, }) }); + let scope_map = create_scope_map(cx, + fn_decl.inputs.as_slice(), + &*top_level_block, + fn_metadata, + fn_ast_id); + // Initialize fn debug context (including scope map and namespace map) let fn_debug_context = box FunctionDebugContextData { - scope_map: RefCell::new(NodeMap::new()), + scope_map: RefCell::new(scope_map), fn_metadata: fn_metadata, argument_counter: Cell::new(1), source_locations_enabled: Cell::new(false), }; - populate_scope_map(cx, - fn_decl.inputs.as_slice(), - &*top_level_block, - fn_metadata, - fn_ast_id, - &mut *fn_debug_context.scope_map.borrow_mut()); - return FunctionDebugContext { repr: DebugInfo(fn_debug_context) }; + + return FunctionDebugContext::RegularContext(fn_debug_context); fn get_function_signature<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fn_ast_id: ast::NodeId, @@ -3176,8 +3185,8 @@ fn DIB(cx: &CrateContext) -> DIBuilderRef { } fn fn_should_be_ignored(fcx: &FunctionContext) -> bool { - match fcx.debug_context.repr { - DebugInfo(_) => false, + match fcx.debug_context { + FunctionDebugContext::RegularContext(_) => false, _ => true } } @@ -3211,12 +3220,14 @@ fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: ast::DefId) // what belongs to which scope, creating DIScope DIEs along the way, and // introducing *artificial* lexical scope descriptors where necessary. These // artificial scopes allow GDB to correctly handle name shadowing. -fn populate_scope_map(cx: &CrateContext, - args: &[ast::Arg], - fn_entry_block: &ast::Block, - fn_metadata: DISubprogram, - fn_ast_id: ast::NodeId, - scope_map: &mut NodeMap) { +fn create_scope_map(cx: &CrateContext, + args: &[ast::Arg], + fn_entry_block: &ast::Block, + fn_metadata: DISubprogram, + fn_ast_id: ast::NodeId) + -> NodeMap { + let mut scope_map = NodeMap::new(); + let def_map = &cx.tcx().def_map; struct ScopeStackEntry { @@ -3242,11 +3253,14 @@ fn populate_scope_map(cx: &CrateContext, with_new_scope(cx, fn_entry_block.span, &mut scope_stack, - scope_map, + &mut scope_map, |cx, scope_stack, scope_map| { walk_block(cx, fn_entry_block, scope_stack, scope_map); }); + return scope_map; + + // local helper functions for walking the AST. fn with_new_scope(cx: &CrateContext, scope_span: Span, @@ -3482,7 +3496,7 @@ fn populate_scope_map(cx: &CrateContext, } ast::PatMac(_) => { - cx.sess().span_bug(pat.span, "debuginfo::populate_scope_map() - \ + cx.sess().span_bug(pat.span, "debuginfo::create_scope_map() - \ Found unexpanded macro."); } } @@ -3568,7 +3582,7 @@ fn populate_scope_map(cx: &CrateContext, } ast::ExprIfLet(..) => { - cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \ + cx.sess().span_bug(exp.span, "debuginfo::create_scope_map() - \ Found unexpanded if-let."); } @@ -3585,7 +3599,7 @@ fn populate_scope_map(cx: &CrateContext, } ast::ExprWhileLet(..) => { - cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \ + cx.sess().span_bug(exp.span, "debuginfo::create_scope_map() - \ Found unexpanded while-let."); } @@ -3610,7 +3624,7 @@ fn populate_scope_map(cx: &CrateContext, } ast::ExprMac(_) => { - cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \ + cx.sess().span_bug(exp.span, "debuginfo::create_scope_map() - \ Found unexpanded macro."); } From 87c5927b79b8eec8763659da8a3cf4561a4ceabd Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 19 Dec 2014 12:46:04 +0100 Subject: [PATCH 31/58] debuginfo: Add test case for destructured for-loop variable. --- .../destructured-for-loop-variable.rs | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 src/test/debuginfo/destructured-for-loop-variable.rs diff --git a/src/test/debuginfo/destructured-for-loop-variable.rs b/src/test/debuginfo/destructured-for-loop-variable.rs new file mode 100644 index 00000000000..19a82ee5e67 --- /dev/null +++ b/src/test/debuginfo/destructured-for-loop-variable.rs @@ -0,0 +1,178 @@ +// Copyright 2013-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. + +// ignore-android: FIXME(#10381) +// min-lldb-version: 310 + +// compile-flags:-g + +// === GDB TESTS =================================================================================== + +// gdb-command:run + +// DESTRUCTURED STRUCT +// gdb-command:print x +// gdb-check:$1 = 400 +// gdb-command:print y +// gdb-check:$2 = 401.5 +// gdb-command:print z +// gdb-check:$3 = true +// gdb-command:continue + +// DESTRUCTURED TUPLE +// gdb-command:print/x _i8 +// gdb-check:$4 = 0x6f +// gdb-command:print/x _u8 +// gdb-check:$5 = 0x70 +// gdb-command:print _i16 +// gdb-check:$6 = -113 +// gdb-command:print _u16 +// gdb-check:$7 = 114 +// gdb-command:print _i32 +// gdb-check:$8 = -115 +// gdb-command:print _u32 +// gdb-check:$9 = 116 +// gdb-command:print _i64 +// gdb-check:$10 = -117 +// gdb-command:print _u64 +// gdb-check:$11 = 118 +// gdb-command:print _f32 +// gdb-check:$12 = 119.5 +// gdb-command:print _f64 +// gdb-check:$13 = 120.5 +// gdb-command:continue + +// MORE COMPLEX CASE +// gdb-command:print v1 +// gdb-check:$14 = 80000 +// gdb-command:print x1 +// gdb-check:$15 = 8000 +// gdb-command:print *y1 +// gdb-check:$16 = 80001.5 +// gdb-command:print z1 +// gdb-check:$17 = false +// gdb-command:print *x2 +// gdb-check:$18 = -30000 +// gdb-command:print y2 +// gdb-check:$19 = -300001.5 +// gdb-command:print *z2 +// gdb-check:$20 = true +// gdb-command:print v2 +// gdb-check:$21 = 854237.5 +// gdb-command:continue + + +// === LLDB TESTS ================================================================================== + +// lldb-command:type format add --format hex char +// lldb-command:type format add --format hex 'unsigned char' + +// lldb-command:run + +// DESTRUCTURED STRUCT +// lldb-command:print x +// lldb-check:[...]$0 = 400 +// lldb-command:print y +// lldb-check:[...]$1 = 401.5 +// lldb-command:print z +// lldb-check:[...]$2 = true +// lldb-command:continue + +// DESTRUCTURED TUPLE +// lldb-command:print _i8 +// lldb-check:[...]$3 = 0x6f +// lldb-command:print _u8 +// lldb-check:[...]$4 = 0x70 +// lldb-command:print _i16 +// lldb-check:[...]$5 = -113 +// lldb-command:print _u16 +// lldb-check:[...]$6 = 114 +// lldb-command:print _i32 +// lldb-check:[...]$7 = -115 +// lldb-command:print _u32 +// lldb-check:[...]$8 = 116 +// lldb-command:print _i64 +// lldb-check:[...]$9 = -117 +// lldb-command:print _u64 +// lldb-check:[...]$10 = 118 +// lldb-command:print _f32 +// lldb-check:[...]$11 = 119.5 +// lldb-command:print _f64 +// lldb-check:[...]$12 = 120.5 +// lldb-command:continue + +// MORE COMPLEX CASE +// lldb-command:print v1 +// lldb-check:[...]$13 = 80000 +// lldb-command:print x1 +// lldb-check:[...]$14 = 8000 +// lldb-command:print *y1 +// lldb-check:[...]$15 = 80001.5 +// lldb-command:print z1 +// lldb-check:[...]$16 = false +// lldb-command:print *x2 +// lldb-check:[...]$17 = -30000 +// lldb-command:print y2 +// lldb-check:[...]$18 = -300001.5 +// lldb-command:print *z2 +// lldb-check:[...]$19 = true +// lldb-command:print v2 +// lldb-check:[...]$20 = 854237.5 +// lldb-command:continue + + +struct Struct { + x: i16, + y: f32, + z: bool +} + +fn main() { + + let s = Struct { + x: 400, + y: 401.5, + z: true + }; + + for &Struct { x, y, z } in [s].iter() { + zzz(); // #break + } + + let tuple: (i8, u8, i16, u16, i32, u32, i64, u64, f32, f64) = + (0x6f, 0x70, -113, 114, -115, 116, -117, 118, 119.5, 120.5); + + for &(_i8, _u8, _i16, _u16, _i32, _u32, _i64, _u64, _f32, _f64) in [tuple].iter() { + zzz(); // #break + } + + let more_complex: (i32, &Struct, Struct, Box) = + (80000, + &Struct { + x: 8000, + y: 80001.5, + z: false + }, + Struct { + x: -30000, + y: -300001.5, + z: true + }, + box 854237.5); + + for &(v1, + &Struct { x: x1, y: ref y1, z: z1 }, + Struct { x: ref x2, y: y2, z: ref z2 }, + box v2) in [more_complex].iter() { + zzz(); // #break + } +} + +fn zzz() {()} From 611ef49f2fa573edf9cff4442eddb8ee7e48878d Mon Sep 17 00:00:00 2001 From: Bheesham Persaud Date: Fri, 19 Dec 2014 08:57:15 -0500 Subject: [PATCH 32/58] Took out all of the metrics stuff from tests.mk References rust-lang/rust/#19145 modified: src/llvm (new commits) --- mk/tests.mk | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/mk/tests.mk b/mk/tests.mk index 3340f9b4969..17bacbefacb 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -73,21 +73,6 @@ endif TEST_LOG_FILE=tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).log TEST_OK_FILE=tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).ok -TEST_RATCHET_FILE=tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4)-metrics.json -TEST_RATCHET_NOISE_PERCENT=10.0 - -# Whether to ratchet or merely save benchmarks -ifdef CFG_RATCHET_BENCH -CRATE_TEST_EXTRA_ARGS= \ - --test $(TEST_BENCH) \ - --ratchet-metrics $(call TEST_RATCHET_FILE,$(1),$(2),$(3),$(4)) \ - --ratchet-noise-percent $(TEST_RATCHET_NOISE_PERCENT) -else -CRATE_TEST_EXTRA_ARGS= \ - --test $(TEST_BENCH) \ - --save-metrics $(call TEST_RATCHET_FILE,$(1),$(2),$(3),$(4)) -endif - # If we're sharding the testsuite between parallel testers, # pass this argument along to the compiletest and crate test # invocations. @@ -454,7 +439,6 @@ $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \ $$(Q)touch tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).log $$(Q)$(CFG_ADB) pull $(CFG_ADB_TEST_DIR)/check-stage$(1)-T-$(2)-H-$(3)-$(4).log tmp/ $$(Q)$(CFG_ADB) shell rm $(CFG_ADB_TEST_DIR)/check-stage$(1)-T-$(2)-H-$(3)-$(4).log - $$(Q)$(CFG_ADB) pull $(CFG_ADB_TEST_DIR)/$$(call TEST_RATCHET_FILE,$(1),$(2),$(3),$(4)) tmp/ @if grep -q "result: ok" tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp; \ then \ rm tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp; \ @@ -696,7 +680,6 @@ CTEST_ARGS$(1)-T-$(2)-H-$(3)-$(4) := \ $$(CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3)) \ --src-base $$(S)src/test/$$(CTEST_SRC_BASE_$(4))/ \ --build-base $(3)/test/$$(CTEST_BUILD_BASE_$(4))/ \ - --ratchet-metrics $(call TEST_RATCHET_FILE,$(1),$(2),$(3),$(4)) \ --mode $$(CTEST_MODE_$(4)) \ $$(CTEST_RUNTOOL_$(4)) From e5d8c855079e08e1aab2cf7b4e5110159ad8fa53 Mon Sep 17 00:00:00 2001 From: Valerii Hiora Date: Fri, 19 Dec 2014 16:11:26 +0200 Subject: [PATCH 33/58] iOS: fallout of runtime removal --- src/libstd/sys/unix/backtrace.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/unix/backtrace.rs b/src/libstd/sys/unix/backtrace.rs index df9dbad2ec7..983d0e5fa14 100644 --- a/src/libstd/sys/unix/backtrace.rs +++ b/src/libstd/sys/unix/backtrace.rs @@ -105,7 +105,7 @@ use sys_common::backtrace::*; #[cfg(all(target_os = "ios", target_arch = "arm"))] #[inline(never)] pub fn write(w: &mut Writer) -> IoResult<()> { - use iter::{Iterator, range}; + use iter::{IteratorExt, range}; use result; use slice::SliceExt; @@ -117,7 +117,7 @@ pub fn write(w: &mut Writer) -> IoResult<()> { // while it doesn't requires lock for work as everything is // local, it still displays much nicer backtraces when a // couple of tasks panic simultaneously - static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT; + static LOCK: StaticMutex = MUTEX_INIT; let _g = unsafe { LOCK.lock() }; try!(writeln!(w, "stack backtrace:")); From 84086c464f537591f0e4629676b3fc75517492ab Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 17 Dec 2014 23:02:47 -0800 Subject: [PATCH 34/58] Register new snapshots This does not yet start the movement to rustc-serialize. That detail is left to a future PR. --- src/libcollections/btree/set.rs | 96 ------- src/libcollections/enum_set.rs | 36 --- src/libcollections/string.rs | 22 -- src/libcollections/vec.rs | 15 - src/libcore/ops.rs | 437 ----------------------------- src/librustc/middle/ty.rs | 27 -- src/libstd/bitflags.rs | 44 --- src/libstd/time/duration.rs | 64 ----- src/libsyntax/codemap.rs | 36 --- src/libsyntax/ext/tt/transcribe.rs | 24 -- src/libtime/lib.rs | 34 --- src/snapshots.txt | 9 + 12 files changed, 9 insertions(+), 835 deletions(-) diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index 4ef2e681992..ef7b3fbf599 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -448,30 +448,6 @@ impl Default for BTreeSet { } #[unstable = "matches collection reform specification, waiting for dust to settle"] -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl Sub,BTreeSet> for BTreeSet { - /// Returns the difference of `self` and `rhs` as a new `BTreeSet`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeSet; - /// - /// let a: BTreeSet = vec![1,2,3].into_iter().collect(); - /// let b: BTreeSet = vec![3,4,5].into_iter().collect(); - /// - /// let result: BTreeSet = a - b; - /// let result_vec: Vec = result.into_iter().collect(); - /// assert_eq!(result_vec, vec![1,2]); - /// ``` - fn sub(&self, rhs: &BTreeSet) -> BTreeSet { - self.difference(rhs).cloned().collect() - } -} - -#[unstable = "matches collection reform specification, waiting for dust to settle"] -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl<'a, 'b, T: Ord + Clone> Sub<&'b BTreeSet, BTreeSet> for &'a BTreeSet { /// Returns the difference of `self` and `rhs` as a new `BTreeSet`. /// @@ -493,30 +469,6 @@ impl<'a, 'b, T: Ord + Clone> Sub<&'b BTreeSet, BTreeSet> for &'a BTreeSet< } #[unstable = "matches collection reform specification, waiting for dust to settle"] -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl BitXor,BTreeSet> for BTreeSet { - /// Returns the symmetric difference of `self` and `rhs` as a new `BTreeSet`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeSet; - /// - /// let a: BTreeSet = vec![1,2,3].into_iter().collect(); - /// let b: BTreeSet = vec![2,3,4].into_iter().collect(); - /// - /// let result: BTreeSet = a ^ b; - /// let result_vec: Vec = result.into_iter().collect(); - /// assert_eq!(result_vec, vec![1,4]); - /// ``` - fn bitxor(&self, rhs: &BTreeSet) -> BTreeSet { - self.symmetric_difference(rhs).cloned().collect() - } -} - -#[unstable = "matches collection reform specification, waiting for dust to settle"] -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl<'a, 'b, T: Ord + Clone> BitXor<&'b BTreeSet, BTreeSet> for &'a BTreeSet { /// Returns the symmetric difference of `self` and `rhs` as a new `BTreeSet`. /// @@ -538,30 +490,6 @@ impl<'a, 'b, T: Ord + Clone> BitXor<&'b BTreeSet, BTreeSet> for &'a BTreeS } #[unstable = "matches collection reform specification, waiting for dust to settle"] -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl BitAnd,BTreeSet> for BTreeSet { - /// Returns the intersection of `self` and `rhs` as a new `BTreeSet`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeSet; - /// - /// let a: BTreeSet = vec![1,2,3].into_iter().collect(); - /// let b: BTreeSet = vec![2,3,4].into_iter().collect(); - /// - /// let result: BTreeSet = a & b; - /// let result_vec: Vec = result.into_iter().collect(); - /// assert_eq!(result_vec, vec![2,3]); - /// ``` - fn bitand(&self, rhs: &BTreeSet) -> BTreeSet { - self.intersection(rhs).cloned().collect() - } -} - -#[unstable = "matches collection reform specification, waiting for dust to settle"] -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl<'a, 'b, T: Ord + Clone> BitAnd<&'b BTreeSet, BTreeSet> for &'a BTreeSet { /// Returns the intersection of `self` and `rhs` as a new `BTreeSet`. /// @@ -583,30 +511,6 @@ impl<'a, 'b, T: Ord + Clone> BitAnd<&'b BTreeSet, BTreeSet> for &'a BTreeS } #[unstable = "matches collection reform specification, waiting for dust to settle"] -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl BitOr,BTreeSet> for BTreeSet { - /// Returns the union of `self` and `rhs` as a new `BTreeSet`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeSet; - /// - /// let a: BTreeSet = vec![1,2,3].into_iter().collect(); - /// let b: BTreeSet = vec![3,4,5].into_iter().collect(); - /// - /// let result: BTreeSet = a | b; - /// let result_vec: Vec = result.into_iter().collect(); - /// assert_eq!(result_vec, vec![1,2,3,4,5]); - /// ``` - fn bitor(&self, rhs: &BTreeSet) -> BTreeSet { - self.union(rhs).cloned().collect() - } -} - -#[unstable = "matches collection reform specification, waiting for dust to settle"] -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet, BTreeSet> for &'a BTreeSet { /// Returns the union of `self` and `rhs` as a new `BTreeSet`. /// diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index 49b66ce25f5..554d642c638 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -183,60 +183,24 @@ impl EnumSet { } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl Sub, EnumSet> for EnumSet { - fn sub(&self, e: &EnumSet) -> EnumSet { - EnumSet {bits: self.bits & !e.bits} - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl Sub, EnumSet> for EnumSet { fn sub(self, e: EnumSet) -> EnumSet { EnumSet {bits: self.bits & !e.bits} } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl BitOr, EnumSet> for EnumSet { - fn bitor(&self, e: &EnumSet) -> EnumSet { - EnumSet {bits: self.bits | e.bits} - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl BitOr, EnumSet> for EnumSet { fn bitor(self, e: EnumSet) -> EnumSet { EnumSet {bits: self.bits | e.bits} } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl BitAnd, EnumSet> for EnumSet { - fn bitand(&self, e: &EnumSet) -> EnumSet { - EnumSet {bits: self.bits & e.bits} - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl BitAnd, EnumSet> for EnumSet { fn bitand(self, e: EnumSet) -> EnumSet { EnumSet {bits: self.bits & e.bits} } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl BitXor, EnumSet> for EnumSet { - fn bitxor(&self, e: &EnumSet) -> EnumSet { - EnumSet {bits: self.bits ^ e.bits} - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl BitXor, EnumSet> for EnumSet { fn bitxor(self, e: EnumSet) -> EnumSet { EnumSet {bits: self.bits ^ e.bits} diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 38ebd686ddb..b897f9b8df3 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -856,28 +856,7 @@ impl<'a, S: Str> Equiv for String { } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] #[experimental = "waiting on Add stabilization"] -impl Add for String { - /// Concatenates `self` and `other` as a new mutable `String`. - /// - /// # Examples - /// - /// ``` - /// let string1 = "foo".to_string(); - /// let string2 = "bar".to_string(); - /// let string3 = string1 + string2; - /// assert_eq!(string3, "foobar".to_string()); - /// ``` - fn add(&self, other: &S) -> String { - let mut s = String::from_str(self.as_slice()); - s.push_str(other.as_slice()); - return s; - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl<'a> Add<&'a str, String> for String { fn add(mut self, other: &str) -> String { self.push_str(other); @@ -885,7 +864,6 @@ impl<'a> Add<&'a str, String> for String { } } -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl<'a> Add for &'a str { fn add(self, mut other: String) -> String { other.push_str(self); diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 94e6103f05f..ffb4955c8fd 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1313,20 +1313,6 @@ impl AsSlice for Vec { } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl> Add> for Vec { - #[inline] - fn add(&self, rhs: &V) -> Vec { - let mut res = Vec::with_capacity(self.len() + rhs.as_slice().len()); - res.push_all(self.as_slice()); - res.push_all(rhs.as_slice()); - res - } -} - - -#[cfg(not(stage0))] // NOTE(stage0): Remove impl after a snapshot impl<'a, T: Clone> Add<&'a [T], Vec> for Vec { #[inline] fn add(mut self, rhs: &[T]) -> Vec { @@ -1335,7 +1321,6 @@ impl<'a, T: Clone> Add<&'a [T], Vec> for Vec { } } -#[cfg(not(stage0))] // NOTE(stage0): Remove impl after a snapshot impl<'a, T: Clone> Add, Vec> for &'a [T] { #[inline] fn add(self, mut rhs: Vec) -> Vec { diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 0090da3cdad..dd5cffeab03 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -93,46 +93,6 @@ pub trait Drop { /// impl Copy for Foo {} /// /// impl Add for Foo { -/// fn add(&self, _rhs: &Foo) -> Foo { -/// println!("Adding!"); -/// *self -/// } -/// } -/// -/// fn main() { -/// Foo + Foo; -/// } -/// ``` -// NOTE(stage0): Remove trait after a snapshot -#[cfg(stage0)] -#[lang="add"] -pub trait Add for Sized? { - /// The method for the `+` operator - fn add(&self, rhs: &RHS) -> Result; -} - -// NOTE(stage0): Remove macro after a snapshot -#[cfg(stage0)] -macro_rules! add_impl { - ($($t:ty)*) => ($( - impl Add<$t, $t> for $t { - #[inline] - fn add(&self, other: &$t) -> $t { (*self) + (*other) } - } - )*) -} - -/// The `Add` trait is used to specify the functionality of `+`. -/// -/// # Example -/// -/// A trivial implementation of `Add`. When `Foo + Foo` happens, it ends up -/// calling `add`, and therefore, `main` prints `Adding!`. -/// -/// ```rust -/// struct Foo; -/// -/// impl Add for Foo { /// fn add(self, _rhs: Foo) -> Foo { /// println!("Adding!"); /// self @@ -143,14 +103,12 @@ macro_rules! add_impl { /// Foo + Foo; /// } /// ``` -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot #[lang="add"] pub trait Add { /// The method for the `+` operator fn add(self, rhs: RHS) -> Result; } -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot macro_rules! add_impl { ($($t:ty)*) => ($( impl Add<$t, $t> for $t { @@ -175,46 +133,6 @@ add_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 } /// impl Copy for Foo {} /// /// impl Sub for Foo { -/// fn sub(&self, _rhs: &Foo) -> Foo { -/// println!("Subtracting!"); -/// *self -/// } -/// } -/// -/// fn main() { -/// Foo - Foo; -/// } -/// ``` -// NOTE(stage0): Remove trait after a snapshot -#[cfg(stage0)] -#[lang="sub"] -pub trait Sub for Sized? { - /// The method for the `-` operator - fn sub(&self, rhs: &RHS) -> Result; -} - -// NOTE(stage0): Remove macro after a snapshot -#[cfg(stage0)] -macro_rules! sub_impl { - ($($t:ty)*) => ($( - impl Sub<$t, $t> for $t { - #[inline] - fn sub(&self, other: &$t) -> $t { (*self) - (*other) } - } - )*) -} - -/// The `Sub` trait is used to specify the functionality of `-`. -/// -/// # Example -/// -/// A trivial implementation of `Sub`. When `Foo - Foo` happens, it ends up -/// calling `sub`, and therefore, `main` prints `Subtracting!`. -/// -/// ```rust -/// struct Foo; -/// -/// impl Sub for Foo { /// fn sub(self, _rhs: Foo) -> Foo { /// println!("Subtracting!"); /// self @@ -225,14 +143,12 @@ macro_rules! sub_impl { /// Foo - Foo; /// } /// ``` -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot #[lang="sub"] pub trait Sub { /// The method for the `-` operator fn sub(self, rhs: RHS) -> Result; } -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot macro_rules! sub_impl { ($($t:ty)*) => ($( impl Sub<$t, $t> for $t { @@ -257,46 +173,6 @@ sub_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 } /// impl Copy for Foo {} /// /// impl Mul for Foo { -/// fn mul(&self, _rhs: &Foo) -> Foo { -/// println!("Multiplying!"); -/// *self -/// } -/// } -/// -/// fn main() { -/// Foo * Foo; -/// } -/// ``` -// NOTE(stage0): Remove trait after a snapshot -#[cfg(stage0)] -#[lang="mul"] -pub trait Mul for Sized? { - /// The method for the `*` operator - fn mul(&self, rhs: &RHS) -> Result; -} - -// NOTE(stage0): Remove macro after a snapshot -#[cfg(stage0)] -macro_rules! mul_impl { - ($($t:ty)*) => ($( - impl Mul<$t, $t> for $t { - #[inline] - fn mul(&self, other: &$t) -> $t { (*self) * (*other) } - } - )*) -} - -/// The `Mul` trait is used to specify the functionality of `*`. -/// -/// # Example -/// -/// A trivial implementation of `Mul`. When `Foo * Foo` happens, it ends up -/// calling `mul`, and therefore, `main` prints `Multiplying!`. -/// -/// ```rust -/// struct Foo; -/// -/// impl Mul for Foo { /// fn mul(self, _rhs: Foo) -> Foo { /// println!("Multiplying!"); /// self @@ -307,14 +183,12 @@ macro_rules! mul_impl { /// Foo * Foo; /// } /// ``` -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot #[lang="mul"] pub trait Mul { /// The method for the `*` operator fn mul(self, rhs: RHS) -> Result; } -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot macro_rules! mul_impl { ($($t:ty)*) => ($( impl Mul<$t, $t> for $t { @@ -339,46 +213,6 @@ mul_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 } /// impl Copy for Foo {} /// /// impl Div for Foo { -/// fn div(&self, _rhs: &Foo) -> Foo { -/// println!("Dividing!"); -/// *self -/// } -/// } -/// -/// fn main() { -/// Foo / Foo; -/// } -/// ``` -// NOTE(stage0): Remove trait after a snapshot -#[cfg(stage0)] -#[lang="div"] -pub trait Div for Sized? { - /// The method for the `/` operator - fn div(&self, rhs: &RHS) -> Result; -} - -// NOTE(stage0): Remove macro after a snapshot -#[cfg(stage0)] -macro_rules! div_impl { - ($($t:ty)*) => ($( - impl Div<$t, $t> for $t { - #[inline] - fn div(&self, other: &$t) -> $t { (*self) / (*other) } - } - )*) -} - -/// The `Div` trait is used to specify the functionality of `/`. -/// -/// # Example -/// -/// A trivial implementation of `Div`. When `Foo / Foo` happens, it ends up -/// calling `div`, and therefore, `main` prints `Dividing!`. -/// -/// ``` -/// struct Foo; -/// -/// impl Div for Foo { /// fn div(self, _rhs: Foo) -> Foo { /// println!("Dividing!"); /// self @@ -389,14 +223,12 @@ macro_rules! div_impl { /// Foo / Foo; /// } /// ``` -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot #[lang="div"] pub trait Div { /// The method for the `/` operator fn div(self, rhs: RHS) -> Result; } -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot macro_rules! div_impl { ($($t:ty)*) => ($( impl Div<$t, $t> for $t { @@ -421,60 +253,6 @@ div_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 } /// impl Copy for Foo {} /// /// impl Rem for Foo { -/// fn rem(&self, _rhs: &Foo) -> Foo { -/// println!("Remainder-ing!"); -/// *self -/// } -/// } -/// -/// fn main() { -/// Foo % Foo; -/// } -/// ``` -// NOTE(stage0): Remove trait after a snapshot -#[cfg(stage0)] -#[lang="rem"] -pub trait Rem for Sized? { - /// The method for the `%` operator - fn rem(&self, rhs: &RHS) -> Result; -} - -// NOTE(stage0): Remove macro after a snapshot -#[cfg(stage0)] -macro_rules! rem_impl { - ($($t:ty)*) => ($( - impl Rem<$t, $t> for $t { - #[inline] - fn rem(&self, other: &$t) -> $t { (*self) % (*other) } - } - )*) -} - -// NOTE(stage0): Remove macro after a snapshot -#[cfg(stage0)] -macro_rules! rem_float_impl { - ($t:ty, $fmod:ident) => { - impl Rem<$t, $t> for $t { - #[inline] - fn rem(&self, other: &$t) -> $t { - extern { fn $fmod(a: $t, b: $t) -> $t; } - unsafe { $fmod(*self, *other) } - } - } - } -} - -/// The `Rem` trait is used to specify the functionality of `%`. -/// -/// # Example -/// -/// A trivial implementation of `Rem`. When `Foo % Foo` happens, it ends up -/// calling `rem`, and therefore, `main` prints `Remainder-ing!`. -/// -/// ``` -/// struct Foo; -/// -/// impl Rem for Foo { /// fn rem(self, _rhs: Foo) -> Foo { /// println!("Remainder-ing!"); /// self @@ -485,14 +263,12 @@ macro_rules! rem_float_impl { /// Foo % Foo; /// } /// ``` -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot #[lang="rem"] pub trait Rem { /// The method for the `%` operator fn rem(self, rhs: RHS) -> Result; } -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot macro_rules! rem_impl { ($($t:ty)*) => ($( impl Rem<$t, $t> for $t { @@ -502,7 +278,6 @@ macro_rules! rem_impl { )*) } -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot macro_rules! rem_float_impl { ($t:ty, $fmod:ident) => { impl Rem<$t, $t> for $t { @@ -729,46 +504,6 @@ not_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 } /// impl Copy for Foo {} /// /// impl BitAnd for Foo { -/// fn bitand(&self, _rhs: &Foo) -> Foo { -/// println!("Bitwise And-ing!"); -/// *self -/// } -/// } -/// -/// fn main() { -/// Foo & Foo; -/// } -/// ``` -// NOTE(stage0): Remove trait after a snapshot -#[cfg(stage0)] -#[lang="bitand"] -pub trait BitAnd for Sized? { - /// The method for the `&` operator - fn bitand(&self, rhs: &RHS) -> Result; -} - -// NOTE(stage0): Remove macro after a snapshot -#[cfg(stage0)] -macro_rules! bitand_impl { - ($($t:ty)*) => ($( - impl BitAnd<$t, $t> for $t { - #[inline] - fn bitand(&self, rhs: &$t) -> $t { (*self) & (*rhs) } - } - )*) -} - -/// The `BitAnd` trait is used to specify the functionality of `&`. -/// -/// # Example -/// -/// A trivial implementation of `BitAnd`. When `Foo & Foo` happens, it ends up -/// calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`. -/// -/// ``` -/// struct Foo; -/// -/// impl BitAnd for Foo { /// fn bitand(self, _rhs: Foo) -> Foo { /// println!("Bitwise And-ing!"); /// self @@ -779,14 +514,12 @@ macro_rules! bitand_impl { /// Foo & Foo; /// } /// ``` -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot #[lang="bitand"] pub trait BitAnd { /// The method for the `&` operator fn bitand(self, rhs: RHS) -> Result; } -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot macro_rules! bitand_impl { ($($t:ty)*) => ($( impl BitAnd<$t, $t> for $t { @@ -811,46 +544,6 @@ bitand_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 } /// impl Copy for Foo {} /// /// impl BitOr for Foo { -/// fn bitor(&self, _rhs: &Foo) -> Foo { -/// println!("Bitwise Or-ing!"); -/// *self -/// } -/// } -/// -/// fn main() { -/// Foo | Foo; -/// } -/// ``` -// NOTE(stage0): Remove trait after a snapshot -#[cfg(stage0)] -#[lang="bitor"] -pub trait BitOr for Sized? { - /// The method for the `|` operator - fn bitor(&self, rhs: &RHS) -> Result; -} - -// NOTE(stage0): Remove macro after a snapshot -#[cfg(stage0)] -macro_rules! bitor_impl { - ($($t:ty)*) => ($( - impl BitOr<$t,$t> for $t { - #[inline] - fn bitor(&self, rhs: &$t) -> $t { (*self) | (*rhs) } - } - )*) -} - -/// The `BitOr` trait is used to specify the functionality of `|`. -/// -/// # Example -/// -/// A trivial implementation of `BitOr`. When `Foo | Foo` happens, it ends up -/// calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`. -/// -/// ``` -/// struct Foo; -/// -/// impl BitOr for Foo { /// fn bitor(self, _rhs: Foo) -> Foo { /// println!("Bitwise Or-ing!"); /// self @@ -861,14 +554,12 @@ macro_rules! bitor_impl { /// Foo | Foo; /// } /// ``` -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot #[lang="bitor"] pub trait BitOr { /// The method for the `|` operator fn bitor(self, rhs: RHS) -> Result; } -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot macro_rules! bitor_impl { ($($t:ty)*) => ($( impl BitOr<$t,$t> for $t { @@ -893,46 +584,6 @@ bitor_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 } /// impl Copy for Foo {} /// /// impl BitXor for Foo { -/// fn bitxor(&self, _rhs: &Foo) -> Foo { -/// println!("Bitwise Xor-ing!"); -/// *self -/// } -/// } -/// -/// fn main() { -/// Foo ^ Foo; -/// } -/// ``` -// NOTE(stage0): Remove trait after a snapshot -#[cfg(stage0)] -#[lang="bitxor"] -pub trait BitXor for Sized? { - /// The method for the `^` operator - fn bitxor(&self, rhs: &RHS) -> Result; -} - -// NOTE(stage0): Remove macro after a snapshot -#[cfg(stage0)] -macro_rules! bitxor_impl { - ($($t:ty)*) => ($( - impl BitXor<$t, $t> for $t { - #[inline] - fn bitxor(&self, other: &$t) -> $t { (*self) ^ (*other) } - } - )*) -} - -/// The `BitXor` trait is used to specify the functionality of `^`. -/// -/// # Example -/// -/// A trivial implementation of `BitXor`. When `Foo ^ Foo` happens, it ends up -/// calling `bitxor`, and therefore, `main` prints `Bitwise Xor-ing!`. -/// -/// ``` -/// struct Foo; -/// -/// impl BitXor for Foo { /// fn bitxor(self, _rhs: Foo) -> Foo { /// println!("Bitwise Xor-ing!"); /// self @@ -943,14 +594,12 @@ macro_rules! bitxor_impl { /// Foo ^ Foo; /// } /// ``` -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot #[lang="bitxor"] pub trait BitXor { /// The method for the `^` operator fn bitxor(self, rhs: RHS) -> Result; } -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot macro_rules! bitxor_impl { ($($t:ty)*) => ($( impl BitXor<$t, $t> for $t { @@ -975,48 +624,6 @@ bitxor_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 } /// impl Copy for Foo {} /// /// impl Shl for Foo { -/// fn shl(&self, _rhs: &Foo) -> Foo { -/// println!("Shifting left!"); -/// *self -/// } -/// } -/// -/// fn main() { -/// Foo << Foo; -/// } -/// ``` -// NOTE(stage0): Remove trait after a snapshot -#[cfg(stage0)] -#[lang="shl"] -pub trait Shl for Sized? { - /// The method for the `<<` operator - fn shl(&self, rhs: &RHS) -> Result; -} - -// NOTE(stage0): Remove macro after a snapshot -#[cfg(stage0)] -macro_rules! shl_impl { - ($($t:ty)*) => ($( - impl Shl for $t { - #[inline] - fn shl(&self, other: &uint) -> $t { - (*self) << (*other) - } - } - )*) -} - -/// The `Shl` trait is used to specify the functionality of `<<`. -/// -/// # Example -/// -/// A trivial implementation of `Shl`. When `Foo << Foo` happens, it ends up -/// calling `shl`, and therefore, `main` prints `Shifting left!`. -/// -/// ``` -/// struct Foo; -/// -/// impl Shl for Foo { /// fn shl(self, _rhs: Foo) -> Foo { /// println!("Shifting left!"); /// self @@ -1027,14 +634,12 @@ macro_rules! shl_impl { /// Foo << Foo; /// } /// ``` -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot #[lang="shl"] pub trait Shl { /// The method for the `<<` operator fn shl(self, rhs: RHS) -> Result; } -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot macro_rules! shl_impl { ($($t:ty)*) => ($( impl Shl for $t { @@ -1061,46 +666,6 @@ shl_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 } /// impl Copy for Foo {} /// /// impl Shr for Foo { -/// fn shr(&self, _rhs: &Foo) -> Foo { -/// println!("Shifting right!"); -/// *self -/// } -/// } -/// -/// fn main() { -/// Foo >> Foo; -/// } -/// ``` -// NOTE(stage0): Remove trait after a snapshot -#[cfg(stage0)] -#[lang="shr"] -pub trait Shr for Sized? { - /// The method for the `>>` operator - fn shr(&self, rhs: &RHS) -> Result; -} - -// NOTE(stage0): Remove macro after a snapshot -#[cfg(stage0)] -macro_rules! shr_impl { - ($($t:ty)*) => ($( - impl Shr for $t { - #[inline] - fn shr(&self, other: &uint) -> $t { (*self) >> (*other) } - } - )*) -} - -/// The `Shr` trait is used to specify the functionality of `>>`. -/// -/// # Example -/// -/// A trivial implementation of `Shr`. When `Foo >> Foo` happens, it ends up -/// calling `shr`, and therefore, `main` prints `Shifting right!`. -/// -/// ``` -/// struct Foo; -/// -/// impl Shr for Foo { /// fn shr(self, _rhs: Foo) -> Foo { /// println!("Shifting right!"); /// self @@ -1111,14 +676,12 @@ macro_rules! shr_impl { /// Foo >> Foo; /// } /// ``` -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot #[lang="shr"] pub trait Shr { /// The method for the `>>` operator fn shr(self, rhs: RHS) -> Result; } -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot macro_rules! shr_impl { ($($t:ty)*) => ($( impl Shr for $t { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 6839e8bcc45..ab3a959d9a7 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2922,45 +2922,18 @@ impl TypeContents { } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl ops::BitOr for TypeContents { - fn bitor(&self, other: &TypeContents) -> TypeContents { - TypeContents {bits: self.bits | other.bits} - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl ops::BitOr for TypeContents { fn bitor(self, other: TypeContents) -> TypeContents { TypeContents {bits: self.bits | other.bits} } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl ops::BitAnd for TypeContents { - fn bitand(&self, other: &TypeContents) -> TypeContents { - TypeContents {bits: self.bits & other.bits} - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl ops::BitAnd for TypeContents { fn bitand(self, other: TypeContents) -> TypeContents { TypeContents {bits: self.bits & other.bits} } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl ops::Sub for TypeContents { - fn sub(&self, other: &TypeContents) -> TypeContents { - TypeContents {bits: self.bits & !other.bits} - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl ops::Sub for TypeContents { fn sub(self, other: TypeContents) -> TypeContents { TypeContents {bits: self.bits & !other.bits} diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs index f467b77dbf4..89aa4b3c9e9 100644 --- a/src/libstd/bitflags.rs +++ b/src/libstd/bitflags.rs @@ -205,17 +205,6 @@ macro_rules! bitflags { } } - // NOTE(stage0): Remove impl after a snapshot - #[cfg(stage0)] - impl BitOr<$BitFlags, $BitFlags> for $BitFlags { - /// Returns the union of the two sets of flags. - #[inline] - fn bitor(&self, other: &$BitFlags) -> $BitFlags { - $BitFlags { bits: self.bits | other.bits } - } - } - - #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl BitOr<$BitFlags, $BitFlags> for $BitFlags { /// Returns the union of the two sets of flags. #[inline] @@ -224,17 +213,6 @@ macro_rules! bitflags { } } - // NOTE(stage0): Remove impl after a snapshot - #[cfg(stage0)] - impl BitXor<$BitFlags, $BitFlags> for $BitFlags { - /// Returns the left flags, but with all the right flags toggled. - #[inline] - fn bitxor(&self, other: &$BitFlags) -> $BitFlags { - $BitFlags { bits: self.bits ^ other.bits } - } - } - - #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl BitXor<$BitFlags, $BitFlags> for $BitFlags { /// Returns the left flags, but with all the right flags toggled. #[inline] @@ -243,17 +221,6 @@ macro_rules! bitflags { } } - // NOTE(stage0): Remove impl after a snapshot - #[cfg(stage0)] - impl BitAnd<$BitFlags, $BitFlags> for $BitFlags { - /// Returns the intersection between the two sets of flags. - #[inline] - fn bitand(&self, other: &$BitFlags) -> $BitFlags { - $BitFlags { bits: self.bits & other.bits } - } - } - - #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl BitAnd<$BitFlags, $BitFlags> for $BitFlags { /// Returns the intersection between the two sets of flags. #[inline] @@ -262,17 +229,6 @@ macro_rules! bitflags { } } - // NOTE(stage0): Remove impl after a snapshot - #[cfg(stage0)] - impl Sub<$BitFlags, $BitFlags> for $BitFlags { - /// Returns the set difference of the two sets of flags. - #[inline] - fn sub(&self, other: &$BitFlags) -> $BitFlags { - $BitFlags { bits: self.bits & !other.bits } - } - } - - #[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl Sub<$BitFlags, $BitFlags> for $BitFlags { /// Returns the set difference of the two sets of flags. #[inline] diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs index 85ed27853c4..1d4fd38d48a 100644 --- a/src/libstd/time/duration.rs +++ b/src/libstd/time/duration.rs @@ -290,21 +290,6 @@ impl Neg for Duration { } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl Add for Duration { - fn add(&self, rhs: &Duration) -> Duration { - let mut secs = self.secs + rhs.secs; - let mut nanos = self.nanos + rhs.nanos; - if nanos >= NANOS_PER_SEC { - nanos -= NANOS_PER_SEC; - secs += 1; - } - Duration { secs: secs, nanos: nanos } - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl Add for Duration { fn add(self, rhs: Duration) -> Duration { let mut secs = self.secs + rhs.secs; @@ -317,21 +302,6 @@ impl Add for Duration { } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl Sub for Duration { - fn sub(&self, rhs: &Duration) -> Duration { - let mut secs = self.secs - rhs.secs; - let mut nanos = self.nanos - rhs.nanos; - if nanos < 0 { - nanos += NANOS_PER_SEC; - secs -= 1; - } - Duration { secs: secs, nanos: nanos } - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl Sub for Duration { fn sub(self, rhs: Duration) -> Duration { let mut secs = self.secs - rhs.secs; @@ -344,19 +314,6 @@ impl Sub for Duration { } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl Mul for Duration { - fn mul(&self, rhs: &i32) -> Duration { - // Multiply nanoseconds as i64, because it cannot overflow that way. - let total_nanos = self.nanos as i64 * *rhs as i64; - let (extra_secs, nanos) = div_mod_floor_64(total_nanos, NANOS_PER_SEC as i64); - let secs = self.secs * *rhs as i64 + extra_secs; - Duration { secs: secs, nanos: nanos as i32 } - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl Mul for Duration { fn mul(self, rhs: i32) -> Duration { // Multiply nanoseconds as i64, because it cannot overflow that way. @@ -367,27 +324,6 @@ impl Mul for Duration { } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl Div for Duration { - fn div(&self, rhs: &i32) -> Duration { - let mut secs = self.secs / *rhs as i64; - let carry = self.secs - secs * *rhs as i64; - let extra_nanos = carry * NANOS_PER_SEC as i64 / *rhs as i64; - let mut nanos = self.nanos / *rhs + extra_nanos as i32; - if nanos >= NANOS_PER_SEC { - nanos -= NANOS_PER_SEC; - secs += 1; - } - if nanos < 0 { - nanos += NANOS_PER_SEC; - secs -= 1; - } - Duration { secs: secs, nanos: nanos } - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl Div for Duration { fn div(self, rhs: i32) -> Duration { let mut secs = self.secs / rhs as i64; diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 17cafc2441f..eae41a21e7d 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -52,30 +52,12 @@ impl Pos for BytePos { fn to_uint(&self) -> uint { let BytePos(n) = *self; n as uint } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl Add for BytePos { - fn add(&self, rhs: &BytePos) -> BytePos { - BytePos((self.to_uint() + rhs.to_uint()) as u32) - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl Add for BytePos { fn add(self, rhs: BytePos) -> BytePos { BytePos((self.to_uint() + rhs.to_uint()) as u32) } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl Sub for BytePos { - fn sub(&self, rhs: &BytePos) -> BytePos { - BytePos((self.to_uint() - rhs.to_uint()) as u32) - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl Sub for BytePos { fn sub(self, rhs: BytePos) -> BytePos { BytePos((self.to_uint() - rhs.to_uint()) as u32) @@ -87,30 +69,12 @@ impl Pos for CharPos { fn to_uint(&self) -> uint { let CharPos(n) = *self; n } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl Add for CharPos { - fn add(&self, rhs: &CharPos) -> CharPos { - CharPos(self.to_uint() + rhs.to_uint()) - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl Add for CharPos { fn add(self, rhs: CharPos) -> CharPos { CharPos(self.to_uint() + rhs.to_uint()) } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl Sub for CharPos { - fn sub(&self, rhs: &CharPos) -> CharPos { - CharPos(self.to_uint() - rhs.to_uint()) - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl Sub for CharPos { fn sub(self, rhs: CharPos) -> CharPos { CharPos(self.to_uint() - rhs.to_uint()) diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index e2439bad178..378dbba07fa 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -106,30 +106,6 @@ enum LockstepIterSize { LisContradiction(String), } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl Add for LockstepIterSize { - fn add(&self, other: &LockstepIterSize) -> LockstepIterSize { - match *self { - LisUnconstrained => other.clone(), - LisContradiction(_) => self.clone(), - LisConstraint(l_len, l_id) => match *other { - LisUnconstrained => self.clone(), - LisContradiction(_) => other.clone(), - LisConstraint(r_len, _) if l_len == r_len => self.clone(), - LisConstraint(r_len, r_id) => { - let l_n = token::get_ident(l_id); - let r_n = token::get_ident(r_id); - LisContradiction(format!("inconsistent lockstep iteration: \ - '{}' has {} items, but '{}' has {}", - l_n, l_len, r_n, r_len).to_string()) - } - }, - } - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl Add for LockstepIterSize { fn add(self, other: LockstepIterSize) -> LockstepIterSize { match self { diff --git a/src/libtime/lib.rs b/src/libtime/lib.rs index 4129086e9ec..bbeddcd263b 100644 --- a/src/libtime/lib.rs +++ b/src/libtime/lib.rs @@ -99,29 +99,6 @@ impl Timespec { } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl Add for Timespec { - fn add(&self, other: &Duration) -> Timespec { - let d_sec = other.num_seconds(); - // It is safe to unwrap the nanoseconds, because there cannot be - // more than one second left, which fits in i64 and in i32. - let d_nsec = (*other - Duration::seconds(d_sec)) - .num_nanoseconds().unwrap() as i32; - let mut sec = self.sec + d_sec; - let mut nsec = self.nsec + d_nsec; - if nsec >= NSEC_PER_SEC { - nsec -= NSEC_PER_SEC; - sec += 1; - } else if nsec < 0 { - nsec += NSEC_PER_SEC; - sec -= 1; - } - Timespec::new(sec, nsec) - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl Add for Timespec { fn add(self, other: Duration) -> Timespec { let d_sec = other.num_seconds(); @@ -142,17 +119,6 @@ impl Add for Timespec { } } -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl Sub for Timespec { - fn sub(&self, other: &Timespec) -> Duration { - let sec = self.sec - other.sec; - let nsec = self.nsec - other.nsec; - Duration::seconds(sec) + Duration::nanoseconds(nsec as i64) - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot impl Sub for Timespec { fn sub(self, other: Timespec) -> Duration { let sec = self.sec - other.sec; diff --git a/src/snapshots.txt b/src/snapshots.txt index 071d9f758eb..b85ff194c7c 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -1,3 +1,12 @@ +S 2014-12-17 22a9f25 + freebsd-x86_64 c6a13ad985e8464fef0fc7cb7e0d221cbb4815a9 + linux-i386 03109a02e2ed6cd2bb982e93814ef555d54b55a6 + linux-x86_64 0cdf84d5f2fa7cd6b9e321150c6cfc7334206163 + macos-i386 384406ebaa2a2065a801733f4cb3f53d96a0a73d + macos-x86_64 b00e10f44b348da454ad602a921213d8170148b3 + winnt-i386 3d6b0f333d142d99f21506dcea5f03d428ddec12 + winnt-x86_64 f8cbf77146d7ddcc5f8388c58c090f31e78de317 + S 2014-12-15 1b97cd3 freebsd-x86_64 a5d7ff81ec04e01e64dc201c7aa2d875ebd0cbbb linux-i386 47e13c2f1d26a0d13e593e0881a80ca103aa7b2e From 1919de87bb5bb58a542a122daa41a61ea6dbf3a0 Mon Sep 17 00:00:00 2001 From: Kevin Yap Date: Sat, 13 Dec 2014 14:36:53 -0800 Subject: [PATCH 35/58] Miscellaneous changes to Rust Guide - Various grammatical changes - Place punctuation outside of key term quotes - Change comment placement in 17.2 code block - Replace double hyphens with en dashes --- src/doc/guide.md | 154 +++++++++++++++++++++++------------------------ 1 file changed, 76 insertions(+), 78 deletions(-) diff --git a/src/doc/guide.md b/src/doc/guide.md index 21043cfef14..6dfc19e7294 100644 --- a/src/doc/guide.md +++ b/src/doc/guide.md @@ -1156,7 +1156,7 @@ enum StringResult { ErrorReason(String), } ``` -Where a `StringResult` is either an `StringOK`, with the result of a computation, or an +Where a `StringResult` is either a `StringOK`, with the result of a computation, or an `ErrorReason` with a `String` explaining what caused the computation to fail. These kinds of `enum`s are actually very useful and are even part of the standard library. @@ -1178,7 +1178,7 @@ fn respond(greeting: &str) -> StringResult { ``` Notice that we need both the enum name and the variant name: `StringResult::StringOK`, but -we didn't need to with `Ordering`, we just said `Greater` rather than `Ordering::Greater`. +we didn't need to with `Ordering` – we just said `Greater` rather than `Ordering::Greater`. There's a reason: the Rust prelude imports the variants of `Ordering` as well as the enum itself. We can use the `use` keyword to do something similar with `StringResult`: @@ -1209,16 +1209,16 @@ now, rather than the full `StringResult::StringOK`. Importing variants can be co also cause name conflicts, so do this with caution. It's considered good style to rarely import variants for this reason. -As you can see `enum`s with values are quite a powerful tool for data representation, -and can be even more useful when they're generic across types. But before we get to -generics, let's talk about how to use them with pattern matching, a tool that will +As you can see, `enum`s with values are quite a powerful tool for data representation, +and can be even more useful when they're generic across types. Before we get to generics, +though, let's talk about how to use them with pattern matching, a tool that will let us deconstruct this sum type (the type theory term for enums) in a very elegant way and avoid all these messy `if`/`else`s. # Match Often, a simple `if`/`else` isn't enough, because you have more than two -possible options. And `else` conditions can get incredibly complicated. So +possible options. Also, `else` conditions can get incredibly complicated, so what's the solution? Rust has a keyword, `match`, that allows you to replace complicated `if`/`else` @@ -1237,13 +1237,13 @@ match x { } ``` -`match` takes an expression, and then branches based on its value. Each 'arm' of +`match` takes an expression and then branches based on its value. Each 'arm' of the branch is of the form `val => expression`. When the value matches, that arm's expression will be evaluated. It's called `match` because of the term 'pattern -matching,' which `match` is an implementation of. +matching', which `match` is an implementation of. So what's the big advantage here? Well, there are a few. First of all, `match` -enforces 'exhaustiveness checking.' Do you see that last arm, the one with the +enforces 'exhaustiveness checking'. Do you see that last arm, the one with the underscore (`_`)? If we remove that arm, Rust will give us an error: ```{notrust} @@ -1251,11 +1251,11 @@ error: non-exhaustive patterns: `_` not covered ``` In other words, Rust is trying to tell us we forgot a value. Because `x` is an -integer, Rust knows that it can have a number of different values. For example, -`6i`. But without the `_`, there is no arm that could match, and so Rust refuses -to compile. `_` is sort of like a catch-all arm. If none of the other arms match, -the arm with `_` will. And since we have this catch-all arm, we now have an arm -for every possible value of `x`, and so our program will now compile. +integer, Rust knows that it can have a number of different values – for example, +`6i`. Without the `_`, however, there is no arm that could match, and so Rust refuses +to compile. `_` acts like a 'catch-all arm'. If none of the other arms match, +the arm with `_` will, and since we have this catch-all arm, we now have an arm +for every possible value of `x`, and so our program will compile successfully. `match` statements also destructure enums, as well. Remember this code from the section on enums? @@ -1336,14 +1336,14 @@ fn main() { ``` That is how you can get and use the values contained in `enum`s. -It can also allow us to treat errors or unexpected computations, for example, a -function that is not guaranteed to be able to compute a result (an `int` here), +It can also allow us to handle errors or unexpected computations; for example, a +function that is not guaranteed to be able to compute a result (an `int` here) could return an `OptionalInt`, and we would handle that value with a `match`. As you can see, `enum` and `match` used together are quite useful! -`match` is also an expression, which means we can use it on the right -hand side of a `let` binding or directly where an expression is -used. We could also implement the previous line like this: +`match` is also an expression, which means we can use it on the right-hand +side of a `let` binding or directly where an expression is used. We could +also implement the previous line like this: ```{rust} fn cmp(a: int, b: int) -> Ordering { @@ -1375,7 +1375,7 @@ two main looping constructs: `for` and `while`. The `for` loop is used to loop a particular number of times. Rust's `for` loops work a bit differently than in other systems languages, however. Rust's `for` -loop doesn't look like this "C style" `for` loop: +loop doesn't look like this "C-style" `for` loop: ```{c} for (x = 0; x < 10; x++) { @@ -1410,7 +1410,7 @@ In our example, `range` is a function that takes a start and an end position, and gives an iterator over those values. The upper bound is exclusive, though, so our loop will print `0` through `9`, not `10`. -Rust does not have the "C style" `for` loop on purpose. Manually controlling +Rust does not have the "C-style" `for` loop on purpose. Manually controlling each element of the loop is complicated and error prone, even for experienced C developers. @@ -1441,7 +1441,7 @@ If you need an infinite loop, you may be tempted to write this: while true { ``` -Rust has a dedicated keyword, `loop`, to handle this case: +However, Rust has a dedicated keyword, `loop`, to handle this case: ```{rust,ignore} loop { @@ -1451,7 +1451,7 @@ Rust's control-flow analysis treats this construct differently than a `while true`, since we know that it will always loop. The details of what that _means_ aren't super important to understand at this stage, but in general, the more information we can give to the compiler, the better it -can do with safety and code generation. So you should always prefer +can do with safety and code generation, so you should always prefer `loop` when you plan to loop infinitely. ## Ending iteration early @@ -1470,7 +1470,7 @@ while !done { ``` We had to keep a dedicated `mut` boolean variable binding, `done`, to know -when we should skip out of the loop. Rust has two keywords to help us with +when we should exit out of the loop. Rust has two keywords to help us with modifying iteration: `break` and `continue`. In this case, we can write the loop in a better way with `break`: @@ -1485,10 +1485,10 @@ loop { } ``` -We now loop forever with `loop`, and use `break` to break out early. +We now loop forever with `loop` and use `break` to break out early. `continue` is similar, but instead of ending the loop, goes to the next -iteration: This will only print the odd numbers: +iteration. This will only print the odd numbers: ```{rust} for x in range(0i, 10i) { @@ -1505,8 +1505,8 @@ Both `continue` and `break` are valid in both kinds of loops. Strings are an important concept for any programmer to master. Rust's string handling system is a bit different from other languages, due to its systems focus. Any time you have a data structure of variable size, things can get -tricky, and strings are a re-sizable data structure. That said, Rust's strings -also work differently than in some other systems languages, such as C. +tricky, and strings are a re-sizable data structure. That being said, Rust's +strings also work differently than in some other systems languages, such as C. Let's dig into the details. A **string** is a sequence of Unicode scalar values encoded as a stream of UTF-8 bytes. All strings are guaranteed to be @@ -1774,22 +1774,22 @@ fn main() { } ``` -We had to match each time, to see if we had a value or not. In this case, -though, we _know_ that `x` has a `Value`. But `match` forces us to handle +We had to match each time to see if we had a value or not. In this case, +though, we _know_ that `x` has a `Value`, but `match` forces us to handle the `missing` case. This is what we want 99% of the time, but sometimes, we know better than the compiler. Likewise, `read_line()` does not return a line of input. It _might_ return a -line of input. It might also fail to do so. This could happen if our program +line of input, though it might also fail to do so. This could happen if our program isn't running in a terminal, but as part of a cron job, or some other context where there's no standard input. Because of this, `read_line` returns a type very similar to our `OptionalInt`: an `IoResult`. We haven't talked about `IoResult` yet because it is the **generic** form of our `OptionalInt`. -Until then, you can think of it as being the same thing, just for any type, not -just `int`s. +Until then, you can think of it as being the same thing, just for any type – +not just `int`s. Rust provides a method on these `IoResult`s called `ok()`, which does the -same thing as our `match` statement, but assuming that we have a valid value. +same thing as our `match` statement but assumes that we have a valid value. We then call `expect()` on the result, which will terminate our program if we don't have a valid value. In this case, if we can't get input, our program doesn't work, so we're okay with that. In most cases, we would want to handle @@ -1831,7 +1831,7 @@ fn main() { } ``` -Sometimes, this makes things more readable. Sometimes, less. Use your judgment +Sometimes, this makes things more readable – sometimes, less. Use your judgement here. That's all you need to get basic input from the standard input! It's not too @@ -1951,10 +1951,8 @@ You can find that page [here](std/index.html). There's a lot of information on that page, but the best part is the search bar. Right up at the top, there's a box that you can enter in a search term. The search is pretty primitive right now, but is getting better all the time. If you type 'random' in that -box, the page will update to [this -one](std/index.html?search=random). The very first -result is a link to -[std::rand::random](std/rand/fn.random.html). If we +box, the page will update to [this one](std/index.html?search=random). The very +first result is a link to [`std::rand::random`](std/rand/fn.random.html). If we click on that result, we'll be taken to its documentation page. This page shows us a few things: the type signature of the function, some @@ -2018,7 +2016,7 @@ rand::random::(); ``` This says "please give me a random `int` value." We can change our code to use -this hint... +this hint: ```{rust,no_run} use std::io; @@ -2359,7 +2357,7 @@ fn cmp(a: uint, b: uint) -> Ordering { } ``` -We use a `match` to either give us the `uint` inside of the `Option`, or we +We use a `match` to either give us the `uint` inside of the `Option`, or else print an error message and return. Let's give this a shot: ```{notrust} @@ -2377,8 +2375,8 @@ Uh, what? But we did! ... actually, we didn't. See, when you get a line of input from `stdin()`, you get all the input. Including the `\n` character from you pressing Enter. -So, `from_str()` sees the string `"5\n"` and says "nope, that's not a number, -there's non-number stuff in there!" Luckily for us, `&str`s have an easy +Therefore, `from_str()` sees the string `"5\n"` and says "nope, that's not a +number; there's non-number stuff in there!" Luckily for us, `&str`s have an easy method we can use defined on them: `trim()`. One small modification, and our code looks like this: @@ -2444,7 +2442,7 @@ out that I guessed 76. Run the program a few times, and verify that guessing the number works, as well as guessing a number too small. The Rust compiler helped us out quite a bit there! This technique is called -"lean on the compiler," and it's often useful when working on some code. Let +"lean on the compiler", and it's often useful when working on some code. Let the error messages help guide you towards the correct types. Now we've got most of the game working, but we can only make one guess. Let's @@ -2452,8 +2450,8 @@ change that by adding loops! ## Looping -As we already discussed, the `loop` keyword gives us an infinite loop. So -let's add that in: +As we already discussed, the `loop` keyword gives us an infinite loop. +Let's add that in: ```{rust,no_run} use std::io; @@ -2759,12 +2757,11 @@ $ cargo run Hello, world! ``` -Excellent! So, we already have a single crate here: our `src/main.rs` is a crate. +Excellent! We already have a single crate here: our `src/main.rs` is a crate. Everything in that file is in the crate root. A crate that generates an executable defines a `main` function inside its root, as we've done here. -Let's define a new module inside our crate. Edit `src/main.rs` to look -like this: +Let's define a new module inside our crate. Edit `src/main.rs` to look like this: ``` fn main() { @@ -2782,7 +2779,7 @@ We now have a module named `hello` inside of our crate root. Modules use `snake_case` naming, like functions and variable bindings. Inside the `hello` module, we've defined a `print_hello` function. This will -also print out our hello world message. Modules allow you to split up your +also print out our "hello world" message. Modules allow you to split up your program into nice neat boxes of functionality, grouping common things together, and keeping different things apart. It's kinda like having a set of shelves: a place for everything and everything in its place. @@ -2942,7 +2939,7 @@ You'll get a warning if you use something marked unstable. You may have noticed an exclamation point in the `warn` attribute declaration. The `!` in this attribute means that this attribute applies to the enclosing -item, rather than to the item that follows the attribute. So this `warn` +item, rather than to the item that follows the attribute. This `warn` attribute declaration applies to the enclosing crate itself, rather than to whatever item statement follows it: @@ -2982,9 +2979,9 @@ Hello, world! Great. Rust's infrastructure supports tests in two sorts of places, and they're for two kinds of tests: you include **unit test**s inside of the crate itself, and you place **integration test**s inside a `tests` directory. "Unit tests" -are small tests that test one focused unit, "integration tests" tests multiple -units in integration. That said, this is a social convention, they're no different -in syntax. Let's make a `tests` directory: +are small tests that test one focused unit; "integration tests" test multiple +units in integration. That being said, this is a social convention – they're no +different in syntax. Let's make a `tests` directory: ```{bash,ignore} $ mkdir tests @@ -3064,7 +3061,7 @@ test foo ... FAILED Now we're getting somewhere. Remember when we talked about naming our tests with good names? This is why. Here, it says 'test foo' because we called our -test 'foo.' If we had given it a good name, it'd be more clear which test +test 'foo'. If we had given it a good name, it'd be more clear which test failed, especially as we accumulate more tests. ```{notrust} @@ -3135,7 +3132,7 @@ our tests, it sets things up so that `cfg(test)` is true. But we want to only include `main` when it's _not_ true. So we use `not` to negate things: `cfg(not(test))` will only compile our code when the `cfg(test)` is false. -With this attribute we won't get the warning (even +With this attribute, we won't get the warning (even though `src/main.rs` gets recompiled this time): ```{ignore} @@ -3179,7 +3176,7 @@ error: aborting due to previous error Build failed, waiting for other jobs to finish... Could not compile `testing`. -To learn more, run the command again with --verbose. +To learn more, run the command again with `--verbose`. ``` Rust can't find this function. That makes sense, as we didn't write it yet! @@ -3187,7 +3184,7 @@ Rust can't find this function. That makes sense, as we didn't write it yet! In order to share this code with our tests, we'll need to make a library crate. This is also just good software design: as we mentioned before, it's a good idea to put most of your functionality into a library crate, and have your executable -crate use that library. This allows for code re-use. +crate use that library. This allows for code reuse. To do that, we'll need to make a new module. Make a new file, `src/lib.rs`, and put this in it: @@ -3261,8 +3258,8 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured Great! One test passed. We've got an integration test showing that our public method works, but maybe we want to test some of the internal logic as well. While this function is simple, if it were more complicated, you can imagine -we'd need more tests. So let's break it up into two helper functions, and -write some unit tests to test those. +we'd need more tests. Let's break it up into two helper functions and write +some unit tests to test those. Change your `src/lib.rs` to look like this: @@ -3511,7 +3508,7 @@ error: cannot borrow immutable local variable `x` as mutable ``` We don't want a mutable reference to immutable data! This error message uses a -term we haven't talked about yet, 'borrow.' We'll get to that in just a moment. +term we haven't talked about yet, 'borrow'. We'll get to that in just a moment. This simple example actually illustrates a lot of Rust's power: Rust has prevented us, at compile time, from breaking our own rules. Because Rust's @@ -3632,9 +3629,10 @@ all of Rust. Let's see this syntax in action: fn foo(x: &int) -> &int { x } { - let x = 5i; // x is the owner of this integer, which is memory on the stack. + // x is the owner of the integer, which is memory on the stack. + let x = 5i; - // privilege 2: you may lend that resource, to as many borrowers as you'd like + // privilege 2: you may lend that resource to as many borrowers as you like let y = &x; let z = &x; @@ -3644,10 +3642,11 @@ fn foo(x: &int) -> &int { x } } { - let mut x = 5i; // x is the owner of this integer, which is memory on the stack. + // x is the owner of this integer, which is memory on the stack. + let mut x = 5i; - let y = &mut x; // privilege 3: you may lend that resource to a single borrower, - // mutably + // privilege 3: you may lend that resource to a single borrower, mutably + let y = &mut x; } ``` @@ -3663,7 +3662,7 @@ This last requirement can seem odd, but it also makes sense. If you have to return something, and you've lent it to someone, they need to give it back to you for you to give it back! If we didn't, then the owner could deallocate the memory, and the person we've loaned it out to would have a pointer to -invalid memory. This is called a 'dangling pointer.' +invalid memory. This is called a 'dangling pointer'. Let's re-examine the error that led us to talk about all of this, which was a violation of the restrictions placed on owners who lend something out mutably. @@ -3786,8 +3785,8 @@ an integer `5` and makes `x` a pointer to it: ``` The great thing about boxes is that we don't have to manually free this -allocation! Instead, when `x` reaches the end of its lifetime -- in this case, -when it goes out of scope at the end of the block -- Rust `free`s `x`. This +allocation! Instead, when `x` reaches the end of its lifetime – in this case, +when it goes out of scope at the end of the block – Rust `free`s `x`. This isn't because Rust has a garbage collector (it doesn't). Instead, by tracking the ownership and lifetime of a variable (with a little help from you, the programmer), the compiler knows precisely when it is no longer used. @@ -3852,12 +3851,12 @@ Sometimes you need a variable that is referenced from multiple places (immutably!), lasting as long as any of those places, and disappearing when it is no longer referenced. For instance, in a graph-like data structure, a node might be referenced from all of its neighbors. In this case, it is not possible -for the compiler to determine ahead of time when the value can be freed -- it +for the compiler to determine ahead of time when the value can be freed – it needs a little run-time support. Rust's **Rc** type provides shared ownership of a dynamically allocated value that is automatically freed at the end of its last owner's lifetime. (`Rc` -stands for 'reference counted,' referring to the way these library types are +stands for 'reference counted', referring to the way these library types are implemented.) This provides more flexibility than single-owner boxes, but has some runtime overhead. @@ -4299,7 +4298,7 @@ This line is more interesting. Here, we call our function, `twice`, and we pass it two arguments: an integer, `5`, and our closure, `square`. This is just like passing any other two variable bindings to a function, but if you've never worked with closures before, it can seem a little complex. Just think: "I'm -passing two variables, one is an int, and one is a function." +passing two variables: one is an int, and one is a function." Next, let's look at how `twice` is defined: @@ -4335,7 +4334,7 @@ fn twice(x: int, f: |int| -> int) -> int { ``` Since our closure is named `f`, we can call it just like we called our closures -before. And we pass in our `x` argument to each one. Hence 'twice.' +before, and we pass in our `x` argument to each one, hence the name `twice`. If you do the math, `(5 * 5) + (5 * 5) == 50`, so that's the output we get. @@ -4806,7 +4805,7 @@ enum Result { ``` if we wanted to. Convention says that the first generic parameter should be -`T`, for 'type,' and that we use `E` for 'error.' Rust doesn't care, however. +`T`, for 'type,' and that we use `E` for 'error'. Rust doesn't care, however. The `Result` type is intended to be used to return the result of a computation, and to have the ability to @@ -5211,7 +5210,7 @@ fn main() { The names don't actually change to this, it's just for illustration. But as you can see, there's no overhead of deciding which version to call here, -hence 'statically dispatched.' The downside is that we have two copies of +hence 'statically dispatched'. The downside is that we have two copies of the same function, so our binary is a little bit larger. # Tasks @@ -5406,7 +5405,7 @@ fn main() { } ``` -You can have the macros expanded like this: `rustc print.rs --pretty=expanded` – which will +You can have the macros expanded like this: `rustc print.rs --pretty=expanded`, which will give us this huge result: ```{rust,ignore} @@ -5492,7 +5491,6 @@ We covered a lot of ground here. When you've mastered everything in this Guide, you will have a firm grasp of basic Rust development. There's a whole lot more out there, we've just covered the surface. There's tons of topics that you can dig deeper into, and we've built specialized guides for many of them. To learn -more, dig into the [full documentation -index](index.html). +more, dig into the [full documentation index](index.html). Happy hacking! From cf350ea5eb562fcfb67775ad4d847e441a8006a4 Mon Sep 17 00:00:00 2001 From: bluss Date: Fri, 19 Dec 2014 21:54:50 +0100 Subject: [PATCH 36/58] hashset: Clean up and rename the HashSet iterators This removes the type SetAlgebraItems and replaces it with the structs Intersection and Difference. Rename the existing HashSet iterators according to RFC #344: * SetItems -> Iter * SetMoveItems -> IntoIter * Remaining set combination iterators renamed to Union and SymmetricDifference [breaking-change] --- src/libstd/collections/hash/set.rs | 133 ++++++++++++++++++----------- 1 file changed, 85 insertions(+), 48 deletions(-) diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 67c0f887832..99fe6696ec7 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -17,7 +17,7 @@ use default::Default; use fmt::Show; use fmt; use hash::{Hash, Hasher, RandomSipHasher}; -use iter::{Iterator, IteratorExt, FromIterator, Map, FilterMap, Chain, Repeat, Zip, Extend, repeat}; +use iter::{Iterator, IteratorExt, FromIterator, Map, Chain, Extend}; use option::Option::{Some, None, mod}; use result::Result::{Ok, Err}; @@ -250,8 +250,8 @@ impl, S, H: Hasher> HashSet { /// } /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn iter<'a>(&'a self) -> SetItems<'a, T> { - SetItems { iter: self.map.keys() } + pub fn iter<'a>(&'a self) -> Iter<'a, T> { + Iter { iter: self.map.keys() } } /// Creates a consuming iterator, that is, one that moves each value out @@ -275,10 +275,10 @@ impl, S, H: Hasher> HashSet { /// } /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn into_iter(self) -> SetMoveItems { + pub fn into_iter(self) -> IntoIter { fn first((a, _): (A, B)) -> A { a } - SetMoveItems { iter: self.map.into_iter().map(first) } + IntoIter { iter: self.map.into_iter().map(first) } } /// Visit the values representing the difference. @@ -304,14 +304,11 @@ impl, S, H: Hasher> HashSet { /// assert_eq!(diff, [4i].iter().map(|&x| x).collect()); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn difference<'a>(&'a self, other: &'a HashSet) -> SetAlgebraItems<'a, T, H> { - fn filter<'a, T, S, H>((other, elt): (&HashSet, &'a T)) -> Option<&'a T> where - T: Eq + Hash, H: Hasher - { - if !other.contains(elt) { Some(elt) } else { None } + pub fn difference<'a>(&'a self, other: &'a HashSet) -> Difference<'a, T, H> { + Difference { + iter: self.iter(), + other: other, } - - SetAlgebraItems { iter: repeat(other).zip(self.iter()).filter_map(filter) } } /// Visit the values representing the symmetric difference. @@ -336,8 +333,8 @@ impl, S, H: Hasher> HashSet { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet) - -> SymDifferenceItems<'a, T, H> { - SymDifferenceItems { iter: self.difference(other).chain(other.difference(self)) } + -> SymmetricDifference<'a, T, H> { + SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) } } /// Visit the values representing the intersection. @@ -358,14 +355,11 @@ impl, S, H: Hasher> HashSet { /// assert_eq!(diff, [2i, 3].iter().map(|&x| x).collect()); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn intersection<'a>(&'a self, other: &'a HashSet) -> SetAlgebraItems<'a, T, H> { - fn filter<'a, T, S, H>((other, elt): (&HashSet, &'a T)) -> Option<&'a T> where - T: Eq + Hash, H: Hasher - { - if other.contains(elt) { Some(elt) } else { None } + pub fn intersection<'a>(&'a self, other: &'a HashSet) -> Intersection<'a, T, H> { + Intersection { + iter: self.iter(), + other: other, } - - SetAlgebraItems { iter: repeat(other).zip(self.iter()).filter_map(filter) } } /// Visit the values representing the union. @@ -386,8 +380,8 @@ impl, S, H: Hasher> HashSet { /// assert_eq!(diff, [1i, 2, 3, 4].iter().map(|&x| x).collect()); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn union<'a>(&'a self, other: &'a HashSet) -> UnionItems<'a, T, H> { - UnionItems { iter: self.iter().chain(other.difference(self)) } + pub fn union<'a>(&'a self, other: &'a HashSet) -> Union<'a, T, H> { + Union { iter: self.iter().chain(other.difference(self)) } } /// Return the number of elements in the set @@ -617,58 +611,101 @@ impl, S, H: Hasher + Default> Default for HashSet { } /// HashSet iterator -pub struct SetItems<'a, K: 'a> { +pub struct Iter<'a, K: 'a> { iter: Keys<'a, K, ()> } /// HashSet move iterator -pub struct SetMoveItems { +pub struct IntoIter { iter: Map<(K, ()), K, MoveEntries, fn((K, ())) -> K> } -// `Repeat` is used to feed the filter closure an explicit capture -// of a reference to the other set -/// Set operations iterator, used directly for intersection and difference -pub struct SetAlgebraItems<'a, T: 'a, H: 'a> { - iter: FilterMap< - (&'a HashSet, &'a T), - &'a T, - Zip>, SetItems<'a, T>>, - for<'b> fn((&HashSet, &'b T)) -> Option<&'b T>, - > +/// Intersection iterator +pub struct Intersection<'a, T: 'a, H: 'a> { + // iterator of the first set + iter: Iter<'a, T>, + // the second set + other: &'a HashSet, +} + +/// Difference iterator +pub struct Difference<'a, T: 'a, H: 'a> { + // iterator of the first set + iter: Iter<'a, T>, + // the second set + other: &'a HashSet, } /// Symmetric difference iterator. -pub struct SymDifferenceItems<'a, T: 'a, H: 'a> { - iter: Chain, SetAlgebraItems<'a, T, H>> +pub struct SymmetricDifference<'a, T: 'a, H: 'a> { + iter: Chain, Difference<'a, T, H>> } /// Set union iterator. -pub struct UnionItems<'a, T: 'a, H: 'a> { - iter: Chain, SetAlgebraItems<'a, T, H>> +pub struct Union<'a, T: 'a, H: 'a> { + iter: Chain, Difference<'a, T, H>> } -impl<'a, K> Iterator<&'a K> for SetItems<'a, K> { +impl<'a, K> Iterator<&'a K> for Iter<'a, K> { fn next(&mut self) -> Option<&'a K> { self.iter.next() } fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } } -impl Iterator for SetMoveItems { +impl Iterator for IntoIter { fn next(&mut self) -> Option { self.iter.next() } fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } } -impl<'a, T, H> Iterator<&'a T> for SetAlgebraItems<'a, T, H> { +impl<'a, T, S, H> Iterator<&'a T> for Intersection<'a, T, H> + where T: Eq + Hash, H: Hasher +{ + fn next(&mut self) -> Option<&'a T> { + loop { + match self.iter.next() { + None => return None, + Some(elt) => if self.other.contains(elt) { + return Some(elt) + }, + } + } + } + + fn size_hint(&self) -> (uint, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } +} + +impl<'a, T, S, H> Iterator<&'a T> for Difference<'a, T, H> + where T: Eq + Hash, H: Hasher +{ + fn next(&mut self) -> Option<&'a T> { + loop { + match self.iter.next() { + None => return None, + Some(elt) => if !self.other.contains(elt) { + return Some(elt) + }, + } + } + } + + fn size_hint(&self) -> (uint, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } +} + +impl<'a, T, S, H> Iterator<&'a T> for SymmetricDifference<'a, T, H> + where T: Eq + Hash, H: Hasher +{ fn next(&mut self) -> Option<&'a T> { self.iter.next() } fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } } -impl<'a, T, H> Iterator<&'a T> for SymDifferenceItems<'a, T, H> { - fn next(&mut self) -> Option<&'a T> { self.iter.next() } - fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } -} - -impl<'a, T, H> Iterator<&'a T> for UnionItems<'a, T, H> { +impl<'a, T, S, H> Iterator<&'a T> for Union<'a, T, H> + where T: Eq + Hash, H: Hasher +{ fn next(&mut self) -> Option<&'a T> { self.iter.next() } fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } } From d61db0c6964b436b3fe1a65295e0101cce45debf Mon Sep 17 00:00:00 2001 From: Chase Southwood Date: Fri, 19 Dec 2014 14:30:51 -0600 Subject: [PATCH 37/58] Implement resize for Vec This commit adds `resize` to `Vec` in accordance with RFC 509. --- src/libcollections/vec.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 94e6103f05f..7452022dd5a 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -412,6 +412,33 @@ impl Vec { } } + /// Resizes the `Vec` in-place so that `len()` is equal to `new_len`. + /// + /// Calls either `extend()` or `truncate()` depending on whether `new_len` + /// is larger than the current value of `len()` or not. + /// + /// # Examples + /// + /// ``` + /// let mut vec = vec!["hello"]; + /// vec.resize(3, "world"); + /// assert_eq!(vec, vec!["hello", "world", "world"]); + /// + /// let mut vec = vec![1i, 2, 3, 4]; + /// vec.resize(2, 0); + /// assert_eq!(vec, vec![1, 2]); + /// ``` + #[unstable = "matches collection reform specification; waiting for dust to settle"] + pub fn resize(&mut self, new_len: uint, value: T) { + let len = self.len(); + + if new_len > len { + self.extend(repeat(value).take(new_len - len)); + } else { + self.truncate(new_len); + } + } + /// Partitions a vector based on a predicate. /// /// Clones the elements of the vector, partitioning them into two `Vec`s From 39f249067a2b0773d887bb311573dc258118d34d Mon Sep 17 00:00:00 2001 From: Barosl Lee Date: Sat, 20 Dec 2014 07:44:21 +0900 Subject: [PATCH 38/58] Implement Deref for Box Fixes #18624. --- src/liballoc/boxed.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 879a8cc6951..ea7b32ace49 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -22,6 +22,7 @@ use core::option::Option; use core::raw::TraitObject; use core::result::Result; use core::result::Result::{Ok, Err}; +use core::ops::{Deref, DerefMut}; /// A value that represents the global exchange heap. This is the default /// place that the `box` keyword allocates into when no place is supplied. @@ -147,6 +148,14 @@ impl fmt::Show for Box { } } +impl Deref for Box { + fn deref(&self) -> &T { &**self } +} + +impl DerefMut for Box { + fn deref_mut(&mut self) -> &mut T { &mut **self } +} + #[cfg(test)] mod test { #[test] @@ -193,4 +202,10 @@ mod test { let s = format!("{}", b); assert_eq!(s, "&Any"); } + + #[test] + fn deref() { + fn homura>(_: T) { } + homura(box 765i32); + } } From 7023bea22c969a324d7d95d8794370410ff7c4c9 Mon Sep 17 00:00:00 2001 From: Barosl Lee Date: Sat, 20 Dec 2014 01:42:21 +0900 Subject: [PATCH 39/58] Print a friendly error for the if-let construct without an else block Fixes #19991. --- src/librustc_typeck/check/_match.rs | 25 ++++++++++++++++++++----- src/librustc_typeck/check/mod.rs | 4 ++-- src/libsyntax/ast.rs | 2 +- src/libsyntax/ext/expand.rs | 4 +++- src/test/compile-fail/issue-19991.rs | 18 ++++++++++++++++++ 5 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 src/test/compile-fail/issue-19991.rs diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 44cc5fce53d..d4b89621ace 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -238,7 +238,8 @@ pub fn check_match<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &ast::Expr, discrim: &ast::Expr, arms: &[ast::Arm], - expected: Expectation<'tcx>) { + expected: Expectation<'tcx>, + match_src: ast::MatchSource) { let tcx = fcx.ccx.tcx; let discrim_ty = fcx.infcx().next_ty_var(); @@ -290,12 +291,26 @@ pub fn check_match<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, if ty::type_is_error(result_ty) || ty::type_is_error(bty) { ty::mk_err() } else { + let (origin, expected, found) = match match_src { + /* if-let construct without an else block */ + ast::MatchIfLetDesugar(contains_else_arm) if !contains_else_arm => ( + infer::IfExpressionWithNoElse(expr.span), + bty, + result_ty, + ), + _ => ( + infer::MatchExpressionArm(expr.span, arm.body.span), + result_ty, + bty, + ), + }; + infer::common_supertype( fcx.infcx(), - infer::MatchExpressionArm(expr.span, arm.body.span), - true, // result_ty is "expected" here - result_ty, - bty + origin, + true, + expected, + found, ) } }); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index bbc33826f35..f8a8ef35f75 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3918,8 +3918,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, fcx.write_nil(id); } } - ast::ExprMatch(ref discrim, ref arms, _) => { - _match::check_match(fcx, expr, &**discrim, arms.as_slice(), expected); + ast::ExprMatch(ref discrim, ref arms, match_src) => { + _match::check_match(fcx, expr, &**discrim, arms.as_slice(), expected, match_src); } ast::ExprClosure(_, opt_kind, ref decl, ref body) => { closure::check_expr_closure(fcx, expr, opt_kind, &**decl, &**body, expected); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index be8f32bc4d5..ab338da63bf 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -754,7 +754,7 @@ pub struct QPath { #[deriving(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum MatchSource { MatchNormal, - MatchIfLetDesugar, + MatchIfLetDesugar(bool /* contains_else_arm */), MatchWhileLetDesugar, } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 20c8ff20b71..63bd38de8a0 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -170,7 +170,9 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { arms.extend(else_if_arms.into_iter()); arms.push(else_arm); - let match_expr = fld.cx.expr(span, ast::ExprMatch(expr, arms, ast::MatchIfLetDesugar)); + let match_expr = fld.cx.expr(span, ast::ExprMatch(expr, + arms, + ast::MatchIfLetDesugar(elseopt.is_some()))); fld.fold_expr(match_expr) } diff --git a/src/test/compile-fail/issue-19991.rs b/src/test/compile-fail/issue-19991.rs new file mode 100644 index 00000000000..0f1dbfa3492 --- /dev/null +++ b/src/test/compile-fail/issue-19991.rs @@ -0,0 +1,18 @@ +// 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 if the sugared if-let construct correctly prints "missing an else clause" when an else +// clause does not exist, instead of the unsympathetic "match arms have incompatible types" + +fn main() { + if let Some(homura) = Some("madoka") { //~ ERROR missing an else clause: expected `()` + 765i32 + }; +} From 314ed2df096858e7c174254b0babd5f949ae6d27 Mon Sep 17 00:00:00 2001 From: Barosl Lee Date: Sat, 20 Dec 2014 07:58:02 +0900 Subject: [PATCH 40/58] Drop the Match prefix from the MatchSource variants --- src/librustc/lint/builtin.rs | 6 +++--- src/librustc/middle/check_match.rs | 6 +++--- src/librustc/util/ppaux.rs | 5 +++-- src/librustc_typeck/check/_match.rs | 3 ++- src/libsyntax/ast.rs | 7 +++---- src/libsyntax/ext/build.rs | 2 +- src/libsyntax/ext/expand.rs | 12 ++++++++---- src/libsyntax/parse/parser.rs | 4 ++-- 8 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 88b12aa5660..f5c7ac16478 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -1157,9 +1157,9 @@ impl LintPass for UnusedParens { ast::ExprIf(ref cond, _, _) => (cond, "`if` condition", true), ast::ExprWhile(ref cond, _, _) => (cond, "`while` condition", true), ast::ExprMatch(ref head, _, source) => match source { - ast::MatchNormal => (head, "`match` head expression", true), - ast::MatchIfLetDesugar => (head, "`if let` head expression", true), - ast::MatchWhileLetDesugar => (head, "`while let` head expression", true), + ast::MatchSource::Normal => (head, "`match` head expression", true), + ast::MatchSource::IfLetDesugar { .. } => (head, "`if let` head expression", true), + ast::MatchSource::WhileLetDesugar => (head, "`while let` head expression", true), }, ast::ExprRet(Some(ref value)) => (value, "`return` value", false), ast::ExprAssign(_, ref value) => (value, "assigned value", false), diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 79e776c3308..ca338f5d02a 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -307,7 +307,7 @@ fn check_arms(cx: &MatchCheckCtxt, match is_useful(cx, &seen, v.as_slice(), LeaveOutWitness) { NotUseful => { match source { - ast::MatchIfLetDesugar => { + ast::MatchSource::IfLetDesugar { .. } => { if printed_if_let_err { // we already printed an irrefutable if-let pattern error. // We don't want two, that's just confusing. @@ -321,7 +321,7 @@ fn check_arms(cx: &MatchCheckCtxt, } }, - ast::MatchWhileLetDesugar => { + ast::MatchSource::WhileLetDesugar => { // find the first arm pattern so we can use its span let &(ref first_arm_pats, _) = &arms[0]; let first_pat = &first_arm_pats[0]; @@ -329,7 +329,7 @@ fn check_arms(cx: &MatchCheckCtxt, span_err!(cx.tcx.sess, span, E0165, "irrefutable while-let pattern"); }, - ast::MatchNormal => { + ast::MatchSource::Normal => { span_err!(cx.tcx.sess, pat.span, E0001, "unreachable pattern") }, } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index b0124977c9f..71146918d99 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -93,8 +93,9 @@ pub fn explain_region_and_span(cx: &ctxt, region: ty::Region) ast::ExprMethodCall(..) => { explain_span(cx, "method call", expr.span) }, - ast::ExprMatch(_, _, ast::MatchIfLetDesugar) => explain_span(cx, "if let", expr.span), - ast::ExprMatch(_, _, ast::MatchWhileLetDesugar) => { + ast::ExprMatch(_, _, ast::MatchSource::IfLetDesugar { .. }) => + explain_span(cx, "if let", expr.span), + ast::ExprMatch(_, _, ast::MatchSource::WhileLetDesugar) => { explain_span(cx, "while let", expr.span) }, ast::ExprMatch(..) => explain_span(cx, "match", expr.span), diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index d4b89621ace..3b48808b362 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -293,7 +293,8 @@ pub fn check_match<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, } else { let (origin, expected, found) = match match_src { /* if-let construct without an else block */ - ast::MatchIfLetDesugar(contains_else_arm) if !contains_else_arm => ( + ast::MatchSource::IfLetDesugar { contains_else_clause } + if !contains_else_clause => ( infer::IfExpressionWithNoElse(expr.span), bty, result_ty, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index ab338da63bf..cb0254a7ec5 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -32,7 +32,6 @@ pub use self::LitIntType::*; pub use self::LocalSource::*; pub use self::Mac_::*; pub use self::MacStmtStyle::*; -pub use self::MatchSource::*; pub use self::MetaItem_::*; pub use self::Method_::*; pub use self::Mutability::*; @@ -753,9 +752,9 @@ pub struct QPath { #[deriving(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum MatchSource { - MatchNormal, - MatchIfLetDesugar(bool /* contains_else_arm */), - MatchWhileLetDesugar, + Normal, + IfLetDesugar { contains_else_clause: bool }, + WhileLetDesugar, } #[deriving(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Show)] diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index d35091f8ab0..9d4992f7453 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -868,7 +868,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } fn expr_match(&self, span: Span, arg: P, arms: Vec) -> P { - self.expr(span, ast::ExprMatch(arg, arms, ast::MatchNormal)) + self.expr(span, ast::ExprMatch(arg, arms, ast::MatchSource::Normal)) } fn expr_if(&self, span: Span, cond: P, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 63bd38de8a0..bf19eecbf65 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -97,7 +97,7 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { // `match { ... }` let arms = vec![pat_arm, break_arm]; let match_expr = fld.cx.expr(span, - ast::ExprMatch(expr, arms, ast::MatchWhileLetDesugar)); + ast::ExprMatch(expr, arms, ast::MatchSource::WhileLetDesugar)); // `[opt_ident]: loop { ... }` let loop_block = fld.cx.block_expr(match_expr); @@ -158,6 +158,8 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { arms }; + let contains_else_clause = elseopt.is_some(); + // `_ => [ | ()]` let else_arm = { let pat_under = fld.cx.pat_wild(span); @@ -170,9 +172,11 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { arms.extend(else_if_arms.into_iter()); arms.push(else_arm); - let match_expr = fld.cx.expr(span, ast::ExprMatch(expr, - arms, - ast::MatchIfLetDesugar(elseopt.is_some()))); + let match_expr = fld.cx.expr(span, + ast::ExprMatch(expr, arms, + ast::MatchSource::IfLetDesugar { + contains_else_clause: contains_else_clause, + })); fld.fold_expr(match_expr) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 3ad224b93ce..b6efbecc78a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -41,7 +41,7 @@ use ast::{LifetimeDef, Lit, Lit_}; use ast::{LitBool, LitChar, LitByte, LitBinary}; use ast::{LitStr, LitInt, Local, LocalLet}; use ast::{MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces}; -use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, MatchNormal}; +use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, MatchSource}; use ast::{Method, MutTy, BiMul, Mutability}; use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, NodeId, UnNot}; use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct}; @@ -3114,7 +3114,7 @@ impl<'a> Parser<'a> { } let hi = self.span.hi; self.bump(); - return self.mk_expr(lo, hi, ExprMatch(discriminant, arms, MatchNormal)); + return self.mk_expr(lo, hi, ExprMatch(discriminant, arms, MatchSource::Normal)); } pub fn parse_arm(&mut self) -> Arm { From 2e86929a4a5a36f3993e577b4582ba70d84bbb40 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Sat, 20 Dec 2014 15:20:51 +1300 Subject: [PATCH 41/58] Allow use of `[_ ; n]` syntax for fixed length and repeating arrays. This does NOT break any existing programs because the `[_, ..n]` syntax is also supported. --- src/librustc/util/ppaux.rs | 2 +- src/librustc_trans/trans/debuginfo.rs | 4 +-- src/libsyntax/parse/parser.rs | 11 +++++- src/libsyntax/print/pprust.rs | 5 ++- src/test/auxiliary/nested_item.rs | 2 +- src/test/bench/noise.rs | 12 +++---- src/test/bench/shootout-fannkuch-redux.rs | 14 ++++---- src/test/bench/shootout-fasta-redux.rs | 12 +++---- src/test/bench/shootout-fasta.rs | 2 +- src/test/bench/shootout-k-nucleotide.rs | 4 +-- src/test/bench/shootout-nbody.rs | 8 ++--- src/test/bench/shootout-reverse-complement.rs | 8 ++--- src/test/bench/sudoku.rs | 6 ++-- src/test/compile-fail/better-expected.rs | 2 +- ...rrowck-for-loop-correct-cmt-for-pattern.rs | 2 +- src/test/compile-fail/coercion-slice.rs | 4 +-- .../compile-fail/const-cast-wrong-type.rs | 2 +- src/test/compile-fail/dst-bad-coerce1.rs | 4 +-- src/test/compile-fail/dst-bad-coerce2.rs | 2 +- src/test/compile-fail/dst-bad-coerce3.rs | 2 +- src/test/compile-fail/dst-bad-coerce4.rs | 4 +-- src/test/compile-fail/dst-bad-deep.rs | 2 +- src/test/compile-fail/huge-array-simple.rs | 2 +- src/test/compile-fail/huge-array.rs | 8 ++--- src/test/compile-fail/huge-enum.rs | 4 +-- src/test/compile-fail/issue-13446.rs | 2 +- src/test/compile-fail/issue-13482-2.rs | 2 +- src/test/compile-fail/issue-13482.rs | 2 +- src/test/compile-fail/issue-14845.rs | 6 ++-- src/test/compile-fail/issue-17252.rs | 4 +-- src/test/compile-fail/issue-17441.rs | 4 +-- .../issue-17718-borrow-interior.rs | 2 +- src/test/compile-fail/issue-19244-1.rs | 2 +- src/test/compile-fail/issue-19244-2.rs | 2 +- src/test/compile-fail/issue-2149.rs | 2 +- src/test/compile-fail/issue-4517.rs | 4 +-- .../compile-fail/lint-uppercase-variables.rs | 2 +- src/test/compile-fail/move-fragments-9.rs | 16 ++++----- .../compile-fail/moves-based-on-type-exprs.rs | 2 +- .../non-constant-enum-for-vec-repeat.rs | 2 +- .../non-constant-expr-for-fixed-len-vec.rs | 2 +- .../non-constant-expr-for-vec-repeat.rs | 2 +- .../non-exhaustive-pattern-witness.rs | 2 +- .../packed-struct-generic-transmute.rs | 2 +- .../compile-fail/removed-syntax-fixed-vec.rs | 2 +- .../removed-syntax-mut-vec-expr.rs | 2 +- .../compile-fail/removed-syntax-mut-vec-ty.rs | 2 +- .../compile-fail/repeat-to-run-dtor-twice.rs | 2 +- src/test/compile-fail/repeat_count.rs | 14 ++++---- .../static-vec-repeat-not-constant.rs | 2 +- .../trailing-comma-array-repeat.rs | 13 ------- .../compile-fail/transmute-type-parameters.rs | 2 +- .../compile-fail/vector-cast-weirdness.rs | 10 +++--- src/test/debuginfo/evec-in-struct.rs | 18 +++++----- .../lexical-scopes-in-block-expression.rs | 4 +-- src/test/debuginfo/recursive-struct.rs | 2 +- src/test/debuginfo/type-names.rs | 4 +-- src/test/debuginfo/vec.rs | 2 +- src/test/pretty/blank-lines.rs | 2 +- src/test/pretty/issue-4264.pp | 35 +++++++++---------- src/test/run-make/no-stack-check/attr.rs | 2 +- src/test/run-make/no-stack-check/flag.rs | 2 +- src/test/run-make/target-specs/foo.rs | 2 +- src/test/run-pass/cast-in-array-size.rs | 8 ++--- src/test/run-pass/check-static-slice.rs | 6 ++-- src/test/run-pass/const-autoderef.rs | 4 +-- src/test/run-pass/const-enum-vec-index.rs | 2 +- src/test/run-pass/const-enum-vector.rs | 2 +- .../const-expr-in-fixed-length-vec.rs | 2 +- src/test/run-pass/const-expr-in-vec-repeat.rs | 2 +- .../run-pass/const-fields-and-indexing.rs | 2 +- .../run-pass/const-region-ptrs-noncopy.rs | 2 +- src/test/run-pass/const-str-ptr.rs | 4 +-- src/test/run-pass/const-vecs-and-slices.rs | 4 +-- src/test/run-pass/dst-struct.rs | 2 +- src/test/run-pass/enum-vec-initializer.rs | 8 ++--- src/test/run-pass/evec-internal.rs | 10 +++--- src/test/run-pass/huge-largest-array.rs | 4 +-- src/test/run-pass/issue-11205.rs | 24 ++++++------- .../run-pass/issue-13259-windows-tcb-trash.rs | 2 +- src/test/run-pass/issue-13763.rs | 4 +-- src/test/run-pass/issue-13837.rs | 2 +- src/test/run-pass/issue-14940.rs | 2 +- src/test/run-pass/issue-15673.rs | 2 +- src/test/run-pass/issue-17302.rs | 2 +- src/test/run-pass/issue-17877.rs | 4 +-- src/test/run-pass/issue-18425.rs | 2 +- src/test/run-pass/issue-19244.rs | 4 +-- src/test/run-pass/issue-2904.rs | 2 +- src/test/run-pass/issue-3656.rs | 2 +- src/test/run-pass/issue-4387.rs | 2 +- src/test/run-pass/issue-5688.rs | 2 +- src/test/run-pass/issue-7784.rs | 4 +-- src/test/run-pass/issue-9942.rs | 2 +- ...vocation-in-count-expr-fixed-array-type.rs | 2 +- src/test/run-pass/match-arm-statics.rs | 2 +- ...thod-mut-self-modifies-mut-slice-lvalue.rs | 2 +- ...o-traits-distinguished-via-where-clause.rs | 2 +- ...ility-inherits-through-fixed-length-vec.rs | 4 +-- .../run-pass/new-style-fixed-length-vec.rs | 2 +- .../nullable-pointer-iotareduction.rs | 4 +-- src/test/run-pass/nullable-pointer-size.rs | 2 +- src/test/run-pass/order-drop-with-match.rs | 2 +- .../out-of-stack-new-thread-no-split.rs | 2 +- src/test/run-pass/out-of-stack-no-split.rs | 2 +- src/test/run-pass/out-of-stack.rs | 2 +- .../run-pass/packed-struct-generic-layout.rs | 4 +-- src/test/run-pass/packed-struct-layout.rs | 6 ++-- src/test/run-pass/packed-struct-size.rs | 2 +- src/test/run-pass/packed-struct-vec.rs | 4 +-- .../run-pass/packed-tuple-struct-layout.rs | 6 ++-- src/test/run-pass/packed-tuple-struct-size.rs | 2 +- .../run-pass/regions-dependent-addr-of.rs | 2 +- src/test/run-pass/repeat-expr-in-static.rs | 4 +-- src/test/run-pass/repeated-vector-syntax.rs | 4 +-- src/test/run-pass/uninit-empty-types.rs | 2 +- src/test/run-pass/unsized3.rs | 4 +-- src/test/run-pass/variadic-ffi.rs | 2 +- src/test/run-pass/vec-dst.rs | 10 +++--- src/test/run-pass/vec-fixed-length.rs | 6 ++-- src/test/run-pass/vec-repeat-with-cast.rs | 2 +- src/test/run-pass/vector-sort-panic-safe.rs | 2 +- 122 files changed, 260 insertions(+), 266 deletions(-) delete mode 100644 src/test/compile-fail/trailing-comma-array-repeat.rs diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index b0124977c9f..b65473bb767 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -452,7 +452,7 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String { ty_vec(t, sz) => { let inner_str = ty_to_string(cx, t); match sz { - Some(n) => format!("[{}, ..{}]", inner_str, n), + Some(n) => format!("[{}; {}]", inner_str, n), None => format!("[{}]", inner_str), } } diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 9a5e6830da1..cdb36602f15 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -334,7 +334,7 @@ impl<'tcx> TypeMap<'tcx> { // mut ptr (*mut) -> {*mut :pointee-uid:} // unique ptr (~) -> {~ :pointee-uid:} // @-ptr (@) -> {@ :pointee-uid:} - // sized vec ([T, ..x]) -> {[:size:] :element-uid:} + // sized vec ([T; x]) -> {[:size:] :element-uid:} // unsized vec ([T]) -> {[] :element-uid:} // trait (T) -> {trait_:svh: / :node-id:_<(:param-uid:),*> } // closure -> { :store-sigil: |(:param-uid:),* <,_...>| -> \ @@ -3752,7 +3752,7 @@ fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, match optional_length { Some(len) => { - output.push_str(format!(", ..{}", len).as_slice()); + output.push_str(format!("; {}", len).as_slice()); } None => { /* nothing to do */ } }; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 3ad224b93ce..620dfd643d2 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1548,7 +1548,7 @@ impl<'a> Parser<'a> { self.expect(&token::OpenDelim(token::Bracket)); let t = self.parse_ty_sum(); - // Parse the `, ..e` in `[ int, ..e ]` + // Parse the `; e` in `[ int; e ]` // where `e` is a const expression let t = match self.maybe_parse_fixed_vstore() { None => TyVec(t), @@ -1716,6 +1716,9 @@ impl<'a> Parser<'a> { self.bump(); self.bump(); Some(self.parse_expr()) + } else if self.check(&token::Semi) { + self.bump(); + Some(self.parse_expr()) } else { None } @@ -2262,6 +2265,12 @@ impl<'a> Parser<'a> { let count = self.parse_expr(); self.expect(&token::CloseDelim(token::Bracket)); ex = ExprRepeat(first_expr, count); + } else if self.check(&token::Semi) { + // Repeating vector syntax: [ 0; 512 ] + self.bump(); + let count = self.parse_expr(); + self.expect(&token::CloseDelim(token::Bracket)); + ex = ExprRepeat(first_expr, count); } else if self.check(&token::Comma) { // Vector with two or more elements. self.bump(); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index d2cc0cba317..993fbed10a8 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -755,7 +755,7 @@ impl<'a> State<'a> { ast::TyFixedLengthVec(ref ty, ref v) => { try!(word(&mut self.s, "[")); try!(self.print_type(&**ty)); - try!(word(&mut self.s, ", ..")); + try!(word(&mut self.s, "; ")); try!(self.print_expr(&**v)); try!(word(&mut self.s, "]")); } @@ -1531,8 +1531,7 @@ impl<'a> State<'a> { try!(self.ibox(indent_unit)); try!(word(&mut self.s, "[")); try!(self.print_expr(&**element)); - try!(word(&mut self.s, ",")); - try!(word(&mut self.s, "..")); + try!(self.word_space(";")); try!(self.print_expr(&**count)); try!(word(&mut self.s, "]")); try!(self.end()); diff --git a/src/test/auxiliary/nested_item.rs b/src/test/auxiliary/nested_item.rs index 96bae656390..d97a2e3cda1 100644 --- a/src/test/auxiliary/nested_item.rs +++ b/src/test/auxiliary/nested_item.rs @@ -28,7 +28,7 @@ impl Foo { pub struct Parser; impl> Parser { fn in_doctype(&mut self) { - static DOCTYPEPattern: [char, ..6] = ['O', 'C', 'T', 'Y', 'P', 'E']; + static DOCTYPEPattern: [char; 6] = ['O', 'C', 'T', 'Y', 'P', 'E']; } } diff --git a/src/test/bench/noise.rs b/src/test/bench/noise.rs index 025f8467d20..75cf864ce49 100644 --- a/src/test/bench/noise.rs +++ b/src/test/bench/noise.rs @@ -37,20 +37,20 @@ fn gradient(orig: Vec2, grad: Vec2, p: Vec2) -> f32 { } struct Noise2DContext { - rgradients: [Vec2, ..256], - permutations: [i32, ..256], + rgradients: [Vec2; 256], + permutations: [i32; 256], } impl Noise2DContext { fn new() -> Noise2DContext { let mut rng = StdRng::new().unwrap(); - let mut rgradients = [Vec2 { x: 0.0, y: 0.0 }, ..256]; + let mut rgradients = [Vec2 { x: 0.0, y: 0.0 }; 256]; for x in rgradients.iter_mut() { *x = random_gradient(&mut rng); } - let mut permutations = [0i32, ..256]; + let mut permutations = [0i32; 256]; for (i, x) in permutations.iter_mut().enumerate() { *x = i as i32; } @@ -65,7 +65,7 @@ impl Noise2DContext { self.rgradients[(idx & 255) as uint] } - fn get_gradients(&self, x: f32, y: f32) -> ([Vec2, ..4], [Vec2, ..4]) { + fn get_gradients(&self, x: f32, y: f32) -> ([Vec2; 4], [Vec2; 4]) { let x0f = x.floor(); let y0f = y.floor(); let x1f = x0f + 1.0; @@ -102,7 +102,7 @@ impl Noise2DContext { fn main() { let symbols = [' ', '░', '▒', '▓', '█', '█']; - let mut pixels = [0f32, ..256*256]; + let mut pixels = [0f32; 256*256]; let n2d = Noise2DContext::new(); for _ in range(0u, 100) { diff --git a/src/test/bench/shootout-fannkuch-redux.rs b/src/test/bench/shootout-fannkuch-redux.rs index 4849421a3f0..723b2b722d7 100644 --- a/src/test/bench/shootout-fannkuch-redux.rs +++ b/src/test/bench/shootout-fannkuch-redux.rs @@ -64,14 +64,14 @@ fn next_permutation(perm: &mut [i32], count: &mut [i32]) { } struct P { - p: [i32, .. 16], + p: [i32; 16], } impl Copy for P {} struct Perm { - cnt: [i32, .. 16], - fact: [u32, .. 16], + cnt: [i32; 16], + fact: [u32; 16], n: u32, permcount: u32, perm: P, @@ -81,21 +81,21 @@ impl Copy for Perm {} impl Perm { fn new(n: u32) -> Perm { - let mut fact = [1, .. 16]; + let mut fact = [1; 16]; for i in range(1, n as uint + 1) { fact[i] = fact[i - 1] * i as u32; } Perm { - cnt: [0, .. 16], + cnt: [0; 16], fact: fact, n: n, permcount: 0, - perm: P { p: [0, .. 16 ] } + perm: P { p: [0; 16 ] } } } fn get(&mut self, mut idx: i32) -> P { - let mut pp = [0u8, .. 16]; + let mut pp = [0u8; 16]; self.permcount = idx as u32; for (i, place) in self.perm.p.iter_mut().enumerate() { *place = i as i32 + 1; diff --git a/src/test/bench/shootout-fasta-redux.rs b/src/test/bench/shootout-fasta-redux.rs index afffbe5bed4..eb18cfdaed3 100644 --- a/src/test/bench/shootout-fasta-redux.rs +++ b/src/test/bench/shootout-fasta-redux.rs @@ -64,7 +64,7 @@ const ALU: &'static str = "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG\ const NULL_AMINO_ACID: AminoAcid = AminoAcid { c: ' ' as u8, p: 0.0 }; -static IUB: [AminoAcid, ..15] = [ +static IUB: [AminoAcid;15] = [ AminoAcid { c: 'a' as u8, p: 0.27 }, AminoAcid { c: 'c' as u8, p: 0.12 }, AminoAcid { c: 'g' as u8, p: 0.12 }, @@ -82,7 +82,7 @@ static IUB: [AminoAcid, ..15] = [ AminoAcid { c: 'Y' as u8, p: 0.02 }, ]; -static HOMO_SAPIENS: [AminoAcid, ..4] = [ +static HOMO_SAPIENS: [AminoAcid;4] = [ AminoAcid { c: 'a' as u8, p: 0.3029549426680 }, AminoAcid { c: 'c' as u8, p: 0.1979883004921 }, AminoAcid { c: 'g' as u8, p: 0.1975473066391 }, @@ -148,8 +148,8 @@ impl<'a, W: Writer> RepeatFasta<'a, W> { } } -fn make_lookup(a: &[AminoAcid]) -> [AminoAcid, ..LOOKUP_SIZE] { - let mut lookup = [ NULL_AMINO_ACID, ..LOOKUP_SIZE ]; +fn make_lookup(a: &[AminoAcid]) -> [AminoAcid;LOOKUP_SIZE] { + let mut lookup = [ NULL_AMINO_ACID;LOOKUP_SIZE ]; let mut j = 0; for (i, slot) in lookup.iter_mut().enumerate() { while a[j].p < (i as f32) { @@ -162,7 +162,7 @@ fn make_lookup(a: &[AminoAcid]) -> [AminoAcid, ..LOOKUP_SIZE] { struct RandomFasta<'a, W:'a> { seed: u32, - lookup: [AminoAcid, ..LOOKUP_SIZE], + lookup: [AminoAcid;LOOKUP_SIZE], out: &'a mut W, } @@ -193,7 +193,7 @@ impl<'a, W: Writer> RandomFasta<'a, W> { fn make(&mut self, n: uint) -> IoResult<()> { let lines = n / LINE_LEN; let chars_left = n % LINE_LEN; - let mut buf = [0, ..LINE_LEN + 1]; + let mut buf = [0;LINE_LEN + 1]; for _ in range(0, lines) { for i in range(0u, LINE_LEN) { diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs index 1f0bed05521..2de61cf3572 100644 --- a/src/test/bench/shootout-fasta.rs +++ b/src/test/bench/shootout-fasta.rs @@ -89,7 +89,7 @@ fn make_fasta>( -> std::io::IoResult<()> { try!(wr.write(header.as_bytes())); - let mut line = [0u8, .. LINE_LENGTH + 1]; + let mut line = [0u8; LINE_LENGTH + 1]; while n > 0 { let nb = min(LINE_LENGTH, n); for i in range(0, nb) { diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs index d112fe60674..8521e2216e9 100644 --- a/src/test/bench/shootout-k-nucleotide.rs +++ b/src/test/bench/shootout-k-nucleotide.rs @@ -46,10 +46,10 @@ use std::string::String; use std::slice; use std::sync::{Arc, Future}; -static TABLE: [u8, ..4] = [ 'A' as u8, 'C' as u8, 'G' as u8, 'T' as u8 ]; +static TABLE: [u8;4] = [ 'A' as u8, 'C' as u8, 'G' as u8, 'T' as u8 ]; static TABLE_SIZE: uint = 2 << 16; -static OCCURRENCES: [&'static str, ..5] = [ +static OCCURRENCES: [&'static str;5] = [ "GGT", "GGTA", "GGTATT", diff --git a/src/test/bench/shootout-nbody.rs b/src/test/bench/shootout-nbody.rs index 3f36c16aff6..dab67331120 100644 --- a/src/test/bench/shootout-nbody.rs +++ b/src/test/bench/shootout-nbody.rs @@ -45,7 +45,7 @@ const SOLAR_MASS: f64 = 4.0 * PI * PI; const YEAR: f64 = 365.24; const N_BODIES: uint = 5; -static BODIES: [Planet, ..N_BODIES] = [ +static BODIES: [Planet;N_BODIES] = [ // Sun Planet { x: 0.0, y: 0.0, z: 0.0, @@ -102,7 +102,7 @@ struct Planet { impl Copy for Planet {} -fn advance(bodies: &mut [Planet, ..N_BODIES], dt: f64, steps: int) { +fn advance(bodies: &mut [Planet;N_BODIES], dt: f64, steps: int) { for _ in range(0, steps) { let mut b_slice = bodies.as_mut_slice(); loop { @@ -135,7 +135,7 @@ fn advance(bodies: &mut [Planet, ..N_BODIES], dt: f64, steps: int) { } } -fn energy(bodies: &[Planet, ..N_BODIES]) -> f64 { +fn energy(bodies: &[Planet;N_BODIES]) -> f64 { let mut e = 0.0; let mut bodies = bodies.iter(); loop { @@ -155,7 +155,7 @@ fn energy(bodies: &[Planet, ..N_BODIES]) -> f64 { e } -fn offset_momentum(bodies: &mut [Planet, ..N_BODIES]) { +fn offset_momentum(bodies: &mut [Planet;N_BODIES]) { let mut px = 0.0; let mut py = 0.0; let mut pz = 0.0; diff --git a/src/test/bench/shootout-reverse-complement.rs b/src/test/bench/shootout-reverse-complement.rs index 312ee2dd27e..d746ec1dbab 100644 --- a/src/test/bench/shootout-reverse-complement.rs +++ b/src/test/bench/shootout-reverse-complement.rs @@ -50,17 +50,17 @@ use std::ptr::{copy_memory}; use std::io::{IoResult, EndOfFile}; struct Tables { - table8: [u8, ..1 << 8], - table16: [u16, ..1 << 16] + table8: [u8;1 << 8], + table16: [u16;1 << 16] } impl Tables { fn new() -> Tables { - let mut table8 = [0, ..1 << 8]; + let mut table8 = [0;1 << 8]; for (i, v) in table8.iter_mut().enumerate() { *v = Tables::computed_cpl8(i as u8); } - let mut table16 = [0, ..1 << 16]; + let mut table16 = [0;1 << 16]; for (i, v) in table16.iter_mut().enumerate() { *v = table8[i & 255] as u16 << 8 | table8[i >> 8] as u16; diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs index c55f85f40e8..5fb7e2c3a84 100644 --- a/src/test/bench/sudoku.rs +++ b/src/test/bench/sudoku.rs @@ -46,7 +46,7 @@ impl Sudoku { return Sudoku { grid: g } } - pub fn from_vec(vec: &[[u8, ..9], ..9]) -> Sudoku { + pub fn from_vec(vec: &[[u8;9];9]) -> Sudoku { let g = Vec::from_fn(9u, |i| { Vec::from_fn(9u, |j| { vec[i][j] }) }); @@ -198,7 +198,7 @@ impl Colors { } } -static DEFAULT_SUDOKU: [[u8, ..9], ..9] = [ +static DEFAULT_SUDOKU: [[u8;9];9] = [ /* 0 1 2 3 4 5 6 7 8 */ /* 0 */ [0u8, 4u8, 0u8, 6u8, 0u8, 0u8, 0u8, 3u8, 2u8], /* 1 */ [0u8, 0u8, 8u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8], @@ -212,7 +212,7 @@ static DEFAULT_SUDOKU: [[u8, ..9], ..9] = [ ]; #[cfg(test)] -static DEFAULT_SOLUTION: [[u8, ..9], ..9] = [ +static DEFAULT_SOLUTION: [[u8;9];9] = [ /* 0 1 2 3 4 5 6 7 8 */ /* 0 */ [1u8, 4u8, 9u8, 6u8, 7u8, 5u8, 8u8, 3u8, 2u8], /* 1 */ [5u8, 3u8, 8u8, 1u8, 2u8, 9u8, 7u8, 4u8, 6u8], diff --git a/src/test/compile-fail/better-expected.rs b/src/test/compile-fail/better-expected.rs index 489f892726a..2e0f2a174c6 100644 --- a/src/test/compile-fail/better-expected.rs +++ b/src/test/compile-fail/better-expected.rs @@ -9,5 +9,5 @@ // except according to those terms. fn main() { - let x: [int ..3]; //~ ERROR expected one of `(`, `+`, `,`, `::`, or `]`, found `..` + let x: [int 3]; //~ ERROR expected one of `(`, `+`, `,`, `::`, `;`, or `]`, found `3` } diff --git a/src/test/compile-fail/borrowck-for-loop-correct-cmt-for-pattern.rs b/src/test/compile-fail/borrowck-for-loop-correct-cmt-for-pattern.rs index 93a4383b4f5..f0d42bb9ac1 100644 --- a/src/test/compile-fail/borrowck-for-loop-correct-cmt-for-pattern.rs +++ b/src/test/compile-fail/borrowck-for-loop-correct-cmt-for-pattern.rs @@ -11,7 +11,7 @@ // Issue #16205. struct Foo { - a: [Box, ..3], + a: [Box; 3], } fn main() { diff --git a/src/test/compile-fail/coercion-slice.rs b/src/test/compile-fail/coercion-slice.rs index bb020688f58..b6b46fadb13 100644 --- a/src/test/compile-fail/coercion-slice.rs +++ b/src/test/compile-fail/coercion-slice.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Tests that we forbid coercion from `[T, ..n]` to `&[T]` +// Tests that we forbid coercion from `[T; n]` to `&[T]` fn main() { - let _: &[int] = [0i]; //~ERROR: mismatched types: expected `&[int]`, found `[int, ..1]` + let _: &[int] = [0i]; //~ERROR: mismatched types: expected `&[int]`, found `[int; 1]` } diff --git a/src/test/compile-fail/const-cast-wrong-type.rs b/src/test/compile-fail/const-cast-wrong-type.rs index 223426dc7c6..b3597441834 100644 --- a/src/test/compile-fail/const-cast-wrong-type.rs +++ b/src/test/compile-fail/const-cast-wrong-type.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -static a: [u8, ..3] = ['h' as u8, 'i' as u8, 0 as u8]; +static a: [u8; 3] = ['h' as u8, 'i' as u8, 0 as u8]; static b: *const i8 = &a as *const i8; //~ ERROR mismatched types fn main() { diff --git a/src/test/compile-fail/dst-bad-coerce1.rs b/src/test/compile-fail/dst-bad-coerce1.rs index 59499ac070d..c77ae25e0cf 100644 --- a/src/test/compile-fail/dst-bad-coerce1.rs +++ b/src/test/compile-fail/dst-bad-coerce1.rs @@ -20,9 +20,9 @@ trait Bar {} pub fn main() { // With a vec of ints. let f1 = Fat { ptr: [1, 2, 3] }; - let f2: &Fat<[int, ..3]> = &f1; + let f2: &Fat<[int; 3]> = &f1; let f3: &Fat<[uint]> = f2; - //~^ ERROR mismatched types: expected `&Fat<[uint]>`, found `&Fat<[int, ..3]>` + //~^ ERROR mismatched types: expected `&Fat<[uint]>`, found `&Fat<[int; 3]>` // With a trait. let f1 = Fat { ptr: Foo }; diff --git a/src/test/compile-fail/dst-bad-coerce2.rs b/src/test/compile-fail/dst-bad-coerce2.rs index e1a754b6332..6eb650e9781 100644 --- a/src/test/compile-fail/dst-bad-coerce2.rs +++ b/src/test/compile-fail/dst-bad-coerce2.rs @@ -21,7 +21,7 @@ impl Bar for Foo {} pub fn main() { // With a vec of ints. let f1 = Fat { ptr: [1, 2, 3] }; - let f2: &Fat<[int, ..3]> = &f1; + let f2: &Fat<[int; 3]> = &f1; let f3: &mut Fat<[int]> = f2; //~ ERROR mismatched types // With a trait. diff --git a/src/test/compile-fail/dst-bad-coerce3.rs b/src/test/compile-fail/dst-bad-coerce3.rs index 7cf647a26d7..b0bd5176374 100644 --- a/src/test/compile-fail/dst-bad-coerce3.rs +++ b/src/test/compile-fail/dst-bad-coerce3.rs @@ -21,7 +21,7 @@ impl Bar for Foo {} fn baz<'a>() { // With a vec of ints. let f1 = Fat { ptr: [1, 2, 3] }; - let f2: &Fat<[int, ..3]> = &f1; //~ ERROR `f1` does not live long enough + let f2: &Fat<[int; 3]> = &f1; //~ ERROR `f1` does not live long enough let f3: &'a Fat<[int]> = f2; // With a trait. diff --git a/src/test/compile-fail/dst-bad-coerce4.rs b/src/test/compile-fail/dst-bad-coerce4.rs index 9010185f76b..783a32d6302 100644 --- a/src/test/compile-fail/dst-bad-coerce4.rs +++ b/src/test/compile-fail/dst-bad-coerce4.rs @@ -17,6 +17,6 @@ struct Fat { pub fn main() { // With a vec of ints. let f1: &Fat<[int]> = &Fat { ptr: [1, 2, 3] }; - let f2: &Fat<[int, ..3]> = f1; - //~^ ERROR mismatched types: expected `&Fat<[int, ..3]>`, found `&Fat<[int]>` + let f2: &Fat<[int; 3]> = f1; + //~^ ERROR mismatched types: expected `&Fat<[int; 3]>`, found `&Fat<[int]>` } diff --git a/src/test/compile-fail/dst-bad-deep.rs b/src/test/compile-fail/dst-bad-deep.rs index 506322d41f5..0833a74f1da 100644 --- a/src/test/compile-fail/dst-bad-deep.rs +++ b/src/test/compile-fail/dst-bad-deep.rs @@ -18,7 +18,7 @@ struct Fat { } pub fn main() { - let f: Fat<[int, ..3]> = Fat { ptr: [5i, 6, 7] }; + let f: Fat<[int; 3]> = Fat { ptr: [5i, 6, 7] }; let g: &Fat<[int]> = &f; let h: &Fat> = &Fat { ptr: *g }; //~^ ERROR the trait `core::kinds::Sized` is not implemented diff --git a/src/test/compile-fail/huge-array-simple.rs b/src/test/compile-fail/huge-array-simple.rs index 17f85c7bd2b..a9dda771b7f 100644 --- a/src/test/compile-fail/huge-array-simple.rs +++ b/src/test/compile-fail/huge-array-simple.rs @@ -11,5 +11,5 @@ // error-pattern: too big for the current fn main() { - let fat : [u8, ..(1<<61)+(1<<31)] = [0, ..(1u64<<61) as uint +(1u64<<31) as uint]; + let fat : [u8; (1<<61)+(1<<31)] = [0; (1u64<<61) as uint +(1u64<<31) as uint]; } diff --git a/src/test/compile-fail/huge-array.rs b/src/test/compile-fail/huge-array.rs index 4b91564154b..029e9651cb3 100644 --- a/src/test/compile-fail/huge-array.rs +++ b/src/test/compile-fail/huge-array.rs @@ -8,13 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: ..1518599999 +// error-pattern:; 1518599999 fn generic(t: T) { - let s: [T, ..1518600000] = [t, ..1518600000]; + let s: [T; 1518600000] = [t; 1518600000]; } fn main() { - let x: [u8, ..1518599999] = [0, ..1518599999]; - generic::<[u8, ..1518599999]>(x); + let x: [u8; 1518599999] = [0; 1518599999]; + generic::<[u8; 1518599999]>(x); } diff --git a/src/test/compile-fail/huge-enum.rs b/src/test/compile-fail/huge-enum.rs index 4a85cb5753b..7c7a75abf3f 100644 --- a/src/test/compile-fail/huge-enum.rs +++ b/src/test/compile-fail/huge-enum.rs @@ -14,10 +14,10 @@ #[cfg(target_word_size = "32")] fn main() { - let big: Option<[u32, ..(1<<29)-1]> = None; + let big: Option<[u32; (1<<29)-1]> = None; } #[cfg(target_word_size = "64")] fn main() { - let big: Option<[u32, ..(1<<45)-1]> = None; + let big: Option<[u32; (1<<45)-1]> = None; } diff --git a/src/test/compile-fail/issue-13446.rs b/src/test/compile-fail/issue-13446.rs index 162324b7c59..a0a7660428d 100644 --- a/src/test/compile-fail/issue-13446.rs +++ b/src/test/compile-fail/issue-13446.rs @@ -13,7 +13,7 @@ // error-pattern: mismatched types -static VEC: [u32, ..256] = vec!(); +static VEC: [u32; 256] = vec!(); fn main() {} diff --git a/src/test/compile-fail/issue-13482-2.rs b/src/test/compile-fail/issue-13482-2.rs index 4ec8c2b1b7e..ef7d3d4d158 100644 --- a/src/test/compile-fail/issue-13482-2.rs +++ b/src/test/compile-fail/issue-13482-2.rs @@ -14,7 +14,7 @@ fn main() { let x = [1,2]; let y = match x { [] => None, - //~^ ERROR types: expected `[_#0i, ..2]`, found `[_#7t, ..0]` + //~^ ERROR types: expected `[_#0i; 2]`, found `[_#7t; 0]` // (expected array of 2 elements, found array of 0 elements) [a,_] => Some(a) }; diff --git a/src/test/compile-fail/issue-13482.rs b/src/test/compile-fail/issue-13482.rs index 18070ed53b0..157280b1719 100644 --- a/src/test/compile-fail/issue-13482.rs +++ b/src/test/compile-fail/issue-13482.rs @@ -12,7 +12,7 @@ fn main() { let x = [1,2]; let y = match x { [] => None, -//~^ ERROR types: expected `[_, ..2]`, found `[_, ..0]` +//~^ ERROR types: expected `[_; 2]`, found `[_; 0]` // (expected array of 2 elements, found array of 0 elements) [a,_] => Some(a) }; diff --git a/src/test/compile-fail/issue-14845.rs b/src/test/compile-fail/issue-14845.rs index bc606d8139f..5166d84a025 100644 --- a/src/test/compile-fail/issue-14845.rs +++ b/src/test/compile-fail/issue-14845.rs @@ -10,15 +10,15 @@ struct X { - a: [u8, ..1] + a: [u8; 1] } fn main() { let x = X { a: [0] }; let _f = &x.a as *mut u8; - //~^ ERROR mismatched types: expected `*mut u8`, found `&[u8, ..1]` + //~^ ERROR mismatched types: expected `*mut u8`, found `&[u8; 1]` let local = [0u8]; let _v = &local as *mut u8; - //~^ ERROR mismatched types: expected `*mut u8`, found `&[u8, ..1]` + //~^ ERROR mismatched types: expected `*mut u8`, found `&[u8; 1]` } diff --git a/src/test/compile-fail/issue-17252.rs b/src/test/compile-fail/issue-17252.rs index 4a6b80d765b..4adb3f041a3 100644 --- a/src/test/compile-fail/issue-17252.rs +++ b/src/test/compile-fail/issue-17252.rs @@ -11,10 +11,10 @@ static FOO: uint = FOO; //~ ERROR recursive constant fn main() { - let _x: [u8, ..FOO]; // caused stack overflow prior to fix + let _x: [u8; FOO]; // caused stack overflow prior to fix let _y: uint = 1 + { static BAR: uint = BAR; //~ ERROR recursive constant - let _z: [u8, ..BAR]; // caused stack overflow prior to fix + let _z: [u8; BAR]; // caused stack overflow prior to fix 1 }; } diff --git a/src/test/compile-fail/issue-17441.rs b/src/test/compile-fail/issue-17441.rs index 11c815da1c7..e5da5c5504e 100644 --- a/src/test/compile-fail/issue-17441.rs +++ b/src/test/compile-fail/issue-17441.rs @@ -10,7 +10,7 @@ fn main() { let _foo = &[1u, 2] as [uint]; - //~^ ERROR cast to unsized type: `&[uint, ..2]` as `[uint]` + //~^ ERROR cast to unsized type: `&[uint; 2]` as `[uint]` //~^^ HELP consider using an implicit coercion to `&[uint]` instead let _bar = box 1u as std::fmt::Show; //~^ ERROR cast to unsized type: `Box` as `core::fmt::Show` @@ -19,6 +19,6 @@ fn main() { //~^ ERROR cast to unsized type: `uint` as `core::fmt::Show` //~^^ HELP consider using a box or reference as appropriate let _quux = [1u, 2] as [uint]; - //~^ ERROR cast to unsized type: `[uint, ..2]` as `[uint]` + //~^ ERROR cast to unsized type: `[uint; 2]` as `[uint]` //~^^ HELP consider using a box or reference as appropriate } diff --git a/src/test/compile-fail/issue-17718-borrow-interior.rs b/src/test/compile-fail/issue-17718-borrow-interior.rs index 1f763dbdc9f..8aa5fdf1c4d 100644 --- a/src/test/compile-fail/issue-17718-borrow-interior.rs +++ b/src/test/compile-fail/issue-17718-borrow-interior.rs @@ -15,7 +15,7 @@ static B: &'static uint = &A.a; static C: &'static uint = &(A.a); //~^ ERROR: cannot refer to the interior of another static -static D: [uint, ..1] = [1]; +static D: [uint; 1] = [1]; static E: uint = D[0]; //~^ ERROR: cannot refer to other statics by value static F: &'static uint = &D[0]; diff --git a/src/test/compile-fail/issue-19244-1.rs b/src/test/compile-fail/issue-19244-1.rs index 7ca83f21305..fafe6377397 100644 --- a/src/test/compile-fail/issue-19244-1.rs +++ b/src/test/compile-fail/issue-19244-1.rs @@ -11,6 +11,6 @@ const TUP: (uint,) = (42,); fn main() { - let a: [int, ..TUP.1]; + let a: [int; TUP.1]; //~^ ERROR expected constant expr for array length: tuple index out of bounds } diff --git a/src/test/compile-fail/issue-19244-2.rs b/src/test/compile-fail/issue-19244-2.rs index d9aeecc0222..95965ca35f9 100644 --- a/src/test/compile-fail/issue-19244-2.rs +++ b/src/test/compile-fail/issue-19244-2.rs @@ -12,6 +12,6 @@ struct MyStruct { field: uint } const STRUCT: MyStruct = MyStruct { field: 42 }; fn main() { - let a: [int, ..STRUCT.nonexistent_field]; + let a: [int; STRUCT.nonexistent_field]; //~^ ERROR expected constant expr for array length: nonexistent struct field } diff --git a/src/test/compile-fail/issue-2149.rs b/src/test/compile-fail/issue-2149.rs index 1150f40db76..3343e92252f 100644 --- a/src/test/compile-fail/issue-2149.rs +++ b/src/test/compile-fail/issue-2149.rs @@ -22,5 +22,5 @@ impl vec_monad for Vec { } fn main() { ["hi"].bind(|x| [x] ); - //~^ ERROR type `[&str, ..1]` does not implement any method in scope named `bind` + //~^ ERROR type `[&str; 1]` does not implement any method in scope named `bind` } diff --git a/src/test/compile-fail/issue-4517.rs b/src/test/compile-fail/issue-4517.rs index f61ed35fca3..1c5fd9be1bd 100644 --- a/src/test/compile-fail/issue-4517.rs +++ b/src/test/compile-fail/issue-4517.rs @@ -11,8 +11,8 @@ fn bar(int_param: int) {} fn main() { - let foo: [u8, ..4] = [1u8, ..4u]; + let foo: [u8; 4] = [1u8; 4u]; bar(foo); - //~^ ERROR mismatched types: expected `int`, found `[u8, ..4]` + //~^ ERROR mismatched types: expected `int`, found `[u8; 4]` // (expected int, found vector) } diff --git a/src/test/compile-fail/lint-uppercase-variables.rs b/src/test/compile-fail/lint-uppercase-variables.rs index eb5c475e7ef..19373c806f1 100644 --- a/src/test/compile-fail/lint-uppercase-variables.rs +++ b/src/test/compile-fail/lint-uppercase-variables.rs @@ -29,7 +29,7 @@ fn main() { println!("{}", Test); let mut f = File::open(&Path::new("something.txt")); - let mut buff = [0u8, ..16]; + let mut buff = [0u8; 16]; match f.read(&mut buff) { Ok(cnt) => println!("read this many bytes: {}", cnt), Err(IoError{ kind: EndOfFile, .. }) => println!("Got end of file: {}", EndOfFile.to_string()), diff --git a/src/test/compile-fail/move-fragments-9.rs b/src/test/compile-fail/move-fragments-9.rs index ce05087f659..0b095ff6f82 100644 --- a/src/test/compile-fail/move-fragments-9.rs +++ b/src/test/compile-fail/move-fragments-9.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Test moving array structures, e.g. `[T, ..3]` as well as moving +// Test moving array structures, e.g. `[T; 3]` as well as moving // elements in and out of such arrays. // // Note also that the `test_move_array_then_overwrite` tests represent @@ -18,14 +18,14 @@ pub struct D { d: int } impl Drop for D { fn drop(&mut self) { } } #[rustc_move_fragments] -pub fn test_move_array_via_return(a: [D, ..3]) -> [D, ..3] { +pub fn test_move_array_via_return(a: [D; 3]) -> [D; 3] { //~^ ERROR assigned_leaf_path: `$(local a)` //~| ERROR moved_leaf_path: `$(local a)` return a; } #[rustc_move_fragments] -pub fn test_move_array_into_recv(a: [D, ..3], recv: &mut [D, ..3]) { +pub fn test_move_array_into_recv(a: [D; 3], recv: &mut [D; 3]) { //~^ ERROR parent_of_fragments: `$(local recv)` //~| ERROR assigned_leaf_path: `$(local a)` //~| ERROR moved_leaf_path: `$(local a)` @@ -34,7 +34,7 @@ pub fn test_move_array_into_recv(a: [D, ..3], recv: &mut [D, ..3]) { } #[rustc_move_fragments] -pub fn test_extract_array_elem(a: [D, ..3], i: uint) -> D { +pub fn test_extract_array_elem(a: [D; 3], i: uint) -> D { //~^ ERROR parent_of_fragments: `$(local a)` //~| ERROR assigned_leaf_path: `$(local i)` //~| ERROR moved_leaf_path: `$(local a).[]` @@ -43,7 +43,7 @@ pub fn test_extract_array_elem(a: [D, ..3], i: uint) -> D { } #[rustc_move_fragments] -pub fn test_overwrite_array_elem(mut a: [D, ..3], i: uint, d: D) { +pub fn test_overwrite_array_elem(mut a: [D; 3], i: uint, d: D) { //~^ ERROR parent_of_fragments: `$(local mut a)` //~| ERROR assigned_leaf_path: `$(local i)` //~| ERROR assigned_leaf_path: `$(local d)` @@ -59,7 +59,7 @@ pub fn test_overwrite_array_elem(mut a: [D, ..3], i: uint, d: D) { // See RFC PR 320 for more discussion. #[rustc_move_fragments] -pub fn test_move_array_then_overwrite_elem1(mut a: [D, ..3], i: uint, recv: &mut [D, ..3], d: D) { +pub fn test_move_array_then_overwrite_elem1(mut a: [D; 3], i: uint, recv: &mut [D; 3], d: D) { //~^ ERROR parent_of_fragments: `$(local mut a)` //~| ERROR parent_of_fragments: `$(local recv)` //~| ERROR assigned_leaf_path: `$(local recv).*` @@ -76,8 +76,8 @@ pub fn test_move_array_then_overwrite_elem1(mut a: [D, ..3], i: uint, recv: &mut } #[rustc_move_fragments] -pub fn test_move_array_then_overwrite_elem2(mut a: [D, ..3], i: uint, j: uint, - recv: &mut [D, ..3], d1: D, d2: D) { +pub fn test_move_array_then_overwrite_elem2(mut a: [D; 3], i: uint, j: uint, + recv: &mut [D; 3], d1: D, d2: D) { //~^^ ERROR parent_of_fragments: `$(local mut a)` //~| ERROR parent_of_fragments: `$(local recv)` //~| ERROR assigned_leaf_path: `$(local recv).*` diff --git a/src/test/compile-fail/moves-based-on-type-exprs.rs b/src/test/compile-fail/moves-based-on-type-exprs.rs index 678808f166c..d8d84e558a9 100644 --- a/src/test/compile-fail/moves-based-on-type-exprs.rs +++ b/src/test/compile-fail/moves-based-on-type-exprs.rs @@ -89,7 +89,7 @@ fn f100() { fn f110() { let x = vec!("hi".to_string()); - let _y = [x.into_iter().next().unwrap(), ..1]; + let _y = [x.into_iter().next().unwrap(); 1]; touch(&x); //~ ERROR use of moved value: `x` } diff --git a/src/test/compile-fail/non-constant-enum-for-vec-repeat.rs b/src/test/compile-fail/non-constant-enum-for-vec-repeat.rs index 3ccce591ee7..a1dc2ab2041 100644 --- a/src/test/compile-fail/non-constant-enum-for-vec-repeat.rs +++ b/src/test/compile-fail/non-constant-enum-for-vec-repeat.rs @@ -11,6 +11,6 @@ enum State { ST_NULL, ST_WHITESPACE } fn main() { - [State::ST_NULL, ..(State::ST_WHITESPACE as uint)]; + [State::ST_NULL; (State::ST_WHITESPACE as uint)]; //~^ ERROR expected constant integer for repeat count, found non-constant expression } diff --git a/src/test/compile-fail/non-constant-expr-for-fixed-len-vec.rs b/src/test/compile-fail/non-constant-expr-for-fixed-len-vec.rs index 91551941c06..85d734ddaf2 100644 --- a/src/test/compile-fail/non-constant-expr-for-fixed-len-vec.rs +++ b/src/test/compile-fail/non-constant-expr-for-fixed-len-vec.rs @@ -12,7 +12,7 @@ fn main() { fn bar(n: int) { - let _x: [int, ..n]; + let _x: [int; n]; //~^ ERROR expected constant expr for array length: non-constant path in constant expr } } diff --git a/src/test/compile-fail/non-constant-expr-for-vec-repeat.rs b/src/test/compile-fail/non-constant-expr-for-vec-repeat.rs index 299e9d3dced..2e063e5237c 100644 --- a/src/test/compile-fail/non-constant-expr-for-vec-repeat.rs +++ b/src/test/compile-fail/non-constant-expr-for-vec-repeat.rs @@ -12,6 +12,6 @@ fn main() { fn bar(n: uint) { - let _x = [0, ..n]; //~ ERROR expected constant integer for repeat count, found variable + let _x = [0; n]; //~ ERROR expected constant integer for repeat count, found variable } } diff --git a/src/test/compile-fail/non-exhaustive-pattern-witness.rs b/src/test/compile-fail/non-exhaustive-pattern-witness.rs index 6e1c3db1014..d35e3ad3c55 100644 --- a/src/test/compile-fail/non-exhaustive-pattern-witness.rs +++ b/src/test/compile-fail/non-exhaustive-pattern-witness.rs @@ -12,7 +12,7 @@ struct Foo { first: bool, - second: Option<[uint, ..4]> + second: Option<[uint; 4]> } enum Color { diff --git a/src/test/compile-fail/packed-struct-generic-transmute.rs b/src/test/compile-fail/packed-struct-generic-transmute.rs index d699f69864e..5c0aba42b96 100644 --- a/src/test/compile-fail/packed-struct-generic-transmute.rs +++ b/src/test/compile-fail/packed-struct-generic-transmute.rs @@ -33,7 +33,7 @@ struct Oof { fn main() { let foo = Foo { bar: [1u8, 2, 3, 4, 5], baz: 10i32 }; unsafe { - let oof: Oof<[u8, .. 5], i32> = mem::transmute(foo); + let oof: Oof<[u8; 5], i32> = mem::transmute(foo); println!("{} {}", oof.rab[], oof.zab); } } diff --git a/src/test/compile-fail/removed-syntax-fixed-vec.rs b/src/test/compile-fail/removed-syntax-fixed-vec.rs index fe49d1f4a8d..0a8420c19c3 100644 --- a/src/test/compile-fail/removed-syntax-fixed-vec.rs +++ b/src/test/compile-fail/removed-syntax-fixed-vec.rs @@ -8,4 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -type v = [int * 3]; //~ ERROR expected one of `(`, `+`, `,`, `::`, or `]`, found `*` +type v = [int * 3]; //~ ERROR expected one of `(`, `+`, `,`, `::`, `;`, or `]`, found `*` diff --git a/src/test/compile-fail/removed-syntax-mut-vec-expr.rs b/src/test/compile-fail/removed-syntax-mut-vec-expr.rs index 437f871f8ea..30302bbd16e 100644 --- a/src/test/compile-fail/removed-syntax-mut-vec-expr.rs +++ b/src/test/compile-fail/removed-syntax-mut-vec-expr.rs @@ -11,5 +11,5 @@ fn f() { let v = [mut 1, 2, 3, 4]; //~^ ERROR expected identifier, found keyword `mut` - //~^^ ERROR expected one of `!`, `,`, `.`, `::`, `]`, `{`, or an operator, found `1` + //~^^ ERROR expected one of `!`, `,`, `.`, `::`, `;`, `]`, `{`, or an operator, found `1` } diff --git a/src/test/compile-fail/removed-syntax-mut-vec-ty.rs b/src/test/compile-fail/removed-syntax-mut-vec-ty.rs index af469fadf98..9c6056bd72a 100644 --- a/src/test/compile-fail/removed-syntax-mut-vec-ty.rs +++ b/src/test/compile-fail/removed-syntax-mut-vec-ty.rs @@ -10,4 +10,4 @@ type v = [mut int]; //~^ ERROR expected identifier, found keyword `mut` - //~^^ ERROR expected one of `(`, `+`, `,`, `::`, or `]`, found `int` + //~^^ ERROR expected one of `(`, `+`, `,`, `::`, `;`, or `]`, found `int` diff --git a/src/test/compile-fail/repeat-to-run-dtor-twice.rs b/src/test/compile-fail/repeat-to-run-dtor-twice.rs index 8fdf586b3d1..d3126cf44d1 100644 --- a/src/test/compile-fail/repeat-to-run-dtor-twice.rs +++ b/src/test/compile-fail/repeat-to-run-dtor-twice.rs @@ -24,6 +24,6 @@ impl Drop for Foo { fn main() { let a = Foo { x: 3 }; - let _ = [ a, ..5 ]; + let _ = [ a; 5 ]; //~^ ERROR the trait `core::kinds::Copy` is not implemented for the type `Foo` } diff --git a/src/test/compile-fail/repeat_count.rs b/src/test/compile-fail/repeat_count.rs index 38fbb426fb1..3b0ef0c293a 100644 --- a/src/test/compile-fail/repeat_count.rs +++ b/src/test/compile-fail/repeat_count.rs @@ -12,18 +12,18 @@ fn main() { let n = 1; - let a = [0, ..n]; //~ ERROR expected constant integer for repeat count, found variable - let b = [0, ..()]; + let a = [0; n]; //~ ERROR expected constant integer for repeat count, found variable + let b = [0; ()]; //~^ ERROR expected constant integer for repeat count, found non-constant expression //~^^ ERROR: expected `uint`, found `()` - let c = [0, ..true]; //~ ERROR expected positive integer for repeat count, found boolean + let c = [0; true]; //~ ERROR expected positive integer for repeat count, found boolean //~^ ERROR: expected `uint`, found `bool` - let d = [0, ..0.5]; //~ ERROR expected positive integer for repeat count, found float + let d = [0; 0.5]; //~ ERROR expected positive integer for repeat count, found float //~^ ERROR: expected `uint`, found `_` - let e = [0, .."foo"]; //~ ERROR expected positive integer for repeat count, found string + let e = [0; "foo"]; //~ ERROR expected positive integer for repeat count, found string //~^ ERROR: expected `uint`, found `&'static str` - let f = [0, ..-4]; + let f = [0; -4]; //~^ ERROR expected positive integer for repeat count, found negative integer - let f = [0u, ..-1]; + let f = [0u; -1]; //~^ ERROR expected positive integer for repeat count, found negative integer } diff --git a/src/test/compile-fail/static-vec-repeat-not-constant.rs b/src/test/compile-fail/static-vec-repeat-not-constant.rs index 03be2cc8f0f..ff84ed5bf0c 100644 --- a/src/test/compile-fail/static-vec-repeat-not-constant.rs +++ b/src/test/compile-fail/static-vec-repeat-not-constant.rs @@ -10,7 +10,7 @@ fn foo() -> int { 23 } -static a: [int, ..2] = [foo(), ..2]; +static a: [int; 2] = [foo(); 2]; //~^ ERROR: function calls in constants are limited to struct and enum constructors fn main() {} diff --git a/src/test/compile-fail/trailing-comma-array-repeat.rs b/src/test/compile-fail/trailing-comma-array-repeat.rs deleted file mode 100644 index dadd6571583..00000000000 --- a/src/test/compile-fail/trailing-comma-array-repeat.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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. - -fn main() { - let [_, ..,] = [(), ()]; //~ ERROR unexpected token: `]` -} diff --git a/src/test/compile-fail/transmute-type-parameters.rs b/src/test/compile-fail/transmute-type-parameters.rs index 53391a0e894..2286c0e75bd 100644 --- a/src/test/compile-fail/transmute-type-parameters.rs +++ b/src/test/compile-fail/transmute-type-parameters.rs @@ -20,7 +20,7 @@ unsafe fn g(x: (T, int)) { let _: int = transmute(x); //~ ERROR cannot transmute } -unsafe fn h(x: [T, ..10]) { +unsafe fn h(x: [T; 10]) { let _: int = transmute(x); //~ ERROR cannot transmute } diff --git a/src/test/compile-fail/vector-cast-weirdness.rs b/src/test/compile-fail/vector-cast-weirdness.rs index e096e5eb436..c5109ce473e 100644 --- a/src/test/compile-fail/vector-cast-weirdness.rs +++ b/src/test/compile-fail/vector-cast-weirdness.rs @@ -12,20 +12,20 @@ // presence of the `_` type shorthand notation. struct X { - y: [u8, ..2], + y: [u8; 2], } fn main() { let x1 = X { y: [0, 0] }; let p1: *const u8 = &x1.y as *const _; //~ ERROR mismatched types - let t1: *const [u8, ..2] = &x1.y as *const _; - let h1: *const [u8, ..2] = &x1.y as *const [u8, ..2]; + let t1: *const [u8; 2] = &x1.y as *const _; + let h1: *const [u8; 2] = &x1.y as *const [u8; 2]; let mut x1 = X { y: [0, 0] }; let p1: *mut u8 = &mut x1.y as *mut _; //~ ERROR mismatched types - let t1: *mut [u8, ..2] = &mut x1.y as *mut _; - let h1: *mut [u8, ..2] = &mut x1.y as *mut [u8, ..2]; + let t1: *mut [u8; 2] = &mut x1.y as *mut _; + let h1: *mut [u8; 2] = &mut x1.y as *mut [u8; 2]; } diff --git a/src/test/debuginfo/evec-in-struct.rs b/src/test/debuginfo/evec-in-struct.rs index aab9c446a9e..786868f6b89 100644 --- a/src/test/debuginfo/evec-in-struct.rs +++ b/src/test/debuginfo/evec-in-struct.rs @@ -53,28 +53,28 @@ #![allow(unused_variables)] struct NoPadding1 { - x: [u32, ..3], + x: [u32; 3], y: i32, - z: [f32, ..2] + z: [f32; 2] } struct NoPadding2 { - x: [u32, ..3], - y: [[u32, ..2], ..2] + x: [u32; 3], + y: [[u32; 2]; 2] } struct StructInternalPadding { - x: [i16, ..2], - y: [i64, ..2] + x: [i16; 2], + y: [i64; 2] } struct SingleVec { - x: [i16, ..5] + x: [i16; 5] } struct StructPaddedAtEnd { - x: [i64, ..2], - y: [i16, ..2] + x: [i64; 2], + y: [i16; 2] } fn main() { diff --git a/src/test/debuginfo/lexical-scopes-in-block-expression.rs b/src/test/debuginfo/lexical-scopes-in-block-expression.rs index a1f34aea0f2..41dee642fea 100644 --- a/src/test/debuginfo/lexical-scopes-in-block-expression.rs +++ b/src/test/debuginfo/lexical-scopes-in-block-expression.rs @@ -450,7 +450,7 @@ fn main() { sentinel(); val - }, ..10]; + }; 10]; zzz(); // #break sentinel(); @@ -491,7 +491,7 @@ fn main() { sentinel(); // index expression - let a_vector = [10i, ..20]; + let a_vector = [10i; 20]; let _ = a_vector[{ zzz(); // #break sentinel(); diff --git a/src/test/debuginfo/recursive-struct.rs b/src/test/debuginfo/recursive-struct.rs index 032b8b1fa26..8cc0fdabfc2 100644 --- a/src/test/debuginfo/recursive-struct.rs +++ b/src/test/debuginfo/recursive-struct.rs @@ -143,7 +143,7 @@ fn main() { value: 2, }; - let vec_unique: [UniqueNode, ..1] = [UniqueNode { + let vec_unique: [UniqueNode; 1] = [UniqueNode { next: Val { val: box UniqueNode { next: Empty, diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs index d72b080409e..286c44667c5 100644 --- a/src/test/debuginfo/type-names.rs +++ b/src/test/debuginfo/type-names.rs @@ -99,10 +99,10 @@ // VECTORS // gdb-command:whatis fixed_size_vec1 -// gdb-check:type = struct ([type-names::Struct1, ..3], i16) +// gdb-check:type = struct ([type-names::Struct1; 3], i16) // gdb-command:whatis fixed_size_vec2 -// gdb-check:type = struct ([uint, ..3], i16) +// gdb-check:type = struct ([uint; 3], i16) // gdb-command:whatis slice1 // gdb-check:type = struct &[uint] diff --git a/src/test/debuginfo/vec.rs b/src/test/debuginfo/vec.rs index fd422a90e63..00c93653cf4 100644 --- a/src/test/debuginfo/vec.rs +++ b/src/test/debuginfo/vec.rs @@ -30,7 +30,7 @@ #![allow(unused_variables)] -static mut VECT: [i32, ..3] = [1, 2, 3]; +static mut VECT: [i32; 3] = [1, 2, 3]; fn main() { let a = [1i, 2, 3]; diff --git a/src/test/pretty/blank-lines.rs b/src/test/pretty/blank-lines.rs index 24eb5337d25..1774edd3f76 100644 --- a/src/test/pretty/blank-lines.rs +++ b/src/test/pretty/blank-lines.rs @@ -9,7 +9,7 @@ // except according to those terms. // pp-exact -fn f() -> [int, ..3] { +fn f() -> [int; 3] { let picard = 0; let data = 1; diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index b5ea9bd4b89..974af1e6f3e 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -21,26 +21,26 @@ use std::prelude::*; // #4264 fixed-length vector types -pub fn foo(_: [int, ..(3 as uint)]) { } +pub fn foo(_: [int; (3 as uint)]) { } pub fn bar() { const FOO: uint = ((5u as uint) - (4u as uint) as uint); - let _: [(), ..(FOO as uint)] = ([(() as ())] as [(), ..1]); + let _: [(); (FOO as uint)] = ([(() as ())] as [(); 1]); - let _: [(), ..(1u as uint)] = ([(() as ())] as [(), ..1]); + let _: [(); (1u as uint)] = ([(() as ())] as [(); 1]); let _ = - (((&((([(1i as int), (2 as int), (3 as int)] as [int, ..3])) as - [int, ..3]) as &[int, ..3]) as *const _ as *const [int, ..3]) - as *const [int, ..(3u as uint)] as *const [int, ..3]); + (((&((([(1i as int), (2 as int), (3 as int)] as [int; 3])) as + [int; 3]) as &[int; 3]) as *const _ as *const [int; 3]) as + *const [int; (3u as uint)] as *const [int; 3]); (match (() as ()) { () => { #[inline] #[allow(dead_code)] static __STATIC_FMTSTR: &'static [&'static str] = - (&([("test" as &'static str)] as [&'static str, ..1]) as - &'static [&'static str, ..1]); + (&([("test" as &'static str)] as [&'static str; 1]) as + &'static [&'static str; 1]); @@ -57,9 +57,9 @@ pub fn bar() { &'static [&'static str]), (&([] as - [core::fmt::Argument<'_>, ..0]) + [core::fmt::Argument<'_>; 0]) as - &[core::fmt::Argument<'_>, ..0])) + &[core::fmt::Argument<'_>; 0])) as core::fmt::Arguments<'_>) as @@ -68,18 +68,17 @@ pub fn bar() { } } as collections::string::String); } -pub type Foo = [int, ..(3u as uint)]; +pub type Foo = [int; (3u as uint)]; pub struct Bar { - pub x: [int, ..(3u as uint)], + pub x: [int; (3u as uint)], } -pub struct TupleBar([int, ..(4u as uint)]); -pub enum Baz { BazVariant([int, ..(5u as uint)]), } +pub struct TupleBar([int; (4u as uint)]); +pub enum Baz { BazVariant([int; (5u as uint)]), } pub fn id(x: T) -> T { (x as T) } pub fn use_id() { let _ = - ((id::<[int, ..(3u as uint)]> as - fn([int, ..3]) -> [int, ..3])(([(1 as int), (2 as int), - (3 as int)] as [int, ..3])) as - [int, ..3]); + ((id::<[int; (3u as uint)]> as + fn([int; 3]) -> [int; 3])(([(1 as int), (2 as int), (3 as int)] + as [int; 3])) as [int; 3]); } fn main() { } diff --git a/src/test/run-make/no-stack-check/attr.rs b/src/test/run-make/no-stack-check/attr.rs index ef2db932b41..7d0fc2d7fe5 100644 --- a/src/test/run-make/no-stack-check/attr.rs +++ b/src/test/run-make/no-stack-check/attr.rs @@ -20,6 +20,6 @@ extern { #[no_stack_check] pub unsafe fn foo() { // Make sure we use the stack - let x: [u8, ..50] = [0, ..50]; + let x: [u8; 50] = [0; 50]; black_box(x.as_ptr()); } diff --git a/src/test/run-make/no-stack-check/flag.rs b/src/test/run-make/no-stack-check/flag.rs index ee0364001e1..2b6e7240d6f 100644 --- a/src/test/run-make/no-stack-check/flag.rs +++ b/src/test/run-make/no-stack-check/flag.rs @@ -19,6 +19,6 @@ extern { pub unsafe fn foo() { // Make sure we use the stack - let x: [u8, ..50] = [0, ..50]; + let x: [u8; 50] = [0; 50]; black_box(x.as_ptr()); } diff --git a/src/test/run-make/target-specs/foo.rs b/src/test/run-make/target-specs/foo.rs index cab98204b17..fd112034f40 100644 --- a/src/test/run-make/target-specs/foo.rs +++ b/src/test/run-make/target-specs/foo.rs @@ -21,7 +21,7 @@ trait Sized { } fn start(_main: *const u8, _argc: int, _argv: *const *const u8) -> int { 0 } extern { - fn _foo() -> [u8, ..16]; + fn _foo() -> [u8; 16]; } fn _main() { diff --git a/src/test/run-pass/cast-in-array-size.rs b/src/test/run-pass/cast-in-array-size.rs index aaffb013ad8..717ca3ff9fe 100644 --- a/src/test/run-pass/cast-in-array-size.rs +++ b/src/test/run-pass/cast-in-array-size.rs @@ -13,8 +13,8 @@ const SIZE: int = 25; fn main() { - let _a: [bool, ..1 as uint]; - let _b: [int, ..SIZE as uint] = [1, ..SIZE as uint]; - let _c: [bool, ..'\n' as uint] = [true, ..'\n' as uint]; - let _d: [bool, ..true as uint] = [true, ..true as uint]; + let _a: [bool; 1 as uint]; + let _b: [int; SIZE as uint] = [1; SIZE as uint]; + let _c: [bool; '\n' as uint] = [true; '\n' as uint]; + let _d: [bool; true as uint] = [true; true as uint]; } diff --git a/src/test/run-pass/check-static-slice.rs b/src/test/run-pass/check-static-slice.rs index 60daedec4c7..6e2cfedf9ec 100644 --- a/src/test/run-pass/check-static-slice.rs +++ b/src/test/run-pass/check-static-slice.rs @@ -11,11 +11,11 @@ // Check that the various ways of getting to a reference to a vec (both sized // and unsized) work properly. -const aa: [int, ..3] = [1, 2, 3]; -const ab: &'static [int, ..3] = &aa; +const aa: [int; 3] = [1, 2, 3]; +const ab: &'static [int; 3] = &aa; const ac: &'static [int] = ab; const ad: &'static [int] = &aa; -const ae: &'static [int, ..3] = &[1, 2, 3]; +const ae: &'static [int; 3] = &[1, 2, 3]; const af: &'static [int] = &[1, 2, 3]; static ca: int = aa[0]; diff --git a/src/test/run-pass/const-autoderef.rs b/src/test/run-pass/const-autoderef.rs index e80ed7c984b..71312fb3878 100644 --- a/src/test/run-pass/const-autoderef.rs +++ b/src/test/run-pass/const-autoderef.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -static A: [u8, ..1] = ['h' as u8]; +static A: [u8; 1] = ['h' as u8]; static B: u8 = (&A)[0]; -static C: &'static &'static &'static &'static [u8, ..1] = & & & &A; +static C: &'static &'static &'static &'static [u8; 1] = & & & &A; static D: u8 = (&C)[0]; pub fn main() { diff --git a/src/test/run-pass/const-enum-vec-index.rs b/src/test/run-pass/const-enum-vec-index.rs index fef6c8624cf..4c8124d28a2 100644 --- a/src/test/run-pass/const-enum-vec-index.rs +++ b/src/test/run-pass/const-enum-vec-index.rs @@ -12,7 +12,7 @@ enum E { V1(int), V0 } const C: &'static [E] = &[E::V0, E::V1(0xDEADBEE)]; static C0: E = C[0]; static C1: E = C[1]; -const D: &'static [E, ..2] = &[E::V0, E::V1(0xDEADBEE)]; +const D: &'static [E; 2] = &[E::V0, E::V1(0xDEADBEE)]; static D0: E = C[0]; static D1: E = C[1]; diff --git a/src/test/run-pass/const-enum-vector.rs b/src/test/run-pass/const-enum-vector.rs index 83687f8775b..6eb5c2dab38 100644 --- a/src/test/run-pass/const-enum-vector.rs +++ b/src/test/run-pass/const-enum-vector.rs @@ -9,7 +9,7 @@ // except according to those terms. enum E { V1(int), V0 } -static C: [E, ..3] = [E::V0, E::V1(0xDEADBEE), E::V0]; +static C: [E; 3] = [E::V0, E::V1(0xDEADBEE), E::V0]; pub fn main() { match C[1] { diff --git a/src/test/run-pass/const-expr-in-fixed-length-vec.rs b/src/test/run-pass/const-expr-in-fixed-length-vec.rs index 317a54e927f..6317c2eec18 100644 --- a/src/test/run-pass/const-expr-in-fixed-length-vec.rs +++ b/src/test/run-pass/const-expr-in-fixed-length-vec.rs @@ -14,6 +14,6 @@ pub fn main() { const FOO: uint = 2; - let _v: [int, ..FOO*3]; + let _v: [int; FOO*3]; } diff --git a/src/test/run-pass/const-expr-in-vec-repeat.rs b/src/test/run-pass/const-expr-in-vec-repeat.rs index 54386b33dd9..d692f3a87e4 100644 --- a/src/test/run-pass/const-expr-in-vec-repeat.rs +++ b/src/test/run-pass/const-expr-in-vec-repeat.rs @@ -13,6 +13,6 @@ pub fn main() { const FOO: uint = 2; - let _v = [0i, ..FOO*3*2/2]; + let _v = [0i; FOO*3*2/2]; } diff --git a/src/test/run-pass/const-fields-and-indexing.rs b/src/test/run-pass/const-fields-and-indexing.rs index 49b244a162b..0819e0becbf 100644 --- a/src/test/run-pass/const-fields-and-indexing.rs +++ b/src/test/run-pass/const-fields-and-indexing.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const x : [int, ..4] = [1,2,3,4]; +const x : [int; 4] = [1,2,3,4]; static p : int = x[2]; const y : &'static [int] = &[1,2,3,4]; static q : int = y[2]; diff --git a/src/test/run-pass/const-region-ptrs-noncopy.rs b/src/test/run-pass/const-region-ptrs-noncopy.rs index 5e417efb4b5..e8081005d4a 100644 --- a/src/test/run-pass/const-region-ptrs-noncopy.rs +++ b/src/test/run-pass/const-region-ptrs-noncopy.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -type Big = [u64, ..8]; +type Big = [u64; 8]; struct Pair<'a> { a: int, b: &'a Big } const x: &'static Big = &([13, 14, 10, 13, 11, 14, 14, 15]); const y: &'static Pair<'static> = &Pair {a: 15, b: x}; diff --git a/src/test/run-pass/const-str-ptr.rs b/src/test/run-pass/const-str-ptr.rs index 47d59eca263..d6f0296619a 100644 --- a/src/test/run-pass/const-str-ptr.rs +++ b/src/test/run-pass/const-str-ptr.rs @@ -10,8 +10,8 @@ use std::{str, string}; -const A: [u8, ..2] = ['h' as u8, 'i' as u8]; -const B: &'static [u8, ..2] = &A; +const A: [u8; 2] = ['h' as u8, 'i' as u8]; +const B: &'static [u8; 2] = &A; const C: *const u8 = B as *const u8; pub fn main() { diff --git a/src/test/run-pass/const-vecs-and-slices.rs b/src/test/run-pass/const-vecs-and-slices.rs index 1a2a3e36e87..26874b9f9d5 100644 --- a/src/test/run-pass/const-vecs-and-slices.rs +++ b/src/test/run-pass/const-vecs-and-slices.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -static x : [int, ..4] = [1,2,3,4]; +static x : [int; 4] = [1,2,3,4]; static y : &'static [int] = &[1,2,3,4]; -static z : &'static [int, ..4] = &[1,2,3,4]; +static z : &'static [int; 4] = &[1,2,3,4]; static zz : &'static [int] = &[1,2,3,4]; pub fn main() { diff --git a/src/test/run-pass/dst-struct.rs b/src/test/run-pass/dst-struct.rs index bf5b300f7cf..3644ca81d56 100644 --- a/src/test/run-pass/dst-struct.rs +++ b/src/test/run-pass/dst-struct.rs @@ -120,7 +120,7 @@ pub fn main() { assert!((*f2)[1] == 2); // Nested Box. - let f1 : Box> = box Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] }; + let f1 : Box> = box Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] }; foo(&*f1); let f2 : Box> = f1; foo(&*f2); diff --git a/src/test/run-pass/enum-vec-initializer.rs b/src/test/run-pass/enum-vec-initializer.rs index 0256420ac4c..d436916c279 100644 --- a/src/test/run-pass/enum-vec-initializer.rs +++ b/src/test/run-pass/enum-vec-initializer.rs @@ -16,9 +16,9 @@ const BAR:uint = Flopsy::Bunny as uint; const BAR2:uint = BAR; pub fn main() { - let _v = [0i, .. Flopsy::Bunny as uint]; - let _v = [0i, .. BAR]; - let _v = [0i, .. BAR2]; + let _v = [0i; Flopsy::Bunny as uint]; + let _v = [0i; BAR]; + let _v = [0i; BAR2]; const BAR3:uint = BAR2; - let _v = [0i, .. BAR3]; + let _v = [0i; BAR3]; } diff --git a/src/test/run-pass/evec-internal.rs b/src/test/run-pass/evec-internal.rs index 36b5f86aeda..28b5f781b5c 100644 --- a/src/test/run-pass/evec-internal.rs +++ b/src/test/run-pass/evec-internal.rs @@ -13,16 +13,16 @@ // Doesn't work; needs a design decision. pub fn main() { - let x : [int, ..5] = [1,2,3,4,5]; - let _y : [int, ..5] = [1,2,3,4,5]; + let x : [int; 5] = [1,2,3,4,5]; + let _y : [int; 5] = [1,2,3,4,5]; let mut z = [1,2,3,4,5]; z = x; assert_eq!(z[0], 1); assert_eq!(z[4], 5); - let a : [int, ..5] = [1,1,1,1,1]; - let b : [int, ..5] = [2,2,2,2,2]; - let c : [int, ..5] = [2,2,2,2,3]; + let a : [int; 5] = [1,1,1,1,1]; + let b : [int; 5] = [2,2,2,2,2]; + let c : [int; 5] = [2,2,2,2,3]; log(debug, a); diff --git a/src/test/run-pass/huge-largest-array.rs b/src/test/run-pass/huge-largest-array.rs index d494e0bf40d..e24731546ed 100644 --- a/src/test/run-pass/huge-largest-array.rs +++ b/src/test/run-pass/huge-largest-array.rs @@ -12,10 +12,10 @@ use std::mem::size_of; #[cfg(target_word_size = "32")] pub fn main() { - assert_eq!(size_of::<[u8, ..(1 << 31) - 1]>(), (1 << 31) - 1); + assert_eq!(size_of::<[u8; (1 << 31) - 1]>(), (1 << 31) - 1); } #[cfg(target_word_size = "64")] pub fn main() { - assert_eq!(size_of::<[u8, ..(1 << 47) - 1]>(), (1 << 47) - 1); + assert_eq!(size_of::<[u8; (1 << 47) - 1]>(), (1 << 47) - 1); } diff --git a/src/test/run-pass/issue-11205.rs b/src/test/run-pass/issue-11205.rs index ea138311f19..549a70f19e3 100644 --- a/src/test/run-pass/issue-11205.rs +++ b/src/test/run-pass/issue-11205.rs @@ -12,22 +12,22 @@ trait Foo {} impl Foo for int {} -fn foo(_: [&Foo, ..2]) {} +fn foo(_: [&Foo; 2]) {} fn foos(_: &[&Foo]) {} fn foog(_: &[T], _: &[T]) {} -fn bar(_: [Box, ..2]) {} +fn bar(_: [Box; 2]) {} fn bars(_: &[Box]) {} fn main() { - let x: [&Foo, ..2] = [&1i, &2i]; + let x: [&Foo; 2] = [&1i, &2i]; foo(x); foo([&1i, &2i]); let r = &1i; - let x: [&Foo, ..2] = [r, ..2]; + let x: [&Foo; 2] = [r; 2]; foo(x); - foo([&1i, ..2]); + foo([&1i; 2]); let x: &[&Foo] = &[&1i, &2i]; foos(x); @@ -37,7 +37,7 @@ fn main() { let r = &1i; foog(x, &[r]); - let x: [Box, ..2] = [box 1i, box 2i]; + let x: [Box; 2] = [box 1i, box 2i]; bar(x); bar([box 1i, box 2i]); @@ -49,16 +49,16 @@ fn main() { foog(x, &[box 1i]); struct T<'a> { - t: [&'a (Foo+'a), ..2] + t: [&'a (Foo+'a); 2] } let _n = T { t: [&1i, &2i] }; let r = &1i; let _n = T { - t: [r, ..2] + t: [r; 2] }; - let x: [&Foo, ..2] = [&1i, &2i]; + let x: [&Foo; 2] = [&1i, &2i]; let _n = T { t: x }; @@ -70,11 +70,11 @@ fn main() { t: &[&1i, &2i] }; let r = &1i; - let r: [&Foo, ..2] = [r, ..2]; + let r: [&Foo; 2] = [r; 2]; let _n = F { t: &r }; - let x: [&Foo, ..2] = [&1i, &2i]; + let x: [&Foo; 2] = [&1i, &2i]; let _n = F { t: &x }; @@ -85,7 +85,7 @@ fn main() { let _n = M { t: &[box 1i, box 2i] }; - let x: [Box, ..2] = [box 1i, box 2i]; + let x: [Box; 2] = [box 1i, box 2i]; let _n = M { t: &x }; diff --git a/src/test/run-pass/issue-13259-windows-tcb-trash.rs b/src/test/run-pass/issue-13259-windows-tcb-trash.rs index 0e42bdbd6ad..329ab7c921d 100644 --- a/src/test/run-pass/issue-13259-windows-tcb-trash.rs +++ b/src/test/run-pass/issue-13259-windows-tcb-trash.rs @@ -27,7 +27,7 @@ mod imp { } pub fn test() { - let mut buf: [u16, ..50] = [0, ..50]; + let mut buf: [u16; 50] = [0; 50]; let ret = unsafe { FormatMessageW(0x1000, 0 as *mut c_void, 1, 0x400, buf.as_mut_ptr(), buf.len() as u32, 0 as *const c_void) diff --git a/src/test/run-pass/issue-13763.rs b/src/test/run-pass/issue-13763.rs index 8b2b732415e..81b6892b0f9 100644 --- a/src/test/run-pass/issue-13763.rs +++ b/src/test/run-pass/issue-13763.rs @@ -12,9 +12,9 @@ use std::u8; const NUM: uint = u8::BITS as uint; -struct MyStruct { nums: [uint, ..8] } +struct MyStruct { nums: [uint; 8] } fn main() { - let _s = MyStruct { nums: [0, ..NUM] }; + let _s = MyStruct { nums: [0; NUM] }; } diff --git a/src/test/run-pass/issue-13837.rs b/src/test/run-pass/issue-13837.rs index 221115a0869..f62a45277b2 100644 --- a/src/test/run-pass/issue-13837.rs +++ b/src/test/run-pass/issue-13837.rs @@ -8,6 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -static TEST_VALUE : *const [int, ..2] = 0x1234 as *const [int, ..2]; +static TEST_VALUE : *const [int; 2] = 0x1234 as *const [int; 2]; fn main() {} diff --git a/src/test/run-pass/issue-14940.rs b/src/test/run-pass/issue-14940.rs index cef09af1fcf..d815620c969 100644 --- a/src/test/run-pass/issue-14940.rs +++ b/src/test/run-pass/issue-14940.rs @@ -15,7 +15,7 @@ fn main() { let args = os::args(); if args.len() > 1 { let mut out = stdio::stdout(); - out.write(&['a' as u8, ..128 * 1024]).unwrap(); + out.write(&['a' as u8; 128 * 1024]).unwrap(); } else { let out = Command::new(args[0].as_slice()).arg("child").output(); let out = out.unwrap(); diff --git a/src/test/run-pass/issue-15673.rs b/src/test/run-pass/issue-15673.rs index 051d98aa1d8..e66788a2c00 100644 --- a/src/test/run-pass/issue-15673.rs +++ b/src/test/run-pass/issue-15673.rs @@ -10,6 +10,6 @@ use std::iter::AdditiveIterator; fn main() { - let x: [u64, ..3] = [1, 2, 3]; + let x: [u64; 3] = [1, 2, 3]; assert_eq!(6, range(0, 3).map(|i| x[i]).sum()); } diff --git a/src/test/run-pass/issue-17302.rs b/src/test/run-pass/issue-17302.rs index 50583c7d127..b2abf2d2b1a 100644 --- a/src/test/run-pass/issue-17302.rs +++ b/src/test/run-pass/issue-17302.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -static mut DROPPED: [bool, ..2] = [false, false]; +static mut DROPPED: [bool; 2] = [false, false]; struct A(uint); struct Foo { _a: A, _b: int } diff --git a/src/test/run-pass/issue-17877.rs b/src/test/run-pass/issue-17877.rs index 51db2f05959..827e6a10abd 100644 --- a/src/test/run-pass/issue-17877.rs +++ b/src/test/run-pass/issue-17877.rs @@ -9,11 +9,11 @@ // except according to those terms. fn main() { - assert_eq!(match [0u8, ..1024] { + assert_eq!(match [0u8; 1024] { _ => 42u, }, 42u); - assert_eq!(match [0u8, ..1024] { + assert_eq!(match [0u8; 1024] { [1, _..] => 0u, [0, _..] => 1u, _ => 2u diff --git a/src/test/run-pass/issue-18425.rs b/src/test/run-pass/issue-18425.rs index 6bb244bf88f..f61530c7418 100644 --- a/src/test/run-pass/issue-18425.rs +++ b/src/test/run-pass/issue-18425.rs @@ -12,5 +12,5 @@ // expression with a count of 1 and a non-Copy element type. fn main() { - let _ = [box 1u, ..1]; + let _ = [box 1u; 1]; } diff --git a/src/test/run-pass/issue-19244.rs b/src/test/run-pass/issue-19244.rs index d42bda6cd5d..3ee5ce9bff9 100644 --- a/src/test/run-pass/issue-19244.rs +++ b/src/test/run-pass/issue-19244.rs @@ -13,8 +13,8 @@ const STRUCT: MyStruct = MyStruct { field: 42 }; const TUP: (uint,) = (43,); fn main() { - let a = [0i, ..STRUCT.field]; - let b = [0i, ..TUP.0]; + let a = [0i; STRUCT.field]; + let b = [0i; TUP.0]; assert!(a.len() == 42); assert!(b.len() == 43); diff --git a/src/test/run-pass/issue-2904.rs b/src/test/run-pass/issue-2904.rs index 1dc1587ff2f..f87eb46d553 100644 --- a/src/test/run-pass/issue-2904.rs +++ b/src/test/run-pass/issue-2904.rs @@ -63,7 +63,7 @@ fn read_board_grid(mut input: rdr) -> Vec> { let mut input: &mut io::Reader = &mut input; let mut grid = Vec::new(); - let mut line = [0, ..10]; + let mut line = [0; 10]; input.read(&mut line); let mut row = Vec::new(); for c in line.iter() { diff --git a/src/test/run-pass/issue-3656.rs b/src/test/run-pass/issue-3656.rs index 53157ce7546..8a39676ca17 100644 --- a/src/test/run-pass/issue-3656.rs +++ b/src/test/run-pass/issue-3656.rs @@ -16,7 +16,7 @@ extern crate libc; use libc::{c_uint, uint32_t, c_void}; pub struct KEYGEN { - hash_algorithm: [c_uint, ..2], + hash_algorithm: [c_uint; 2], count: uint32_t, salt: *const c_void, salt_size: uint32_t, diff --git a/src/test/run-pass/issue-4387.rs b/src/test/run-pass/issue-4387.rs index 447bf3b4b26..43948ef4a45 100644 --- a/src/test/run-pass/issue-4387.rs +++ b/src/test/run-pass/issue-4387.rs @@ -9,5 +9,5 @@ // except according to those terms. pub fn main() { - let _foo = [0i, ..2*4]; + let _foo = [0i; 2*4]; } diff --git a/src/test/run-pass/issue-5688.rs b/src/test/run-pass/issue-5688.rs index 0a13e001fab..7c8940aafbf 100644 --- a/src/test/run-pass/issue-5688.rs +++ b/src/test/run-pass/issue-5688.rs @@ -13,7 +13,7 @@ ...should print &[1, 2, 3] but instead prints something like &[4492532864, 24]. It is pretty evident that the compiler messed up -with the representation of [int, ..n] and [int] somehow, or at least +with the representation of [int; n] and [int] somehow, or at least failed to typecheck correctly. */ diff --git a/src/test/run-pass/issue-7784.rs b/src/test/run-pass/issue-7784.rs index 666847517ef..b936eb322fc 100644 --- a/src/test/run-pass/issue-7784.rs +++ b/src/test/run-pass/issue-7784.rs @@ -10,10 +10,10 @@ #![feature(advanced_slice_patterns)] -fn foo + Clone>([x, y, z]: [T, ..3]) -> (T, T, T) { +fn foo + Clone>([x, y, z]: [T; 3]) -> (T, T, T) { (x.clone(), x.clone() + y.clone(), x + y + z) } -fn bar(a: &'static str, b: &'static str) -> [&'static str, ..4] { +fn bar(a: &'static str, b: &'static str) -> [&'static str; 4] { [a, b, b, a] } diff --git a/src/test/run-pass/issue-9942.rs b/src/test/run-pass/issue-9942.rs index b9410ffdb43..321e22cd19c 100644 --- a/src/test/run-pass/issue-9942.rs +++ b/src/test/run-pass/issue-9942.rs @@ -9,5 +9,5 @@ // except according to those terms. pub fn main() { - const S: uint = 23 as uint; [0i, ..S]; () + const S: uint = 23 as uint; [0i; S]; () } diff --git a/src/test/run-pass/macro-invocation-in-count-expr-fixed-array-type.rs b/src/test/run-pass/macro-invocation-in-count-expr-fixed-array-type.rs index 4c124d85eee..ecd7c0458f7 100644 --- a/src/test/run-pass/macro-invocation-in-count-expr-fixed-array-type.rs +++ b/src/test/run-pass/macro-invocation-in-count-expr-fixed-array-type.rs @@ -15,5 +15,5 @@ macro_rules! four ( ); fn main() { - let _x: [u16, ..four!()]; + let _x: [u16; four!()]; } diff --git a/src/test/run-pass/match-arm-statics.rs b/src/test/run-pass/match-arm-statics.rs index 400aab64b4c..db512adc011 100644 --- a/src/test/run-pass/match-arm-statics.rs +++ b/src/test/run-pass/match-arm-statics.rs @@ -64,7 +64,7 @@ fn issue_6533() { } fn issue_13626() { - const VAL: [u8, ..1] = [0]; + const VAL: [u8; 1] = [0]; match [1] { VAL => unreachable!(), _ => () diff --git a/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs b/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs index 00319d57f8d..9ae7f49c75a 100644 --- a/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs +++ b/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs @@ -38,7 +38,7 @@ impl<'a> MyWriter for &'a mut [u8] { } fn main() { - let mut buf = [0_u8, .. 6]; + let mut buf = [0_u8; 6]; { let mut writer = buf.as_mut_slice(); diff --git a/src/test/run-pass/method-two-traits-distinguished-via-where-clause.rs b/src/test/run-pass/method-two-traits-distinguished-via-where-clause.rs index 986236fb6f9..fbecb6851b6 100644 --- a/src/test/run-pass/method-two-traits-distinguished-via-where-clause.rs +++ b/src/test/run-pass/method-two-traits-distinguished-via-where-clause.rs @@ -28,7 +28,7 @@ impl B for *const [T] { } fn main() { - let x: [int, ..4] = [1,2,3,4]; + let x: [int; 4] = [1,2,3,4]; let xptr = x.as_slice() as *const _; xptr.foo(); } diff --git a/src/test/run-pass/mutability-inherits-through-fixed-length-vec.rs b/src/test/run-pass/mutability-inherits-through-fixed-length-vec.rs index ef0bc75c326..bf926a6c48a 100644 --- a/src/test/run-pass/mutability-inherits-through-fixed-length-vec.rs +++ b/src/test/run-pass/mutability-inherits-through-fixed-length-vec.rs @@ -9,13 +9,13 @@ // except according to those terms. fn test1() { - let mut ints = [0i, ..32]; + let mut ints = [0i; 32]; ints[0] += 1; assert_eq!(ints[0], 1); } fn test2() { - let mut ints = [0i, ..32]; + let mut ints = [0i; 32]; for i in ints.iter_mut() { *i += 22; } for i in ints.iter() { assert!(*i == 22); } } diff --git a/src/test/run-pass/new-style-fixed-length-vec.rs b/src/test/run-pass/new-style-fixed-length-vec.rs index a689fb0cf7c..e06461daed0 100644 --- a/src/test/run-pass/new-style-fixed-length-vec.rs +++ b/src/test/run-pass/new-style-fixed-length-vec.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -static FOO: [int, ..3] = [1, 2, 3]; +static FOO: [int; 3] = [1, 2, 3]; pub fn main() { println!("{} {} {}", FOO[0], FOO[1], FOO[2]); diff --git a/src/test/run-pass/nullable-pointer-iotareduction.rs b/src/test/run-pass/nullable-pointer-iotareduction.rs index da1ad094df6..2660de619e9 100644 --- a/src/test/run-pass/nullable-pointer-iotareduction.rs +++ b/src/test/run-pass/nullable-pointer-iotareduction.rs @@ -20,7 +20,7 @@ use std::{option, mem}; // trying to get assert failure messages that at least identify which case // failed. -enum E { Thing(int, T), Nothing((), ((), ()), [i8, ..0]) } +enum E { Thing(int, T), Nothing((), ((), ()), [i8; 0]) } impl E { fn is_none(&self) -> bool { match *self { @@ -54,7 +54,7 @@ macro_rules! check_fancy { check_fancy!($e: $T, |ptr| assert!(*ptr == $e)); }}; ($e:expr: $T:ty, |$v:ident| $chk:expr) => {{ - assert!(E::Nothing::<$T>((), ((), ()), [23i8, ..0]).is_none()); + assert!(E::Nothing::<$T>((), ((), ()), [23i8; 0]).is_none()); let e = $e; let t_ = E::Thing::<$T>(23, e); match t_.get_ref() { diff --git a/src/test/run-pass/nullable-pointer-size.rs b/src/test/run-pass/nullable-pointer-size.rs index 5708310abad..afc22be38b8 100644 --- a/src/test/run-pass/nullable-pointer-size.rs +++ b/src/test/run-pass/nullable-pointer-size.rs @@ -12,7 +12,7 @@ use std::mem; -enum E { Thing(int, T), Nothing((), ((), ()), [i8, ..0]) } +enum E { Thing(int, T), Nothing((), ((), ()), [i8; 0]) } struct S(int, T); // These are macros so we get useful assert messages. diff --git a/src/test/run-pass/order-drop-with-match.rs b/src/test/run-pass/order-drop-with-match.rs index 9a76beac9e5..a866be43a05 100644 --- a/src/test/run-pass/order-drop-with-match.rs +++ b/src/test/run-pass/order-drop-with-match.rs @@ -14,7 +14,7 @@ // in ORDER matching up to when it ran. // Correct order is: matched, inner, outer -static mut ORDER: [uint, ..3] = [0, 0, 0]; +static mut ORDER: [uint; 3] = [0, 0, 0]; static mut INDEX: uint = 0; struct A; diff --git a/src/test/run-pass/out-of-stack-new-thread-no-split.rs b/src/test/run-pass/out-of-stack-new-thread-no-split.rs index 419d9b5d824..674d0dc86da 100644 --- a/src/test/run-pass/out-of-stack-new-thread-no-split.rs +++ b/src/test/run-pass/out-of-stack-new-thread-no-split.rs @@ -27,7 +27,7 @@ pub fn black_box(dummy: T) { unsafe { asm!("" : : "r"(&dummy)) } } #[no_stack_check] fn recurse() { - let buf = [0i, ..10]; + let buf = [0i; 10]; black_box(buf); recurse(); } diff --git a/src/test/run-pass/out-of-stack-no-split.rs b/src/test/run-pass/out-of-stack-no-split.rs index ecb93cc6f8c..79926776abf 100644 --- a/src/test/run-pass/out-of-stack-no-split.rs +++ b/src/test/run-pass/out-of-stack-no-split.rs @@ -28,7 +28,7 @@ pub fn black_box(dummy: T) { unsafe { asm!("" : : "r"(&dummy)) } } #[no_stack_check] fn recurse() { - let buf = [0i, ..10]; + let buf = [0i; 10]; black_box(buf); recurse(); } diff --git a/src/test/run-pass/out-of-stack.rs b/src/test/run-pass/out-of-stack.rs index 81e75ba2cd5..1594cca89e5 100644 --- a/src/test/run-pass/out-of-stack.rs +++ b/src/test/run-pass/out-of-stack.rs @@ -22,7 +22,7 @@ use std::os; pub fn black_box(dummy: T) { unsafe { asm!("" : : "r"(&dummy)) } } fn silent_recurse() { - let buf = [0i, ..1000]; + let buf = [0i; 1000]; black_box(buf); silent_recurse(); } diff --git a/src/test/run-pass/packed-struct-generic-layout.rs b/src/test/run-pass/packed-struct-generic-layout.rs index 999e4aeeb59..004a3022018 100644 --- a/src/test/run-pass/packed-struct-generic-layout.rs +++ b/src/test/run-pass/packed-struct-generic-layout.rs @@ -20,7 +20,7 @@ struct S { pub fn main() { unsafe { let s = S { a: 0xff_ff_ff_ffu32, b: 1, c: 0xaa_aa_aa_aa as i32 }; - let transd : [u8, .. 9] = mem::transmute(s); + let transd : [u8; 9] = mem::transmute(s); // Don't worry about endianness, the numbers are palindromic. assert!(transd == [0xff, 0xff, 0xff, 0xff, @@ -29,7 +29,7 @@ pub fn main() { let s = S { a: 1u8, b: 2u8, c: 0b10000001_10000001 as i16}; - let transd : [u8, .. 4] = mem::transmute(s); + let transd : [u8; 4] = mem::transmute(s); // Again, no endianness problems. assert!(transd == [1, 2, 0b10000001, 0b10000001]); diff --git a/src/test/run-pass/packed-struct-layout.rs b/src/test/run-pass/packed-struct-layout.rs index b4fbf0820cd..9e94502a92a 100644 --- a/src/test/run-pass/packed-struct-layout.rs +++ b/src/test/run-pass/packed-struct-layout.rs @@ -13,7 +13,7 @@ use std::mem; #[repr(packed)] struct S4 { a: u8, - b: [u8, .. 3], + b: [u8; 3], } #[repr(packed)] @@ -25,11 +25,11 @@ struct S5 { pub fn main() { unsafe { let s4 = S4 { a: 1, b: [2,3,4] }; - let transd : [u8, .. 4] = mem::transmute(s4); + let transd : [u8; 4] = mem::transmute(s4); assert!(transd == [1, 2, 3, 4]); let s5 = S5 { a: 1, b: 0xff_00_00_ff }; - let transd : [u8, .. 5] = mem::transmute(s5); + let transd : [u8; 5] = mem::transmute(s5); // Don't worry about endianness, the u32 is palindromic. assert!(transd == [1, 0xff, 0, 0, 0xff]); } diff --git a/src/test/run-pass/packed-struct-size.rs b/src/test/run-pass/packed-struct-size.rs index 9472fd4ce38..846d51e2e7e 100644 --- a/src/test/run-pass/packed-struct-size.rs +++ b/src/test/run-pass/packed-struct-size.rs @@ -14,7 +14,7 @@ use std::mem; #[repr(packed)] struct S4 { a: u8, - b: [u8, .. 3], + b: [u8; 3], } #[repr(packed)] diff --git a/src/test/run-pass/packed-struct-vec.rs b/src/test/run-pass/packed-struct-vec.rs index 59bb5678b69..d2121aa7752 100644 --- a/src/test/run-pass/packed-struct-vec.rs +++ b/src/test/run-pass/packed-struct-vec.rs @@ -22,9 +22,9 @@ struct Foo { impl Copy for Foo {} pub fn main() { - let foos = [Foo { bar: 1, baz: 2 }, .. 10]; + let foos = [Foo { bar: 1, baz: 2 }; 10]; - assert_eq!(mem::size_of::<[Foo, .. 10]>(), 90); + assert_eq!(mem::size_of::<[Foo; 10]>(), 90); for i in range(0u, 10) { assert_eq!(foos[i], Foo { bar: 1, baz: 2}); diff --git a/src/test/run-pass/packed-tuple-struct-layout.rs b/src/test/run-pass/packed-tuple-struct-layout.rs index 5fb43503ccb..c41d678b0f5 100644 --- a/src/test/run-pass/packed-tuple-struct-layout.rs +++ b/src/test/run-pass/packed-tuple-struct-layout.rs @@ -11,7 +11,7 @@ use std::mem; #[repr(packed)] -struct S4(u8,[u8, .. 3]); +struct S4(u8,[u8; 3]); #[repr(packed)] struct S5(u8,u32); @@ -19,11 +19,11 @@ struct S5(u8,u32); pub fn main() { unsafe { let s4 = S4(1, [2,3,4]); - let transd : [u8, .. 4] = mem::transmute(s4); + let transd : [u8; 4] = mem::transmute(s4); assert!(transd == [1, 2, 3, 4]); let s5 = S5(1, 0xff_00_00_ff); - let transd : [u8, .. 5] = mem::transmute(s5); + let transd : [u8; 5] = mem::transmute(s5); // Don't worry about endianness, the u32 is palindromic. assert!(transd == [1, 0xff, 0, 0, 0xff]); } diff --git a/src/test/run-pass/packed-tuple-struct-size.rs b/src/test/run-pass/packed-tuple-struct-size.rs index 8967b07ca88..a0b88ea53c5 100644 --- a/src/test/run-pass/packed-tuple-struct-size.rs +++ b/src/test/run-pass/packed-tuple-struct-size.rs @@ -12,7 +12,7 @@ use std::mem; #[repr(packed)] -struct S4(u8,[u8, .. 3]); +struct S4(u8,[u8; 3]); #[repr(packed)] struct S5(u8, u32); diff --git a/src/test/run-pass/regions-dependent-addr-of.rs b/src/test/run-pass/regions-dependent-addr-of.rs index 79f8ca48882..41396ef01be 100644 --- a/src/test/run-pass/regions-dependent-addr-of.rs +++ b/src/test/run-pass/regions-dependent-addr-of.rs @@ -18,7 +18,7 @@ struct A { struct B { v1: int, - v2: [int, ..3], + v2: [int; 3], v3: Vec , v4: C, v5: Box, diff --git a/src/test/run-pass/repeat-expr-in-static.rs b/src/test/run-pass/repeat-expr-in-static.rs index 9955673bb0b..a53f1da4ce6 100644 --- a/src/test/run-pass/repeat-expr-in-static.rs +++ b/src/test/run-pass/repeat-expr-in-static.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -static FOO: [int, ..4] = [32, ..4]; -static BAR: [int, ..4] = [32, 32, 32, 32]; +static FOO: [int; 4] = [32; 4]; +static BAR: [int; 4] = [32, 32, 32, 32]; pub fn main() { assert!(FOO == BAR); diff --git a/src/test/run-pass/repeated-vector-syntax.rs b/src/test/run-pass/repeated-vector-syntax.rs index 9c369c0d770..0781822cb74 100644 --- a/src/test/run-pass/repeated-vector-syntax.rs +++ b/src/test/run-pass/repeated-vector-syntax.rs @@ -11,8 +11,8 @@ #![feature(slicing_syntax)] pub fn main() { - let x = [ [true], ..512 ]; - let y = [ 0i, ..1 ]; + let x = [ [true]; 512 ]; + let y = [ 0i; 1 ]; print!("["); for xi in x.iter() { diff --git a/src/test/run-pass/uninit-empty-types.rs b/src/test/run-pass/uninit-empty-types.rs index 005205353fc..c2bd738b8a4 100644 --- a/src/test/run-pass/uninit-empty-types.rs +++ b/src/test/run-pass/uninit-empty-types.rs @@ -18,6 +18,6 @@ struct Foo; pub fn main() { unsafe { let _x: Foo = mem::uninitialized(); - let _x: [Foo, ..2] = mem::uninitialized(); + let _x: [Foo; 2] = mem::uninitialized(); } } diff --git a/src/test/run-pass/unsized3.rs b/src/test/run-pass/unsized3.rs index e5e6ce6e76b..271f5817c9e 100644 --- a/src/test/run-pass/unsized3.rs +++ b/src/test/run-pass/unsized3.rs @@ -60,7 +60,7 @@ pub fn main() { unsafe { struct Foo_ { - f: [T, ..3] + f: [T; 3] } let data = box Foo_{f: [1i32, 2, 3] }; @@ -72,7 +72,7 @@ pub fn main() { struct Baz_ { f1: uint, - f2: [u8, ..5], + f2: [u8; 5], } let data = box Baz_{ f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] }; diff --git a/src/test/run-pass/variadic-ffi.rs b/src/test/run-pass/variadic-ffi.rs index aa71de2123c..f8eef988561 100644 --- a/src/test/run-pass/variadic-ffi.rs +++ b/src/test/run-pass/variadic-ffi.rs @@ -19,7 +19,7 @@ extern { } unsafe fn check(expected: &str, f: |*mut c_char| -> T) { - let mut x = [0 as c_char, ..50]; + let mut x = [0 as c_char; 50]; f(&mut x[0] as *mut c_char); let res = CString::new(&x[0], false); assert_eq!(expected, res.as_str().unwrap()); diff --git a/src/test/run-pass/vec-dst.rs b/src/test/run-pass/vec-dst.rs index d8bf0a5c627..4a36231e72b 100644 --- a/src/test/run-pass/vec-dst.rs +++ b/src/test/run-pass/vec-dst.rs @@ -9,9 +9,9 @@ // except according to those terms. pub fn main() { - // Tests for indexing into box/& [T, ..n] - let x: [int, ..3] = [1, 2, 3]; - let mut x: Box<[int, ..3]> = box x; + // Tests for indexing into box/& [T; n] + let x: [int; 3] = [1, 2, 3]; + let mut x: Box<[int; 3]> = box x; assert!(x[0] == 1); assert!(x[1] == 2); assert!(x[2] == 3); @@ -20,8 +20,8 @@ pub fn main() { assert!(x[1] == 45); assert!(x[2] == 3); - let mut x: [int, ..3] = [1, 2, 3]; - let x: &mut [int, ..3] = &mut x; + let mut x: [int; 3] = [1, 2, 3]; + let x: &mut [int; 3] = &mut x; assert!(x[0] == 1); assert!(x[1] == 2); assert!(x[2] == 3); diff --git a/src/test/run-pass/vec-fixed-length.rs b/src/test/run-pass/vec-fixed-length.rs index 05a7388b5e2..20e1becd008 100644 --- a/src/test/run-pass/vec-fixed-length.rs +++ b/src/test/run-pass/vec-fixed-length.rs @@ -11,17 +11,17 @@ use std::mem::size_of; pub fn main() { - let x: [int, ..4] = [1, 2, 3, 4]; + let x: [int; 4] = [1, 2, 3, 4]; assert_eq!(x[0], 1); assert_eq!(x[1], 2); assert_eq!(x[2], 3); assert_eq!(x[3], 4); - assert_eq!(size_of::<[u8, ..4]>(), 4u); + assert_eq!(size_of::<[u8; 4]>(), 4u); // FIXME #10183 // FIXME #18069 //if cfg!(target_word_size = "64") { - // assert_eq!(size_of::<[u8, ..(1 << 32)]>(), (1u << 32)); + // assert_eq!(size_of::<[u8; (1 << 32)]>(), (1u << 32)); //} } diff --git a/src/test/run-pass/vec-repeat-with-cast.rs b/src/test/run-pass/vec-repeat-with-cast.rs index 18ccd8c96ab..97a443cb3b8 100644 --- a/src/test/run-pass/vec-repeat-with-cast.rs +++ b/src/test/run-pass/vec-repeat-with-cast.rs @@ -8,4 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub fn main() { let _a = [0i, ..1 as uint]; } +pub fn main() { let _a = [0i; 1 as uint]; } diff --git a/src/test/run-pass/vector-sort-panic-safe.rs b/src/test/run-pass/vector-sort-panic-safe.rs index c969e66957c..fe89c7532ee 100644 --- a/src/test/run-pass/vector-sort-panic-safe.rs +++ b/src/test/run-pass/vector-sort-panic-safe.rs @@ -14,7 +14,7 @@ use std::rand::{task_rng, Rng, Rand}; const REPEATS: uint = 5; const MAX_LEN: uint = 32; -static drop_counts: [AtomicUint, .. MAX_LEN] = +static drop_counts: [AtomicUint; MAX_LEN] = // FIXME #5244: AtomicUint is not Copy. [ INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, From e0d44386d334e13677e2d43ad9365d6b24350780 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 16 Dec 2014 18:38:06 +0200 Subject: [PATCH 42/58] rustc: use Ty instead of passing ty::sty around. --- src/librustc/metadata/tyencode.rs | 197 +++++++++++++------------- src/librustc/middle/infer/coercion.rs | 110 +++++++------- src/librustc/middle/ty_fold.rs | 112 +++++++-------- src/librustc_typeck/check/closure.rs | 75 +++++----- src/librustc_typeck/check/mod.rs | 51 +++---- src/librustc_typeck/check/wf.rs | 6 +- 6 files changed, 259 insertions(+), 292 deletions(-) diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 5d7d85d4679..ce63c467822 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -55,7 +55,103 @@ pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'t None => {} } let pos = w.tell().unwrap(); - enc_sty(w, cx, &t.sty); + + match t.sty { + ty::ty_bool => mywrite!(w, "b"), + ty::ty_char => mywrite!(w, "c"), + ty::ty_int(t) => { + match t { + ast::TyI => mywrite!(w, "i"), + ast::TyI8 => mywrite!(w, "MB"), + ast::TyI16 => mywrite!(w, "MW"), + ast::TyI32 => mywrite!(w, "ML"), + ast::TyI64 => mywrite!(w, "MD") + } + } + ty::ty_uint(t) => { + match t { + ast::TyU => mywrite!(w, "u"), + ast::TyU8 => mywrite!(w, "Mb"), + ast::TyU16 => mywrite!(w, "Mw"), + ast::TyU32 => mywrite!(w, "Ml"), + ast::TyU64 => mywrite!(w, "Md") + } + } + ty::ty_float(t) => { + match t { + ast::TyF32 => mywrite!(w, "Mf"), + ast::TyF64 => mywrite!(w, "MF"), + } + } + ty::ty_enum(def, ref substs) => { + mywrite!(w, "t[{}|", (cx.ds)(def)); + enc_substs(w, cx, substs); + mywrite!(w, "]"); + } + ty::ty_trait(box ty::TyTrait { ref principal, + ref bounds }) => { + mywrite!(w, "x["); + enc_trait_ref(w, cx, &principal.0); + enc_existential_bounds(w, cx, bounds); + mywrite!(w, "]"); + } + ty::ty_tup(ref ts) => { + mywrite!(w, "T["); + for t in ts.iter() { enc_ty(w, cx, *t); } + mywrite!(w, "]"); + } + ty::ty_uniq(typ) => { mywrite!(w, "~"); enc_ty(w, cx, typ); } + ty::ty_ptr(mt) => { mywrite!(w, "*"); enc_mt(w, cx, mt); } + ty::ty_rptr(r, mt) => { + mywrite!(w, "&"); + enc_region(w, cx, r); + enc_mt(w, cx, mt); + } + ty::ty_vec(t, sz) => { + mywrite!(w, "V"); + enc_ty(w, cx, t); + mywrite!(w, "/"); + match sz { + Some(n) => mywrite!(w, "{}|", n), + None => mywrite!(w, "|"), + } + } + ty::ty_str => { + mywrite!(w, "v"); + } + ty::ty_closure(ref f) => { + mywrite!(w, "f"); + enc_closure_ty(w, cx, &**f); + } + ty::ty_bare_fn(ref f) => { + mywrite!(w, "F"); + enc_bare_fn_ty(w, cx, f); + } + ty::ty_infer(_) => { + cx.diag.handler().bug("cannot encode inference variable types"); + } + ty::ty_param(ParamTy {space, idx: id, def_id: did}) => { + mywrite!(w, "p{}|{}|{}|", (cx.ds)(did), id, space.to_uint()) + } + ty::ty_struct(def, ref substs) => { + mywrite!(w, "a[{}|", (cx.ds)(def)); + enc_substs(w, cx, substs); + mywrite!(w, "]"); + } + ty::ty_unboxed_closure(def, region, ref substs) => { + mywrite!(w, "k[{}|", (cx.ds)(def)); + enc_region(w, cx, region); + enc_substs(w, cx, substs); + mywrite!(w, "]"); + } + ty::ty_err => { + mywrite!(w, "e"); + } + ty::ty_open(_) => { + cx.diag.handler().bug("unexpected type in enc_sty (ty_open)"); + } + } + let end = w.tell().unwrap(); let len = end - pos; fn estimate_sz(u: u64) -> u64 { @@ -214,105 +310,6 @@ pub fn enc_trait_store(w: &mut SeekableMemWriter, cx: &ctxt, s: ty::TraitStore) } } -fn enc_sty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, - st: &ty::sty<'tcx>) { - match *st { - ty::ty_bool => mywrite!(w, "b"), - ty::ty_char => mywrite!(w, "c"), - ty::ty_int(t) => { - match t { - ast::TyI => mywrite!(w, "i"), - ast::TyI8 => mywrite!(w, "MB"), - ast::TyI16 => mywrite!(w, "MW"), - ast::TyI32 => mywrite!(w, "ML"), - ast::TyI64 => mywrite!(w, "MD") - } - } - ty::ty_uint(t) => { - match t { - ast::TyU => mywrite!(w, "u"), - ast::TyU8 => mywrite!(w, "Mb"), - ast::TyU16 => mywrite!(w, "Mw"), - ast::TyU32 => mywrite!(w, "Ml"), - ast::TyU64 => mywrite!(w, "Md") - } - } - ty::ty_float(t) => { - match t { - ast::TyF32 => mywrite!(w, "Mf"), - ast::TyF64 => mywrite!(w, "MF"), - } - } - ty::ty_enum(def, ref substs) => { - mywrite!(w, "t[{}|", (cx.ds)(def)); - enc_substs(w, cx, substs); - mywrite!(w, "]"); - } - ty::ty_trait(box ty::TyTrait { ref principal, - ref bounds }) => { - mywrite!(w, "x["); - enc_trait_ref(w, cx, &principal.0); - enc_existential_bounds(w, cx, bounds); - mywrite!(w, "]"); - } - ty::ty_tup(ref ts) => { - mywrite!(w, "T["); - for t in ts.iter() { enc_ty(w, cx, *t); } - mywrite!(w, "]"); - } - ty::ty_uniq(typ) => { mywrite!(w, "~"); enc_ty(w, cx, typ); } - ty::ty_ptr(mt) => { mywrite!(w, "*"); enc_mt(w, cx, mt); } - ty::ty_rptr(r, mt) => { - mywrite!(w, "&"); - enc_region(w, cx, r); - enc_mt(w, cx, mt); - } - ty::ty_vec(t, sz) => { - mywrite!(w, "V"); - enc_ty(w, cx, t); - mywrite!(w, "/"); - match sz { - Some(n) => mywrite!(w, "{}|", n), - None => mywrite!(w, "|"), - } - } - ty::ty_str => { - mywrite!(w, "v"); - } - ty::ty_closure(ref f) => { - mywrite!(w, "f"); - enc_closure_ty(w, cx, &**f); - } - ty::ty_bare_fn(ref f) => { - mywrite!(w, "F"); - enc_bare_fn_ty(w, cx, f); - } - ty::ty_infer(_) => { - cx.diag.handler().bug("cannot encode inference variable types"); - } - ty::ty_param(ParamTy {space, idx: id, def_id: did}) => { - mywrite!(w, "p{}|{}|{}|", (cx.ds)(did), id, space.to_uint()) - } - ty::ty_struct(def, ref substs) => { - mywrite!(w, "a[{}|", (cx.ds)(def)); - enc_substs(w, cx, substs); - mywrite!(w, "]"); - } - ty::ty_unboxed_closure(def, region, ref substs) => { - mywrite!(w, "k[{}|", (cx.ds)(def)); - enc_region(w, cx, region); - enc_substs(w, cx, substs); - mywrite!(w, "]"); - } - ty::ty_err => { - mywrite!(w, "e"); - } - ty::ty_open(_) => { - cx.diag.handler().bug("unexpected type in enc_sty (ty_open)"); - } - } -} - fn enc_unsafety(w: &mut SeekableMemWriter, p: ast::Unsafety) { match p { ast::Unsafety::Normal => mywrite!(w, "n"), diff --git a/src/librustc/middle/infer/coercion.rs b/src/librustc/middle/infer/coercion.rs index 805d4532aa1..64bfd138802 100644 --- a/src/librustc/middle/infer/coercion.rs +++ b/src/librustc/middle/infer/coercion.rs @@ -90,8 +90,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { b.repr(self.get_ref().infcx.tcx)); // Consider coercing the subtype to a DST - let unsize = self.unpack_actual_value(a, |sty_a| { - self.coerce_unsized(a, sty_a, b) + let unsize = self.unpack_actual_value(a, |a| { + self.coerce_unsized(a, b) }); if unsize.is_ok() { return unsize; @@ -105,14 +105,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { ty::ty_ptr(mt_b) => { match mt_b.ty.sty { ty::ty_str => { - return self.unpack_actual_value(a, |sty_a| { - self.coerce_unsafe_ptr(a, sty_a, b, ast::MutImmutable) + return self.unpack_actual_value(a, |a| { + self.coerce_unsafe_ptr(a, b, ast::MutImmutable) }); } ty::ty_trait(..) => { - let result = self.unpack_actual_value(a, |sty_a| { - self.coerce_unsafe_object(a, sty_a, b, mt_b.mutbl) + let result = self.unpack_actual_value(a, |a| { + self.coerce_unsafe_object(a, b, mt_b.mutbl) }); match result { @@ -122,8 +122,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } _ => { - return self.unpack_actual_value(a, |sty_a| { - self.coerce_unsafe_ptr(a, sty_a, b, mt_b.mutbl) + return self.unpack_actual_value(a, |a| { + self.coerce_unsafe_ptr(a, b, mt_b.mutbl) }); } }; @@ -132,14 +132,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { ty::ty_rptr(_, mt_b) => { match mt_b.ty.sty { ty::ty_str => { - return self.unpack_actual_value(a, |sty_a| { - self.coerce_borrowed_pointer(a, sty_a, b, ast::MutImmutable) + return self.unpack_actual_value(a, |a| { + self.coerce_borrowed_pointer(a, b, ast::MutImmutable) }); } ty::ty_trait(..) => { - let result = self.unpack_actual_value(a, |sty_a| { - self.coerce_borrowed_object(a, sty_a, b, mt_b.mutbl) + let result = self.unpack_actual_value(a, |a| { + self.coerce_borrowed_object(a, b, mt_b.mutbl) }); match result { @@ -149,8 +149,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } _ => { - return self.unpack_actual_value(a, |sty_a| { - self.coerce_borrowed_pointer(a, sty_a, b, mt_b.mutbl) + return self.unpack_actual_value(a, |a| { + self.coerce_borrowed_pointer(a, b, mt_b.mutbl) }); } }; @@ -160,16 +160,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { store: ty::RegionTraitStore(..), .. }) => { - return self.unpack_actual_value(a, |sty_a| { - self.coerce_borrowed_fn(a, sty_a, b) + return self.unpack_actual_value(a, |a| { + self.coerce_borrowed_fn(a, b) }); } _ => {} } - self.unpack_actual_value(a, |sty_a| { - match *sty_a { + self.unpack_actual_value(a, |a| { + match a.sty { ty::ty_bare_fn(ref a_f) => { // Bare functions are coercible to any closure type. // @@ -194,20 +194,19 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } pub fn unpack_actual_value(&self, a: Ty<'tcx>, f: F) -> T where - F: FnOnce(&ty::sty<'tcx>) -> T, + F: FnOnce(Ty<'tcx>) -> T, { - f(&self.get_ref().infcx.shallow_resolve(a).sty) + f(self.get_ref().infcx.shallow_resolve(a)) } // ~T -> &T or &mut T -> &T (including where T = [U] or str) pub fn coerce_borrowed_pointer(&self, a: Ty<'tcx>, - sty_a: &ty::sty<'tcx>, b: Ty<'tcx>, mutbl_b: ast::Mutability) -> CoerceResult<'tcx> { - debug!("coerce_borrowed_pointer(a={}, sty_a={}, b={})", - a.repr(self.get_ref().infcx.tcx), sty_a, + debug!("coerce_borrowed_pointer(a={}, b={})", + a.repr(self.get_ref().infcx.tcx), b.repr(self.get_ref().infcx.tcx)); // If we have a parameter of type `&M T_a` and the value @@ -220,7 +219,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let coercion = Coercion(self.get_ref().trace.clone()); let r_borrow = self.get_ref().infcx.next_region_var(coercion); - let inner_ty = match *sty_a { + let inner_ty = match a.sty { ty::ty_uniq(_) => return Err(ty::terr_mismatch), ty::ty_rptr(_, mt_a) => mt_a.ty, _ => { @@ -245,11 +244,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // or &Concrete -> &Trait, etc. fn coerce_unsized(&self, a: Ty<'tcx>, - sty_a: &ty::sty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> { - debug!("coerce_unsized(a={}, sty_a={}, b={})", - a.repr(self.get_ref().infcx.tcx), sty_a, + debug!("coerce_unsized(a={}, b={})", + a.repr(self.get_ref().infcx.tcx), b.repr(self.get_ref().infcx.tcx)); // Note, we want to avoid unnecessary unsizing. We don't want to coerce to @@ -259,11 +257,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let sub = Sub(self.get_ref().clone()); - let sty_b = &b.sty; - match (sty_a, sty_b) { + match (&a.sty, &b.sty) { (&ty::ty_rptr(_, ty::mt{ty: t_a, mutbl: mutbl_a}), &ty::ty_rptr(_, mt_b)) => { - self.unpack_actual_value(t_a, |sty_a| { - match self.unsize_ty(t_a, sty_a, mt_b.ty) { + self.unpack_actual_value(t_a, |a| { + match self.unsize_ty(t_a, a, mt_b.ty) { Some((ty, kind)) => { if !can_coerce_mutbls(mutbl_a, mt_b.mutbl) { return Err(ty::terr_mutability); @@ -288,8 +285,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { }) } (&ty::ty_rptr(_, ty::mt{ty: t_a, mutbl: mutbl_a}), &ty::ty_ptr(mt_b)) => { - self.unpack_actual_value(t_a, |sty_a| { - match self.unsize_ty(t_a, sty_a, mt_b.ty) { + self.unpack_actual_value(t_a, |a| { + match self.unsize_ty(t_a, a, mt_b.ty) { Some((ty, kind)) => { if !can_coerce_mutbls(mutbl_a, mt_b.mutbl) { return Err(ty::terr_mutability); @@ -311,8 +308,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { }) } (&ty::ty_uniq(t_a), &ty::ty_uniq(t_b)) => { - self.unpack_actual_value(t_a, |sty_a| { - match self.unsize_ty(t_a, sty_a, t_b) { + self.unpack_actual_value(t_a, |a| { + match self.unsize_ty(t_a, a, t_b) { Some((ty, kind)) => { let ty = ty::mk_uniq(self.get_ref().infcx.tcx, ty); try!(self.get_ref().infcx.try(|_| sub.tys(ty, b))); @@ -336,15 +333,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // E.g., `[T, ..n]` -> `([T], UnsizeLength(n))` fn unsize_ty(&self, ty_a: Ty<'tcx>, - sty_a: &ty::sty<'tcx>, + a: Ty<'tcx>, ty_b: Ty<'tcx>) -> Option<(Ty<'tcx>, ty::UnsizeKind<'tcx>)> { - debug!("unsize_ty(sty_a={}, ty_b={})", sty_a, ty_b.repr(self.get_ref().infcx.tcx)); + debug!("unsize_ty(a={}, ty_b={})", a, ty_b.repr(self.get_ref().infcx.tcx)); let tcx = self.get_ref().infcx.tcx; - self.unpack_actual_value(ty_b, |sty_b| - match (sty_a, sty_b) { + self.unpack_actual_value(ty_b, |b| + match (&a.sty, &b.sty) { (&ty::ty_vec(t_a, Some(len)), &ty::ty_vec(_, None)) => { let ty = ty::mk_vec(tcx, t_a, None); Some((ty, ty::UnsizeLength(len))) @@ -412,44 +409,41 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { fn coerce_borrowed_object(&self, a: Ty<'tcx>, - sty_a: &ty::sty<'tcx>, b: Ty<'tcx>, b_mutbl: ast::Mutability) -> CoerceResult<'tcx> { let tcx = self.get_ref().infcx.tcx; - debug!("coerce_borrowed_object(a={}, sty_a={}, b={}, b_mutbl={})", - a.repr(tcx), sty_a, + debug!("coerce_borrowed_object(a={}, b={}, b_mutbl={})", + a.repr(tcx), b.repr(tcx), b_mutbl); let coercion = Coercion(self.get_ref().trace.clone()); let r_a = self.get_ref().infcx.next_region_var(coercion); - self.coerce_object(a, sty_a, b, b_mutbl, + self.coerce_object(a, b, b_mutbl, |tr| ty::mk_rptr(tcx, r_a, ty::mt{ mutbl: b_mutbl, ty: tr }), || AutoPtr(r_a, b_mutbl, None)) } fn coerce_unsafe_object(&self, a: Ty<'tcx>, - sty_a: &ty::sty<'tcx>, b: Ty<'tcx>, b_mutbl: ast::Mutability) -> CoerceResult<'tcx> { let tcx = self.get_ref().infcx.tcx; - debug!("coerce_unsafe_object(a={}, sty_a={}, b={}, b_mutbl={})", - a.repr(tcx), sty_a, + debug!("coerce_unsafe_object(a={}, b={}, b_mutbl={})", + a.repr(tcx), b.repr(tcx), b_mutbl); - self.coerce_object(a, sty_a, b, b_mutbl, + self.coerce_object(a, b, b_mutbl, |tr| ty::mk_ptr(tcx, ty::mt{ mutbl: b_mutbl, ty: tr }), || AutoUnsafe(b_mutbl, None)) } fn coerce_object(&self, a: Ty<'tcx>, - sty_a: &ty::sty<'tcx>, b: Ty<'tcx>, b_mutbl: ast::Mutability, mk_ty: F, @@ -459,7 +453,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { { let tcx = self.get_ref().infcx.tcx; - match *sty_a { + match a.sty { ty::ty_rptr(_, ty::mt{ty, mutbl}) => match ty.sty { ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => { debug!("mutbl={} b_mutbl={}", mutbl, b_mutbl); @@ -483,14 +477,13 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { pub fn coerce_borrowed_fn(&self, a: Ty<'tcx>, - sty_a: &ty::sty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> { - debug!("coerce_borrowed_fn(a={}, sty_a={}, b={})", - a.repr(self.get_ref().infcx.tcx), sty_a, + debug!("coerce_borrowed_fn(a={}, b={})", + a.repr(self.get_ref().infcx.tcx), b.repr(self.get_ref().infcx.tcx)); - match *sty_a { + match a.sty { ty::ty_bare_fn(ref f) => { self.coerce_from_bare_fn(a, f, b) } @@ -504,7 +497,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { /// `proc`. fn coerce_from_bare_fn(&self, a: Ty<'tcx>, fn_ty_a: &ty::BareFnTy<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> { - self.unpack_actual_value(b, |sty_b| { + self.unpack_actual_value(b, |b| { debug!("coerce_from_bare_fn(a={}, b={})", a.repr(self.get_ref().infcx.tcx), b.repr(self.get_ref().infcx.tcx)); @@ -513,7 +506,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { return self.subtype(a, b); } - let fn_ty_b = match *sty_b { + let fn_ty_b = match b.sty { ty::ty_closure(ref f) => (*f).clone(), _ => return self.subtype(a, b) }; @@ -531,15 +524,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { pub fn coerce_unsafe_ptr(&self, a: Ty<'tcx>, - sty_a: &ty::sty<'tcx>, b: Ty<'tcx>, mutbl_b: ast::Mutability) -> CoerceResult<'tcx> { - debug!("coerce_unsafe_ptr(a={}, sty_a={}, b={})", - a.repr(self.get_ref().infcx.tcx), sty_a, + debug!("coerce_unsafe_ptr(a={}, b={})", + a.repr(self.get_ref().infcx.tcx), b.repr(self.get_ref().infcx.tcx)); - let mt_a = match *sty_a { + let mt_a = match a.sty { ty::ty_rptr(_, mt) | ty::ty_ptr(mt) => mt, _ => { return self.subtype(a, b); diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 71e42a9dbb3..d69ae96d07e 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -82,10 +82,6 @@ pub trait TypeFolder<'tcx> { super_fold_trait_ref(self, t) } - fn fold_sty(&mut self, sty: &ty::sty<'tcx>) -> ty::sty<'tcx> { - super_fold_sty(self, sty) - } - fn fold_substs(&mut self, substs: &subst::Substs<'tcx>) -> subst::Substs<'tcx> { @@ -260,12 +256,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for ty::sty<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::sty<'tcx> { - folder.fold_sty(self) - } -} - impl<'tcx> TypeFoldable<'tcx> for ty::TraitRef<'tcx> { fn fold_with>(&self, folder: &mut F) -> ty::TraitRef<'tcx> { folder.fold_trait_ref(self) @@ -521,9 +511,55 @@ impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate // They should invoke `foo.fold_with()` to do recursive folding. pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T, - t: Ty<'tcx>) + ty: Ty<'tcx>) -> Ty<'tcx> { - let sty = t.sty.fold_with(this); + let sty = match ty.sty { + ty::ty_uniq(typ) => { + ty::ty_uniq(typ.fold_with(this)) + } + ty::ty_ptr(ref tm) => { + ty::ty_ptr(tm.fold_with(this)) + } + ty::ty_vec(typ, sz) => { + ty::ty_vec(typ.fold_with(this), sz) + } + ty::ty_open(typ) => { + ty::ty_open(typ.fold_with(this)) + } + ty::ty_enum(tid, ref substs) => { + ty::ty_enum(tid, substs.fold_with(this)) + } + ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => { + ty::ty_trait(box ty::TyTrait { + principal: (*principal).fold_with(this), + bounds: bounds.fold_with(this), + }) + } + ty::ty_tup(ref ts) => { + ty::ty_tup(ts.fold_with(this)) + } + ty::ty_bare_fn(ref f) => { + ty::ty_bare_fn(f.fold_with(this)) + } + ty::ty_closure(ref f) => { + ty::ty_closure(box f.fold_with(this)) + } + ty::ty_rptr(r, ref tm) => { + ty::ty_rptr(r.fold_with(this), tm.fold_with(this)) + } + ty::ty_struct(did, ref substs) => { + ty::ty_struct(did, substs.fold_with(this)) + } + ty::ty_unboxed_closure(did, ref region, ref substs) => { + ty::ty_unboxed_closure(did, region.fold_with(this), substs.fold_with(this)) + } + ty::ty_bool | ty::ty_char | ty::ty_str | + ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) | + ty::ty_err | ty::ty_infer(_) | + ty::ty_param(..) => { + ty.sty.clone() + } + }; ty::mk_t(this.tcx(), sty) } @@ -601,58 +637,6 @@ pub fn super_fold_mt<'tcx, T: TypeFolder<'tcx>>(this: &mut T, mutbl: mt.mutbl} } -pub fn super_fold_sty<'tcx, T: TypeFolder<'tcx>>(this: &mut T, - sty: &ty::sty<'tcx>) - -> ty::sty<'tcx> { - match *sty { - ty::ty_uniq(typ) => { - ty::ty_uniq(typ.fold_with(this)) - } - ty::ty_ptr(ref tm) => { - ty::ty_ptr(tm.fold_with(this)) - } - ty::ty_vec(typ, sz) => { - ty::ty_vec(typ.fold_with(this), sz) - } - ty::ty_open(typ) => { - ty::ty_open(typ.fold_with(this)) - } - ty::ty_enum(tid, ref substs) => { - ty::ty_enum(tid, substs.fold_with(this)) - } - ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => { - ty::ty_trait(box ty::TyTrait { - principal: (*principal).fold_with(this), - bounds: bounds.fold_with(this), - }) - } - ty::ty_tup(ref ts) => { - ty::ty_tup(ts.fold_with(this)) - } - ty::ty_bare_fn(ref f) => { - ty::ty_bare_fn(f.fold_with(this)) - } - ty::ty_closure(ref f) => { - ty::ty_closure(box f.fold_with(this)) - } - ty::ty_rptr(r, ref tm) => { - ty::ty_rptr(r.fold_with(this), tm.fold_with(this)) - } - ty::ty_struct(did, ref substs) => { - ty::ty_struct(did, substs.fold_with(this)) - } - ty::ty_unboxed_closure(did, ref region, ref substs) => { - ty::ty_unboxed_closure(did, region.fold_with(this), substs.fold_with(this)) - } - ty::ty_bool | ty::ty_char | ty::ty_str | - ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) | - ty::ty_err | ty::ty_infer(_) | - ty::ty_param(..) => { - (*sty).clone() - } - } -} - pub fn super_fold_trait_store<'tcx, T: TypeFolder<'tcx>>(this: &mut T, trait_store: ty::TraitStore) -> ty::TraitStore { diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 2ade3040d6c..09226052367 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -261,44 +261,43 @@ fn check_boxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, // Find the expected input/output types (if any). Substitute // fresh bound regions for any bound regions we find in the // expected types so as to avoid capture. - let expected_sty = expected.map_to_option(fcx, |x| Some((*x).clone())); - let (expected_sig, - expected_onceness, - expected_bounds) = { - match expected_sty { - Some(ty::ty_closure(ref cenv)) => { - let (sig, _) = - ty::replace_late_bound_regions( - tcx, - &cenv.sig, - |_, debruijn| fcx.inh.infcx.fresh_bound_region(debruijn)); - let onceness = match (&store, &cenv.store) { - // As the closure type and onceness go, only three - // combinations are legit: - // once closure - // many closure - // once proc - // If the actual and expected closure type disagree with - // each other, set expected onceness to be always Once or - // Many according to the actual type. Otherwise, it will - // yield either an illegal "many proc" or a less known - // "once closure" in the error message. - (&ty::UniqTraitStore, &ty::UniqTraitStore) | - (&ty::RegionTraitStore(..), &ty::RegionTraitStore(..)) => - cenv.onceness, - (&ty::UniqTraitStore, _) => ast::Once, - (&ty::RegionTraitStore(..), _) => ast::Many, - }; - (Some(sig), onceness, cenv.bounds) - } - _ => { - // Not an error! Means we're inferring the closure type - let region = fcx.infcx().next_region_var( - infer::AddrOfRegion(expr.span)); - let bounds = ty::region_existential_bound(region); - let onceness = ast::Many; - (None, onceness, bounds) - } + let expected_cenv = expected.map_to_option(fcx, |ty| match ty.sty { + ty::ty_closure(ref cenv) => Some(cenv), + _ => None + }); + let (expected_sig, expected_onceness, expected_bounds) = match expected_cenv { + Some(cenv) => { + let (sig, _) = + ty::replace_late_bound_regions( + tcx, + &cenv.sig, + |_, debruijn| fcx.inh.infcx.fresh_bound_region(debruijn)); + let onceness = match (&store, &cenv.store) { + // As the closure type and onceness go, only three + // combinations are legit: + // once closure + // many closure + // once proc + // If the actual and expected closure type disagree with + // each other, set expected onceness to be always Once or + // Many according to the actual type. Otherwise, it will + // yield either an illegal "many proc" or a less known + // "once closure" in the error message. + (&ty::UniqTraitStore, &ty::UniqTraitStore) | + (&ty::RegionTraitStore(..), &ty::RegionTraitStore(..)) => + cenv.onceness, + (&ty::UniqTraitStore, _) => ast::Once, + (&ty::RegionTraitStore(..), _) => ast::Many, + }; + (Some(sig), onceness, cenv.bounds) + } + _ => { + // Not an error! Means we're inferring the closure type + let region = fcx.infcx().next_region_var( + infer::AddrOfRegion(expr.span)); + let bounds = ty::region_existential_bound(region); + let onceness = ast::Many; + (None, onceness, bounds) } }; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index bbc33826f35..1e624dfaaa4 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2042,7 +2042,7 @@ fn try_overloaded_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, -> bool { // Bail out if the callee is a bare function or a closure. We check those // manually. - match *structure_of(fcx, callee.span, callee_type) { + match structurally_resolved_type(fcx, callee.span, callee_type).sty { ty::ty_bare_fn(_) | ty::ty_closure(_) => return false, _ => {} } @@ -2717,10 +2717,9 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, ast::LitInt(_, ast::SignedIntLit(t, _)) => ty::mk_mach_int(t), ast::LitInt(_, ast::UnsignedIntLit(t)) => ty::mk_mach_uint(t), ast::LitInt(_, ast::UnsuffixedIntLit(_)) => { - let opt_ty = expected.map_to_option(fcx, |sty| { - match *sty { - ty::ty_int(i) => Some(ty::mk_mach_int(i)), - ty::ty_uint(i) => Some(ty::mk_mach_uint(i)), + let opt_ty = expected.map_to_option(fcx, |ty| { + match ty.sty { + ty::ty_int(_) | ty::ty_uint(_) => Some(ty), ty::ty_char => Some(ty::mk_mach_uint(ast::TyU8)), ty::ty_ptr(..) => Some(ty::mk_mach_uint(ast::TyU)), ty::ty_bare_fn(..) => Some(ty::mk_mach_uint(ast::TyU)), @@ -2732,9 +2731,9 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, } ast::LitFloat(_, t) => ty::mk_mach_float(t), ast::LitFloatUnsuffixed(_) => { - let opt_ty = expected.map_to_option(fcx, |sty| { - match *sty { - ty::ty_float(i) => Some(ty::mk_mach_float(i)), + let opt_ty = expected.map_to_option(fcx, |ty| { + match ty.sty { + ty::ty_float(_) => Some(ty), _ => None } }); @@ -2910,7 +2909,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, let fn_ty = fcx.expr_ty(f); // Extract the function signature from `in_fty`. - let fn_sty = structure_of(fcx, f.span, fn_ty); + let fn_ty = structurally_resolved_type(fcx, f.span, fn_ty); // This is the "default" function signature, used in case of error. // In that case, we check each argument against "error" in order to @@ -2921,7 +2920,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, variadic: false }); - let fn_sig = match *fn_sty { + let fn_sig = match fn_ty.sty { ty::ty_bare_fn(ty::BareFnTy {ref sig, ..}) | ty::ty_closure(box ty::ClosureTy {ref sig, ..}) => sig, _ => { @@ -3655,9 +3654,9 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, } } ast::ExprUnary(unop, ref oprnd) => { - let expected_inner = expected.map(fcx, |sty| { + let expected_inner = expected.map(fcx, |ty| { match unop { - ast::UnUniq => match *sty { + ast::UnUniq => match ty.sty { ty::ty_uniq(ty) => { ExpectHasType(ty) } @@ -3746,9 +3745,11 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, } ast::ExprAddrOf(mutbl, ref oprnd) => { let expected = expected.only_has_type(); - let hint = expected.map(fcx, |sty| { - match *sty { ty::ty_rptr(_, ref mt) | ty::ty_ptr(ref mt) => ExpectHasType(mt.ty), - _ => NoExpectation } + let hint = expected.map(fcx, |ty| { + match ty.sty { + ty::ty_rptr(_, ref mt) | ty::ty_ptr(ref mt) => ExpectHasType(mt.ty), + _ => NoExpectation + } }); let lvalue_pref = match mutbl { ast::MutMutable => PreferMutLvalue, @@ -4037,9 +4038,9 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, } ast::ExprTup(ref elts) => { let expected = expected.only_has_type(); - let flds = expected.map_to_option(fcx, |sty| { - match *sty { - ty::ty_tup(ref flds) => Some((*flds).clone()), + let flds = expected.map_to_option(fcx, |ty| { + match ty.sty { + ty::ty_tup(ref flds) => Some(flds[]), _ => None } }); @@ -4304,20 +4305,20 @@ impl<'tcx> Expectation<'tcx> { } fn map<'a, F>(self, fcx: &FnCtxt<'a, 'tcx>, unpack: F) -> Expectation<'tcx> where - F: FnOnce(&ty::sty<'tcx>) -> Expectation<'tcx> + F: FnOnce(Ty<'tcx>) -> Expectation<'tcx> { match self.resolve(fcx) { NoExpectation => NoExpectation, - ExpectCastableToType(t) | ExpectHasType(t) => unpack(&t.sty), + ExpectCastableToType(ty) | ExpectHasType(ty) => unpack(ty), } } fn map_to_option<'a, O, F>(self, fcx: &FnCtxt<'a, 'tcx>, unpack: F) -> Option where - F: FnOnce(&ty::sty<'tcx>) -> Option, + F: FnOnce(Ty<'tcx>) -> Option, { match self.resolve(fcx) { NoExpectation => None, - ExpectCastableToType(t) | ExpectHasType(t) => unpack(&t.sty), + ExpectCastableToType(ty) | ExpectHasType(ty) => unpack(ty), } } } @@ -5320,12 +5321,6 @@ pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, ty } -// Returns the one-level-deep structure of the given type. -pub fn structure_of<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, typ: Ty<'tcx>) - -> &'tcx ty::sty<'tcx> { - &structurally_resolved_type(fcx, sp, typ).sty -} - // Returns true if b contains a break that can exit from b pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &ast::Block) -> bool { // First: is there an unlabeled break immediately diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index c09ce3db6dd..24d7bf5031e 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -17,7 +17,7 @@ use middle::subst::{Subst}; use middle::traits; use middle::ty::{mod, Ty}; use middle::ty::liberate_late_bound_regions; -use middle::ty_fold::{TypeFolder, TypeFoldable}; +use middle::ty_fold::{TypeFolder, TypeFoldable, super_fold_ty}; use util::ppaux::Repr; use std::collections::HashSet; @@ -368,8 +368,8 @@ impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'tcx> { self.binding_count -= 1; } - ref sty => { - self.fold_sty(sty); + _ => { + super_fold_ty(self, t); } } From 89f75a6e810e8994143f44e2239f58ffa132ad86 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Fri, 19 Dec 2014 22:28:12 -0800 Subject: [PATCH 43/58] Stabilize integer modules This small patch stabilizes the names of all integer modules (including `int` and `uint`) and the `MIN` and `MAX` constants. The `BITS` and `BYTES` constants are left unstable for now. --- src/libcore/num/int.rs | 3 +-- src/libcore/num/int_macros.rs | 5 ++--- src/libcore/num/uint.rs | 3 +-- src/libcore/num/uint_macros.rs | 5 ++--- src/libstd/num/int.rs | 2 +- src/libstd/num/uint.rs | 2 +- 6 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/libcore/num/int.rs b/src/libcore/num/int.rs index a0659d38307..91c5e4163f9 100644 --- a/src/libcore/num/int.rs +++ b/src/libcore/num/int.rs @@ -10,9 +10,8 @@ //! Operations and constants for architecture-sized signed integers (`int` type) -#![unstable] +#![stable] #![doc(primitive = "int")] #[cfg(target_word_size = "32")] int_module! { int, 32 } #[cfg(target_word_size = "64")] int_module! { int, 64 } - diff --git a/src/libcore/num/int_macros.rs b/src/libcore/num/int_macros.rs index 00b9d88abe1..522eab9180c 100644 --- a/src/libcore/num/int_macros.rs +++ b/src/libcore/num/int_macros.rs @@ -24,13 +24,12 @@ pub const BYTES : uint = ($bits / 8); // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of // calling the `Bounded::min_value` function. -#[unstable] +#[stable] pub const MIN: $T = (-1 as $T) << (BITS - 1); // FIXME(#9837): Compute MIN like this so the high bits that shouldn't exist are 0. // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of // calling the `Bounded::max_value` function. -#[unstable] +#[stable] pub const MAX: $T = !MIN; ) } - diff --git a/src/libcore/num/uint.rs b/src/libcore/num/uint.rs index 80d7b0b4ef3..35739f68da9 100644 --- a/src/libcore/num/uint.rs +++ b/src/libcore/num/uint.rs @@ -10,8 +10,7 @@ //! Operations and constants for architecture-sized unsigned integers (`uint` type) -#![unstable] +#![stable] #![doc(primitive = "uint")] uint_module! { uint, int, ::int::BITS } - diff --git a/src/libcore/num/uint_macros.rs b/src/libcore/num/uint_macros.rs index d79cf20fdfa..82eca0d4659 100644 --- a/src/libcore/num/uint_macros.rs +++ b/src/libcore/num/uint_macros.rs @@ -18,10 +18,9 @@ pub const BITS : uint = $bits; #[unstable] pub const BYTES : uint = ($bits / 8); -#[unstable] +#[stable] pub const MIN: $T = 0 as $T; -#[unstable] +#[stable] pub const MAX: $T = 0 as $T - 1 as $T; ) } - diff --git a/src/libstd/num/int.rs b/src/libstd/num/int.rs index f59dab4b20b..9ccb1544fdc 100644 --- a/src/libstd/num/int.rs +++ b/src/libstd/num/int.rs @@ -10,7 +10,7 @@ //! Operations and constants for architecture-sized signed integers (`int` type) -#![unstable] +#![stable] #![doc(primitive = "int")] pub use core::int::{BITS, BYTES, MIN, MAX}; diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs index 7f8edee571f..cd000b3098b 100644 --- a/src/libstd/num/uint.rs +++ b/src/libstd/num/uint.rs @@ -10,7 +10,7 @@ //! Operations and constants for architecture-sized unsigned integers (`uint` type) -#![unstable] +#![stable] #![doc(primitive = "uint")] pub use core::uint::{BITS, BYTES, MIN, MAX}; From e473e700ccb94177cdc8e799b9f08bceb1c75601 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Fri, 19 Dec 2014 23:47:46 -0800 Subject: [PATCH 44/58] Stabilize cell This patch finalizes stabilization for the `cell` module, settling on the current names `Cell`, `RefCell`, `UnsafeCell`, `Ref` and `RefMut`. While we had considered improving these names, no one was able to produce a truly compelling alternative. There is one substantive change here: the `get` method of `UnsafeSell` is now marked `unsafe`. Merely getting a raw pointer to the contents is not, by itself, an unsafe operation. (Consider that you can always safely turn a reference into a raw pointer, and that raw pointer may then be aliased by subsequent references.) --- src/libcore/cell.rs | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 01979e97577..03eb4504448 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -164,7 +164,7 @@ use option::Option; use option::Option::{None, Some}; /// A mutable memory location that admits only `Copy` data. -#[unstable = "likely to be renamed; otherwise stable"] +#[stable] pub struct Cell { value: UnsafeCell, noshare: marker::NoSync, @@ -231,7 +231,7 @@ impl PartialEq for Cell { } /// A mutable memory location with dynamically checked borrow rules -#[unstable = "likely to be renamed; otherwise stable"] +#[stable] pub struct RefCell { value: UnsafeCell, borrow: Cell, @@ -256,7 +256,7 @@ impl RefCell { } /// Consumes the `RefCell`, returning the wrapped value. - #[unstable = "recently renamed per RFC 430"] + #[stable] 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. @@ -275,7 +275,7 @@ impl RefCell { /// immutable borrows can be taken out at the same time. /// /// Returns `None` if the value is currently mutably borrowed. - #[unstable = "may be renamed, depending on global conventions"] + #[unstable = "may be renamed or removed"] pub fn try_borrow<'a>(&'a self) -> Option> { match BorrowRef::new(&self.borrow) { Some(b) => Some(Ref { _value: unsafe { &*self.value.get() }, _borrow: b }), @@ -291,7 +291,7 @@ impl RefCell { /// # Panics /// /// Panics if the value is currently mutably borrowed. - #[unstable] + #[stable] pub fn borrow<'a>(&'a self) -> Ref<'a, T> { match self.try_borrow() { Some(ptr) => ptr, @@ -305,7 +305,7 @@ impl RefCell { /// cannot be borrowed while this borrow is active. /// /// Returns `None` if the value is currently borrowed. - #[unstable = "may be renamed, depending on global conventions"] + #[unstable = "may be renamed or removed"] 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 }), @@ -321,7 +321,7 @@ impl RefCell { /// # Panics /// /// Panics if the value is currently borrowed. - #[unstable] + #[stable] pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> { match self.try_borrow_mut() { Some(ptr) => ptr, @@ -400,7 +400,7 @@ impl<'b> Clone for BorrowRef<'b> { } /// Wraps a borrowed reference to a value in a `RefCell` box. -#[unstable] +#[stable] pub struct Ref<'b, T:'b> { // FIXME #12808: strange name to try to avoid interfering with // field accesses of the contained type via Deref @@ -456,7 +456,7 @@ impl<'b> BorrowRefMut<'b> { } /// Wraps a mutable borrowed reference to a value in a `RefCell` box. -#[unstable] +#[stable] pub struct RefMut<'b, T:'b> { // FIXME #12808: strange name to try to avoid interfering with // field accesses of the contained type via Deref @@ -517,7 +517,7 @@ impl<'b, T> DerefMut for RefMut<'b, T> { /// is not recommended to access its fields directly, `get` should be used /// instead. #[lang="unsafe"] -#[unstable = "this type may be renamed in the future"] +#[stable] pub struct UnsafeCell { /// Wrapped value /// @@ -539,22 +539,16 @@ impl UnsafeCell { } /// Gets a mutable pointer to the wrapped value. - /// - /// This function is unsafe as the pointer returned is an unsafe pointer and - /// no guarantees are made about the aliasing of the pointers being handed - /// out in this or other tasks. #[inline] - #[unstable = "conventions around acquiring an inner reference are still \ - under development"] - pub unsafe fn get(&self) -> *mut T { &self.value as *const T as *mut T } + #[stable] + pub fn get(&self) -> *mut T { &self.value as *const T as *mut T } /// Unwraps the value /// /// This function is unsafe because there is no guarantee that this or other /// tasks are currently inspecting the inner value. #[inline] - #[unstable = "conventions around the name `unwrap` are still under \ - development"] + #[stable] pub unsafe fn into_inner(self) -> T { self.value } /// Deprecated, use into_inner() instead From a7f1ce37bfc1dff62a6b22e88e687a9a1a2ff475 Mon Sep 17 00:00:00 2001 From: Jarod Liu Date: Sat, 20 Dec 2014 16:07:03 +0800 Subject: [PATCH 45/58] use binary literals to better reflect "bitflags" --- src/libstd/bitflags.rs | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs index f467b77dbf4..3285708fbff 100644 --- a/src/libstd/bitflags.rs +++ b/src/libstd/bitflags.rs @@ -24,9 +24,9 @@ /// ```{.rust} /// bitflags! { /// flags Flags: u32 { -/// const FLAG_A = 0x00000001, -/// const FLAG_B = 0x00000010, -/// const FLAG_C = 0x00000100, +/// const FLAG_A = 0b00000001, +/// const FLAG_B = 0b00000010, +/// const FLAG_C = 0b00000100, /// const FLAG_ABC = FLAG_A.bits /// | FLAG_B.bits /// | FLAG_C.bits, @@ -50,8 +50,8 @@ /// /// bitflags! { /// flags Flags: u32 { -/// const FLAG_A = 0x00000001, -/// const FLAG_B = 0x00000010, +/// const FLAG_A = 0b00000001, +/// const FLAG_B = 0b00000010, /// } /// } /// @@ -326,10 +326,10 @@ mod tests { #[doc = "> "] #[doc = "> - Richard Feynman"] flags Flags: u32 { - const FlagA = 0x00000001, + const FlagA = 0b00000001, #[doc = " macros are way better at generating code than trans is"] - const FlagB = 0x00000010, - const FlagC = 0x00000100, + const FlagB = 0b00000010, + const FlagC = 0b00000100, #[doc = "* cmr bed"] #[doc = "* strcat table"] #[doc = " wait what?"] @@ -347,21 +347,21 @@ mod tests { #[test] fn test_bits(){ - assert_eq!(Flags::empty().bits(), 0x00000000); - assert_eq!(FlagA.bits(), 0x00000001); - assert_eq!(FlagABC.bits(), 0x00000111); + assert_eq!(Flags::empty().bits(), 0b00000000); + assert_eq!(FlagA.bits(), 0b00000001); + assert_eq!(FlagABC.bits(), 0b00000111); - assert_eq!(AnotherSetOfFlags::empty().bits(), 0x00); + assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00); assert_eq!(AnotherFlag.bits(), !0_i8); } #[test] fn test_from_bits() { assert!(Flags::from_bits(0) == Some(Flags::empty())); - assert!(Flags::from_bits(0x1) == Some(FlagA)); - assert!(Flags::from_bits(0x10) == Some(FlagB)); - assert!(Flags::from_bits(0x11) == Some(FlagA | FlagB)); - assert!(Flags::from_bits(0x1000) == None); + assert!(Flags::from_bits(0b1) == Some(FlagA)); + assert!(Flags::from_bits(0b10) == Some(FlagB)); + assert!(Flags::from_bits(0b11) == Some(FlagA | FlagB)); + assert!(Flags::from_bits(0b1000) == None); assert!(AnotherSetOfFlags::from_bits(!0_i8) == Some(AnotherFlag)); } @@ -369,11 +369,11 @@ mod tests { #[test] fn test_from_bits_truncate() { assert!(Flags::from_bits_truncate(0) == Flags::empty()); - assert!(Flags::from_bits_truncate(0x1) == FlagA); - assert!(Flags::from_bits_truncate(0x10) == FlagB); - assert!(Flags::from_bits_truncate(0x11) == (FlagA | FlagB)); - assert!(Flags::from_bits_truncate(0x1000) == Flags::empty()); - assert!(Flags::from_bits_truncate(0x1001) == FlagA); + assert!(Flags::from_bits_truncate(0b1) == FlagA); + assert!(Flags::from_bits_truncate(0b10) == FlagB); + assert!(Flags::from_bits_truncate(0b11) == (FlagA | FlagB)); + assert!(Flags::from_bits_truncate(0b1000) == Flags::empty()); + assert!(Flags::from_bits_truncate(0b1001) == FlagA); assert!(AnotherSetOfFlags::from_bits_truncate(0_i8) == AnotherSetOfFlags::empty()); } From 31f5ab3f0c59f65e6758fe5ffadb617a98dcd5b4 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Sun, 14 Dec 2014 15:42:41 +1300 Subject: [PATCH 46/58] Allow `Self` in impls. --- src/libsyntax/ext/base.rs | 2 +- src/libsyntax/ext/expand.rs | 51 +++++++++++++++++++++++++++++++--- src/test/run-pass/self-impl.rs | 42 ++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 src/test/run-pass/self-impl.rs diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 3947a602809..aefbb2a1fea 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -490,7 +490,7 @@ impl<'a> ExtCtxt<'a> { /// Returns a `Folder` for deeply expanding all macros in a AST node. pub fn expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> { - expand::MacroExpander { cx: self } + expand::MacroExpander::new(self) } pub fn new_parser_from_tts(&self, tts: &[ast::TokenTree]) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 20c8ff20b71..01d55eba316 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -15,6 +15,7 @@ use ast::{ItemMac, MacStmtWithSemicolon, Mrk, Stmt, StmtDecl, StmtMac}; use ast::{StmtExpr, StmtSemi}; use ast::TokenTree; use ast; +use ast_util::path_to_ident; use ext::mtwt; use ext::build::AstBuilder; use attr; @@ -37,6 +38,30 @@ enum Either { Right(R) } +pub fn expand_type(t: P, + fld: &mut MacroExpander, + impl_ty: Option>) + -> P { + debug!("expanding type {} with impl_ty {}", t, impl_ty); + let t = match (t.node.clone(), impl_ty) { + // Expand uses of `Self` in impls to the concrete type. + (ast::Ty_::TyPath(ref path, _), Some(ref impl_ty)) => { + let path_as_ident = path_to_ident(path); + // Note unhygenic comparison here. I think this is correct, since + // even though `Self` is almost just a type parameter, the treatment + // for this expansion is as if it were a keyword. + if path_as_ident.is_some() && + path_as_ident.unwrap().name == token::special_idents::type_self.name { + impl_ty.clone() + } else { + t + } + } + _ => t + }; + fold::noop_fold_ty(t, fld) +} + pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { e.and_then(|ast::Expr {id, node, span}| match node { // expr_mac should really be expr_ext or something; it's the @@ -1059,6 +1084,14 @@ fn expand_and_rename_fn_decl_and_block(fn_decl: P, block: P { pub cx: &'a mut ExtCtxt<'b>, + // The type of the impl currently being expanded. + current_impl_type: Option>, +} + +impl<'a, 'b> MacroExpander<'a, 'b> { + pub fn new(cx: &'a mut ExtCtxt<'b>) -> MacroExpander<'a, 'b> { + MacroExpander { cx: cx, current_impl_type: None } + } } impl<'a, 'b> Folder for MacroExpander<'a, 'b> { @@ -1071,7 +1104,14 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { } fn fold_item(&mut self, item: P) -> SmallVector> { - expand_item(item, self) + let prev_type = self.current_impl_type.clone(); + if let ast::Item_::ItemImpl(_, _, _, ref ty, _) = item.node { + self.current_impl_type = Some(ty.clone()); + } + + let result = expand_item(item, self); + self.current_impl_type = prev_type; + result } fn fold_item_underscore(&mut self, item: ast::Item_) -> ast::Item_ { @@ -1094,6 +1134,11 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { expand_method(method, self) } + fn fold_ty(&mut self, t: P) -> P { + let impl_type = self.current_impl_type.clone(); + expand_type(t, self, impl_type) + } + fn new_span(&mut self, span: Span) -> Span { new_span(self.cx, span) } @@ -1138,9 +1183,7 @@ pub fn expand_crate(parse_sess: &parse::ParseSess, user_exts: Vec, c: Crate) -> Crate { let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg); - let mut expander = MacroExpander { - cx: &mut cx, - }; + let mut expander = MacroExpander::new(&mut cx); for ExportedMacros { crate_name, macros } in imported_macros.into_iter() { let name = format!("<{} macros>", token::get_ident(crate_name)) diff --git a/src/test/run-pass/self-impl.rs b/src/test/run-pass/self-impl.rs new file mode 100644 index 00000000000..3ece042aef0 --- /dev/null +++ b/src/test/run-pass/self-impl.rs @@ -0,0 +1,42 @@ +// 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 can use `Self` types in impls in the expected way. + +struct Foo; + +// Test uses on inherant impl. +impl Foo { + fn foo(_x: Self, _y: &Self, _z: Box) -> Self { + Foo + } +} + +// Test uses when implementing a trait and with a type parameter. +pub struct Baz { + pub f: X, +} + +trait Bar { + fn bar(x: Self, y: &Self, z: Box) -> Self; +} + +impl Bar for Box> { + fn bar(_x: Self, _y: &Self, _z: Box) -> Self { + box Baz { f: 42 } + } +} + +fn main() { + let _: Foo = Foo::foo(Foo, &Foo, box Foo); + let _: Box> = Bar::bar(box Baz { f: 42 }, + &box Baz { f: 42 }, + box box Baz { f: 42 }); +} From 84b8f318a54e32f8bce0db0759bdcd3c562b97b3 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Sat, 20 Dec 2014 00:32:07 -0800 Subject: [PATCH 47/58] add {:?} fmt syntax --- src/libsyntax/ext/format.rs | 1 + src/test/run-pass/ifmt.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 5d595474e9c..95c7fcc564a 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -654,6 +654,7 @@ impl<'a, 'b> Context<'a, 'b> { Known(ref tyname) => { match tyname.as_slice() { "" => "Show", + "?" => "Show", "e" => "LowerExp", "E" => "UpperExp", "o" => "Octal", diff --git a/src/test/run-pass/ifmt.rs b/src/test/run-pass/ifmt.rs index 9eac9c30dc8..f3e15562b6d 100644 --- a/src/test/run-pass/ifmt.rs +++ b/src/test/run-pass/ifmt.rs @@ -60,6 +60,7 @@ pub fn main() { t!(format!("{}", 10i), "10"); t!(format!("{}", 10i), "10"); t!(format!("{}", 10u), "10"); + t!(format!("{:?}", true), "true"); t!(format!("{:o}", 10u), "12"); t!(format!("{:x}", 10u), "a"); t!(format!("{:X}", 10u), "A"); From 92ccc073e1a5a68fada24b5b3cb47b65b5ff1c61 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Sat, 20 Dec 2014 00:35:06 -0800 Subject: [PATCH 48/58] Stabilize clone This patch marks `clone` stable, as well as the `Clone` trait, but leaves `clone_from` unstable. The latter will be decided by the beta. The patch also marks most manual implementations of `Clone` as stable, except where the APIs are otherwise deprecated or where there is uncertainty about providing `Clone`. --- src/liballoc/arc.rs | 2 +- src/liballoc/boxed.rs | 2 +- src/liballoc/rc.rs | 2 +- src/libcollections/bit.rs | 1 + src/libcollections/btree/node.rs | 1 + src/libcollections/dlist.rs | 1 + src/libcollections/ring_buf.rs | 1 + src/libcollections/vec.rs | 2 +- src/libcore/array.rs | 3 +-- src/libcore/borrow.rs | 1 + src/libcore/cell.rs | 4 ++-- src/libcore/clone.rs | 9 ++++++--- src/libcore/hash/sip.rs | 1 + src/libcore/iter.rs | 9 +++++++++ src/libcore/option.rs | 1 + src/libcore/ptr.rs | 3 ++- src/libcore/slice.rs | 4 ++-- src/libcore/tuple/mod.rs | 3 +-- src/libstd/comm/mod.rs | 4 ++-- src/libstd/io/comm_adapters.rs | 1 + 20 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index e909947ab08..c3bd5c4157c 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -132,7 +132,7 @@ pub fn weak_count(this: &Arc) -> uint { this.inner().weak.load(atomic::Seq #[experimental] pub fn strong_count(this: &Arc) -> uint { this.inner().strong.load(atomic::SeqCst) } -#[unstable = "waiting on stability of Clone"] +#[stable] impl Clone for Arc { /// Duplicate an atomically reference counted wrapper. /// diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 879a8cc6951..f0c96196b78 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -57,7 +57,7 @@ impl Default for Box<[T]> { fn default() -> Box<[T]> { box [] } } -#[unstable] +#[stable] impl Clone for Box { /// Returns a copy of the owned box. #[inline] diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 0257c640d3c..b22c366e29d 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -413,7 +413,7 @@ impl Drop for Rc { } } -#[unstable = "Clone is unstable."] +#[stable] impl Clone for Rc { /// Makes a clone of the `Rc`. /// diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index 7f78d56607e..2025af1286b 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -851,6 +851,7 @@ impl Extend for Bitv { } } +#[stable] impl Clone for Bitv { #[inline] fn clone(&self) -> Bitv { diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index 9698b06c7fa..56b544c4087 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -390,6 +390,7 @@ impl Node { } // FIXME(gereeter) Write an efficient clone_from +#[stable] impl Clone for Node { fn clone(&self) -> Node { let mut ret = if self.is_leaf() { diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index e7454aef51e..04bd40bf51a 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -758,6 +758,7 @@ impl Ord for DList { } } +#[stable] impl Clone for DList { fn clone(&self) -> DList { self.iter().map(|x| x.clone()).collect() diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs index cdb92d302e9..5d53520b8f3 100644 --- a/src/libcollections/ring_buf.rs +++ b/src/libcollections/ring_buf.rs @@ -48,6 +48,7 @@ pub struct RingBuf { ptr: *mut T } +#[stable] impl Clone for RingBuf { fn clone(&self) -> RingBuf { self.iter().map(|t| t.clone()).collect() diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index e986b204430..7fca8b37705 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -443,7 +443,7 @@ impl Vec { } } -#[unstable] +#[stable] impl Clone for Vec { fn clone(&self) -> Vec { self.as_slice().to_vec() } diff --git a/src/libcore/array.rs b/src/libcore/array.rs index ffaf35414ea..e85a132ed36 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -25,7 +25,7 @@ use option::Option; macro_rules! array_impls { ($($N:expr)+) => { $( - #[unstable = "waiting for Clone to stabilize"] + #[stable] impl Clone for [T, ..$N] { fn clone(&self) -> [T, ..$N] { *self @@ -115,4 +115,3 @@ array_impls! { 20 21 22 23 24 25 26 27 28 29 30 31 32 } - diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index b44b87bd938..9bbcf67773e 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -137,6 +137,7 @@ pub enum Cow<'a, T, Sized? B: 'a> where B: ToOwned { Owned(T) } +#[stable] impl<'a, T, Sized? B> Clone for Cow<'a, T, B> where B: ToOwned { fn clone(&self) -> Cow<'a, T, B> { match *self { diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 01979e97577..e0041f9738e 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -208,7 +208,7 @@ impl Cell { } } -#[unstable = "waiting for `Clone` trait to become stable"] +#[stable] impl Clone for Cell { fn clone(&self) -> Cell { Cell::new(self.get()) @@ -341,7 +341,7 @@ impl RefCell { } } -#[unstable = "waiting for `Clone` to become stable"] +#[stable] impl Clone for RefCell { fn clone(&self) -> RefCell { RefCell::new(self.borrow().clone()) diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index f6be422813a..686ccf6f1a2 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -19,13 +19,15 @@ //! explicitly, by convention implementing the `Clone` trait and calling //! the `clone` method. -#![unstable] +#![stable] use kinds::Sized; /// A common trait for cloning an object. +#[stable] pub trait Clone { /// Returns a copy of the value. + #[stable] fn clone(&self) -> Self; /// Perform copy-assignment from `source`. @@ -34,12 +36,13 @@ pub trait Clone { /// but can be overridden to reuse the resources of `a` to avoid unnecessary /// allocations. #[inline(always)] - #[experimental = "this function is mostly unused"] + #[unstable = "this function rarely unused"] fn clone_from(&mut self, source: &Self) { *self = source.clone() } } +#[stable] impl<'a, Sized? T> Clone for &'a T { /// Return a shallow copy of the reference. #[inline] @@ -48,6 +51,7 @@ impl<'a, Sized? T> Clone for &'a T { macro_rules! clone_impl { ($t:ty) => { + #[stable] impl Clone for $t { /// Return a deep copy of the value. #[inline] @@ -95,4 +99,3 @@ extern_fn_clone! { A, B, C, D, E } extern_fn_clone! { A, B, C, D, E, F } extern_fn_clone! { A, B, C, D, E, F, G } extern_fn_clone! { A, B, C, D, E, F, G, H } - diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs index e10f5a9fed1..628c1897f6e 100644 --- a/src/libcore/hash/sip.rs +++ b/src/libcore/hash/sip.rs @@ -195,6 +195,7 @@ impl Writer for SipState { } } +#[stable] impl Clone for SipState { #[inline] fn clone(&self) -> SipState { diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 1f83aad9c7c..b592d1db274 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -1386,6 +1386,7 @@ pub struct Map, F: FnMut(A) -> B> { } // FIXME(#19839) Remove in favor of `#[deriving(Clone)]` +#[stable] impl Clone for Map where I: Clone + Iterator, F: Clone + FnMut(A) -> B, @@ -1460,6 +1461,7 @@ pub struct Filter where I: Iterator, P: FnMut(&A) -> bool { } // FIXME(#19839) Remove in favor of `#[deriving(Clone)]` +#[stable] impl Clone for Filter where I: Clone + Iterator, P: Clone + FnMut(&A) -> bool, @@ -1518,6 +1520,7 @@ pub struct FilterMap where I: Iterator, F: FnMut(A) -> Option } // FIXME(#19839) Remove in favor of `#[deriving(Clone)]` +#[stable] impl Clone for FilterMap where I: Clone + Iterator, F: Clone + FnMut(A) -> Option, @@ -1693,6 +1696,7 @@ pub struct SkipWhile where I: Iterator, P: FnMut(&A) -> bool { } // FIXME(#19839) Remove in favor of `#[deriving(Clone)]` +#[stable] impl Clone for SkipWhile where I: Clone + Iterator, P: Clone + FnMut(&A) -> bool, @@ -1736,6 +1740,7 @@ pub struct TakeWhile where I: Iterator, P: FnMut(&A) -> bool { } // FIXME(#19839) Remove in favor of `#[deriving(Clone)]` +#[stable] impl Clone for TakeWhile where I: Clone + Iterator, P: Clone + FnMut(&A) -> bool, @@ -1911,6 +1916,7 @@ pub struct Scan where I: Iterator, F: FnMut(&mut St, A) -> Op } // FIXME(#19839) Remove in favor of `#[deriving(Clone)]` +#[stable] impl Clone for Scan where I: Clone + Iterator, St: Clone, @@ -1955,6 +1961,7 @@ pub struct FlatMap where I: Iterator, U: Iterator, F: FnMut } // FIXME(#19839) Remove in favor of `#[deriving(Clone)]` +#[stable] impl Clone for FlatMap where I: Clone + Iterator, U: Clone + Iterator, @@ -2115,6 +2122,7 @@ pub struct Inspect where I: Iterator, F: FnMut(&A) { } // FIXME(#19839) Remove in favor of `#[deriving(Clone)]` +#[stable] impl Clone for Inspect where I: Clone + Iterator, F: Clone + FnMut(&A), @@ -2222,6 +2230,7 @@ pub struct Unfold where F: FnMut(&mut St) -> Option { } // FIXME(#19839) Remove in favor of `#[deriving(Clone)]` +#[stable] impl Clone for Unfold where F: Clone + FnMut(&mut St) -> Option, St: Clone, diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 314b47fc647..8adbba8b94b 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -819,6 +819,7 @@ impl<'a, A> DoubleEndedIterator<&'a A> for Iter<'a, A> { impl<'a, A> ExactSizeIterator<&'a A> for Iter<'a, A> {} +#[stable] impl<'a, A> Clone for Iter<'a, A> { fn clone(&self) -> Iter<'a, A> { Iter { inner: self.inner.clone() } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 36c6b9572ea..1726a753792 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -340,6 +340,7 @@ impl Equiv<*const T> for *mut T { } } +#[stable] impl Clone for *const T { #[inline] fn clone(&self) -> *const T { @@ -347,6 +348,7 @@ impl Clone for *const T { } } +#[stable] impl Clone for *mut T { #[inline] fn clone(&self) -> *mut T { @@ -451,4 +453,3 @@ impl PartialOrd for *mut T { #[inline] fn ge(&self, other: &*mut T) -> bool { *self >= *other } } - diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index f5d117bca9f..efc92429afd 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -781,7 +781,7 @@ iterator!{struct Items -> *const T, &'a T} #[experimental = "needs review"] impl<'a, T> ExactSizeIterator<&'a T> for Items<'a, T> {} -#[experimental = "needs review"] +#[stable] impl<'a, T> Clone for Items<'a, T> { fn clone(&self) -> Items<'a, T> { *self } } @@ -893,6 +893,7 @@ pub struct Splits<'a, T:'a, P> where P: FnMut(&T) -> bool { } // FIXME(#19839) Remove in favor of `#[deriving(Clone)]` +#[stable] impl<'a, T, P> Clone for Splits<'a, T, P> where P: Clone + FnMut(&T) -> bool { fn clone(&self) -> Splits<'a, T, P> { Splits { @@ -1550,4 +1551,3 @@ impl_int_slice! { u16, i16 } impl_int_slice! { u32, i32 } impl_int_slice! { u64, i64 } impl_int_slice! { uint, int } - diff --git a/src/libcore/tuple/mod.rs b/src/libcore/tuple/mod.rs index 5ea84f7db91..1a82109be5b 100644 --- a/src/libcore/tuple/mod.rs +++ b/src/libcore/tuple/mod.rs @@ -126,7 +126,7 @@ macro_rules! tuple_impls { )+ } - #[unstable = "waiting for Clone to stabilize"] + #[stable] impl<$($T:Clone),+> Clone for ($($T,)+) { fn clone(&self) -> ($($T,)+) { ($(e!(self.$idx.clone()),)+) @@ -328,4 +328,3 @@ tuple_impls! { (val11, ref11, mut11, 11) -> L } } - diff --git a/src/libstd/comm/mod.rs b/src/libstd/comm/mod.rs index 9043cb8c7d6..55f5662dbd8 100644 --- a/src/libstd/comm/mod.rs +++ b/src/libstd/comm/mod.rs @@ -628,7 +628,7 @@ impl Sender { } } -#[unstable] +#[stable] impl Clone for Sender { fn clone(&self) -> Sender { let (packet, sleeper, guard) = match *unsafe { self.inner() } { @@ -756,7 +756,7 @@ impl SyncSender { } } -#[unstable] +#[stable] impl Clone for SyncSender { fn clone(&self) -> SyncSender { unsafe { (*self.inner.get()).clone_chan(); } diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs index e865bf42bd0..3a18b0dc1b5 100644 --- a/src/libstd/io/comm_adapters.rs +++ b/src/libstd/io/comm_adapters.rs @@ -132,6 +132,7 @@ impl ChanWriter { } } +#[stable] impl Clone for ChanWriter { fn clone(&self) -> ChanWriter { ChanWriter { tx: self.tx.clone() } From b4a065a3a097beb0777f6dc7081a492c3ddbcde9 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Sat, 20 Dec 2014 11:08:51 -0500 Subject: [PATCH 49/58] Correct typo in doc for StdinReaderGuard --- src/libstd/io/stdio.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index aa50597c816..36dd5492356 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -104,7 +104,7 @@ pub struct StdinReader { inner: Arc>>, } -/// A guard for exlusive access to `StdinReader`'s internal `BufferedReader`. +/// A guard for exclusive access to `StdinReader`'s internal `BufferedReader`. pub struct StdinReaderGuard<'a> { inner: MutexGuard<'a, BufferedReader>, } From 44f6f52578d5711ba8f395c8d5da577bb3c5fe15 Mon Sep 17 00:00:00 2001 From: Tom Jakubowski Date: Sat, 20 Dec 2014 09:29:38 -0800 Subject: [PATCH 50/58] metadata: Encode attrs for foreign items. Related to #19649 and #16289 --- src/librustc/metadata/encoder.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index deb86397eda..8eb902f0797 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1478,6 +1478,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, if abi == abi::RustIntrinsic { encode_inlined_item(ecx, rbml_w, IIForeignRef(nitem)); } + encode_attributes(rbml_w, &*nitem.attrs); encode_symbol(ecx, rbml_w, nitem.id); } ast::ForeignItemStatic(_, mutbl) => { @@ -1488,6 +1489,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, } encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(ecx.tcx,local_def(nitem.id))); + encode_attributes(rbml_w, &*nitem.attrs); encode_symbol(ecx, rbml_w, nitem.id); encode_name(rbml_w, nitem.ident.name); } From cc33ce6fd07467bca1006823ae7336e84054726c Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sat, 20 Dec 2014 17:17:58 +0000 Subject: [PATCH 51/58] Add String::push_with_ascii_fast_path, bench it against String::push `String::push(&mut self, ch: char)` currently has a single code path that calls `Char::encode_utf8`. Perhaps it could be faster for ASCII `char`s, which are represented as a single byte in UTF-8. This commit leaves the method unchanged, adds a copy of it with the fast path, and adds benchmarks to compare them. Results show that the fast path very significantly improves the performance of repeatedly pushing an ASCII `char`, but does not significantly affect the performance for a non-ASCII `char` (where the fast path is not taken). Output of `make check-stage1-collections NO_REBUILD=1 PLEASE_BENCH=1 TESTNAME=string::tests::bench_push` ``` test string::tests::bench_push_char_one_byte ... bench: 59552 ns/iter (+/- 2132) = 167 MB/s test string::tests::bench_push_char_one_byte_with_fast_path ... bench: 6563 ns/iter (+/- 658) = 1523 MB/s test string::tests::bench_push_char_two_bytes ... bench: 71520 ns/iter (+/- 3541) = 279 MB/s test string::tests::bench_push_char_two_bytes_with_slow_path ... bench: 71452 ns/iter (+/- 4202) = 279 MB/s test string::tests::bench_push_str ... bench: 24 ns/iter (+/- 2) test string::tests::bench_push_str_one_byte ... bench: 38910 ns/iter (+/- 2477) = 257 MB/s ``` A benchmark of pushing a one-byte-long `&str` is added for comparison, but its performance [has varied a lot lately]( https://github.com/rust-lang/rust/pull/19640#issuecomment-67741561). (When the input is fixed, `s.push_str("x")` could be used instead of `s.push('x')`.) --- src/libcollections/string.rs | 80 ++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index bcd1e3b3680..d894f0b58d9 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -528,6 +528,29 @@ impl String { } } + #[inline] + fn push_with_ascii_fast_path(&mut self, ch: char) { + if (ch as u32) < 0x80 { + self.vec.push(ch as u8); + return; + } + + let cur_len = self.len(); + // This may use up to 4 bytes. + self.vec.reserve(4); + + unsafe { + // Attempt to not use an intermediate buffer by just pushing bytes + // directly onto this string. + let slice = RawSlice { + data: self.vec.as_ptr().offset(cur_len as int), + len: 4, + }; + let used = ch.encode_utf8(mem::transmute(slice)).unwrap_or(0); + self.vec.set_len(cur_len + used); + } + } + /// Works with the underlying buffer as a byte slice. /// /// # Examples @@ -1408,6 +1431,63 @@ mod tests { }); } + const REPETITIONS: u64 = 10_000; + + #[bench] + fn bench_push_str_one_byte(b: &mut Bencher) { + b.bytes = REPETITIONS; + b.iter(|| { + let mut r = String::new(); + for _ in range(0, REPETITIONS) { + r.push_str("a") + } + }); + } + + #[bench] + fn bench_push_char_one_byte(b: &mut Bencher) { + b.bytes = REPETITIONS; + b.iter(|| { + let mut r = String::new(); + for _ in range(0, REPETITIONS) { + r.push('a') + } + }); + } + + #[bench] + fn bench_push_char_one_byte_with_fast_path(b: &mut Bencher) { + b.bytes = REPETITIONS; + b.iter(|| { + let mut r = String::new(); + for _ in range(0, REPETITIONS) { + r.push_with_ascii_fast_path('a') + } + }); + } + + #[bench] + fn bench_push_char_two_bytes(b: &mut Bencher) { + b.bytes = REPETITIONS * 2; + b.iter(|| { + let mut r = String::new(); + for _ in range(0, REPETITIONS) { + r.push('â') + } + }); + } + + #[bench] + fn bench_push_char_two_bytes_with_slow_path(b: &mut Bencher) { + b.bytes = REPETITIONS * 2; + b.iter(|| { + let mut r = String::new(); + for _ in range(0, REPETITIONS) { + r.push_with_ascii_fast_path('â') + } + }); + } + #[bench] fn from_utf8_lossy_100_ascii(b: &mut Bencher) { let s = b"Hello there, the quick brown fox jumped over the lazy dog! \ From e40a81b37bf11ae6f7fc3294ac17230eabaaab03 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sat, 20 Dec 2014 17:29:02 +0000 Subject: [PATCH 52/58] Merge String::push_with_ascii_fast_path into String::push. --- src/libcollections/string.rs | 40 ------------------------------------ 1 file changed, 40 deletions(-) diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index d894f0b58d9..678e81d40b4 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -512,24 +512,6 @@ impl String { #[inline] #[stable = "function just renamed from push_char"] pub fn push(&mut self, ch: char) { - let cur_len = self.len(); - // This may use up to 4 bytes. - self.vec.reserve(4); - - unsafe { - // Attempt to not use an intermediate buffer by just pushing bytes - // directly onto this string. - let slice = RawSlice { - data: self.vec.as_ptr().offset(cur_len as int), - len: 4, - }; - let used = ch.encode_utf8(mem::transmute(slice)).unwrap_or(0); - self.vec.set_len(cur_len + used); - } - } - - #[inline] - fn push_with_ascii_fast_path(&mut self, ch: char) { if (ch as u32) < 0x80 { self.vec.push(ch as u8); return; @@ -1455,17 +1437,6 @@ mod tests { }); } - #[bench] - fn bench_push_char_one_byte_with_fast_path(b: &mut Bencher) { - b.bytes = REPETITIONS; - b.iter(|| { - let mut r = String::new(); - for _ in range(0, REPETITIONS) { - r.push_with_ascii_fast_path('a') - } - }); - } - #[bench] fn bench_push_char_two_bytes(b: &mut Bencher) { b.bytes = REPETITIONS * 2; @@ -1477,17 +1448,6 @@ mod tests { }); } - #[bench] - fn bench_push_char_two_bytes_with_slow_path(b: &mut Bencher) { - b.bytes = REPETITIONS * 2; - b.iter(|| { - let mut r = String::new(); - for _ in range(0, REPETITIONS) { - r.push_with_ascii_fast_path('â') - } - }); - } - #[bench] fn from_utf8_lossy_100_ascii(b: &mut Bencher) { let s = b"Hello there, the quick brown fox jumped over the lazy dog! \ From fb9b45189effece40b2b672fc4fd3b01e15f19cb Mon Sep 17 00:00:00 2001 From: Tom Jakubowski Date: Sat, 20 Dec 2014 10:08:16 -0800 Subject: [PATCH 53/58] Visit + encode stability for foreign items Fix #19649 --- src/librustc/metadata/encoder.rs | 4 ++++ src/librustc/middle/stability.rs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 8eb902f0797..e5dae926db9 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1479,6 +1479,8 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, encode_inlined_item(ecx, rbml_w, IIForeignRef(nitem)); } encode_attributes(rbml_w, &*nitem.attrs); + let stab = stability::lookup(ecx.tcx, ast_util::local_def(nitem.id)); + encode_stability(rbml_w, stab); encode_symbol(ecx, rbml_w, nitem.id); } ast::ForeignItemStatic(_, mutbl) => { @@ -1490,6 +1492,8 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(ecx.tcx,local_def(nitem.id))); encode_attributes(rbml_w, &*nitem.attrs); + let stab = stability::lookup(ecx.tcx, ast_util::local_def(nitem.id)); + encode_stability(rbml_w, stab); encode_symbol(ecx, rbml_w, nitem.id); encode_name(rbml_w, nitem.ident.name); } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index ca8029fdfca..3e874f46a33 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -111,6 +111,10 @@ impl<'v> Visitor<'v> for Annotator { fn visit_struct_field(&mut self, s: &StructField) { self.annotate(s.node.id, &s.node.attrs, |v| visit::walk_struct_field(v, s)); } + + fn visit_foreign_item(&mut self, i: &ast::ForeignItem) { + self.annotate(i.id, &i.attrs, |_| {}); + } } impl Index { From bffd802a3fa10e3e56a84e214fc099f297a40930 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Sat, 20 Dec 2014 17:13:13 -0500 Subject: [PATCH 54/58] Fix small typos in std::rand documentation --- src/libstd/rand/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs index 0035e5747aa..c590c0f575e 100644 --- a/src/libstd/rand/mod.rs +++ b/src/libstd/rand/mod.rs @@ -45,7 +45,7 @@ //! so the "quality" of `/dev/random` is not better than `/dev/urandom` in most cases. //! However, this means that `/dev/urandom` can yield somewhat predictable randomness //! if the entropy pool is very small, such as immediately after first booting. -//! Linux 3,17 added `getrandom(2)` system call which solves the issue: it blocks if entropy +//! Linux 3.17 added the `getrandom(2)` system call which solves the issue: it blocks if entropy //! pool is not initialized yet, but it does not block once initialized. //! `OsRng` tries to use `getrandom(2)` if available, and use `/dev/urandom` fallback if not. //! If an application does not have `getrandom` and likely to be run soon after first booting, @@ -126,7 +126,7 @@ //! > Is it to your advantage to switch your choice? //! //! The rather unintuitive answer is that you will have a 2/3 chance of winning if -//! you switch and a 1/3 chance of winning of you don't, so it's better to switch. +//! you switch and a 1/3 chance of winning if you don't, so it's better to switch. //! //! This program will simulate the game show and with large enough simulation steps //! it will indeed confirm that it is better to switch. From 98af642f5c8f60ae141a5d3ff92e8cc4e4317342 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 13 Dec 2014 11:15:18 -0500 Subject: [PATCH 55/58] Remove a ton of public reexports Remove most of the public reexports mentioned in #19253 These are all leftovers from the enum namespacing transition In particular: * src/libstd/num/strconv.rs * ExponentFormat * SignificantDigits * SignFormat * src/libstd/path/windows.rs * PathPrefix * src/libstd/sys/windows/timer.rs * Req * src/libcollections/str.rs * MaybeOwned * src/libstd/collections/hash/map.rs * Entry * src/libstd/collections/hash/table.rs * BucketState * src/libstd/dynamic_lib.rs * Rtld * src/libstd/io/net/ip.rs * IpAddr * src/libstd/os.rs * MemoryMapKind * MapOption * MapError * src/libstd/sys/common/net.rs * SocketStatus * InAddr * src/libstd/sys/unix/timer.rs * Req [breaking-change] --- src/compiletest/runtest.rs | 2 +- src/libcollections/str.rs | 4 ++-- src/libcollections/string.rs | 3 ++- src/librustc/lint/builtin.rs | 2 +- src/librustc/metadata/creader.rs | 2 +- src/librustc/metadata/loader.rs | 2 +- src/librustc/middle/const_eval.rs | 2 +- src/librustc/middle/infer/freshen.rs | 6 +++--- .../middle/infer/region_inference/graphviz.rs | 2 +- src/librustc/middle/traits/fulfill.rs | 2 +- src/librustc/middle/ty.rs | 3 ++- src/librustc/session/config.rs | 2 +- src/librustc_resolve/lib.rs | 2 +- src/librustc_typeck/check/_match.rs | 2 +- src/librustc_typeck/check/regionck.rs | 2 +- src/librustdoc/html/render.rs | 2 +- src/librustdoc/lib.rs | 2 +- src/libstd/collections/hash/map.rs | 17 ++++++++++------- src/libstd/collections/hash/table.rs | 2 +- src/libstd/dynamic_lib.rs | 2 +- src/libstd/num/f32.rs | 18 ++++++++++-------- src/libstd/num/f64.rs | 18 ++++++++++-------- src/libstd/num/strconv.rs | 6 +++--- src/libstd/os.rs | 18 +++++++++--------- src/libstd/path/windows.rs | 3 ++- src/libstd/sys/common/net.rs | 4 ++-- src/libstd/sys/unix/pipe.rs | 1 + src/libstd/sys/unix/tcp.rs | 3 ++- src/libstd/sys/unix/timer.rs | 2 +- src/libstd/sys/windows/timer.rs | 2 +- src/libsyntax/ext/mtwt.rs | 2 +- src/libsyntax/ext/tt/macro_parser.rs | 2 +- src/libtest/stats.rs | 2 +- src/test/run-pass/exponential-notation.rs | 14 ++++++++------ 34 files changed, 86 insertions(+), 72 deletions(-) diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 1457d1de7d5..567734b0dab 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -1609,7 +1609,7 @@ fn _arm_exec_compiled_test(config: &Config, stderr_out.as_slice()); ProcRes { - status: process::ExitStatus(exitcode), + status: process::ProcessExit::ExitStatus(exitcode), stdout: stdout_out, stderr: stderr_out, cmdline: cmdline diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index feec2a216c7..bb03575b3ac 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -51,7 +51,7 @@ #![doc(primitive = "str")] -pub use self::MaybeOwned::*; +use self::MaybeOwned::*; use self::RecompositionState::*; use self::DecompositionType::*; @@ -842,7 +842,7 @@ mod tests { use core::iter::AdditiveIterator; use super::{eq_slice, from_utf8, is_utf8, is_utf16, raw}; use super::truncate_utf16_at_nul; - use super::{Owned, Slice}; + use super::MaybeOwned::{Owned, Slice}; #[test] fn test_eq_slice() { diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index bcd1e3b3680..edd96dd683f 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -26,7 +26,8 @@ use core::raw::Slice as RawSlice; use slice::CloneSliceExt; use str; -use str::{CharRange, CowString, FromStr, StrAllocating, Owned}; +use str::{CharRange, CowString, FromStr, StrAllocating}; +use str::MaybeOwned::Owned; use vec::{DerefVec, Vec, as_vec}; /// A growable string stored as a UTF-8 encoded buffer. diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 88b12aa5660..aad3cdf8b4a 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -37,7 +37,7 @@ use util::nodemap::{FnvHashMap, NodeSet}; use lint::{Context, LintPass, LintArray}; use std::{cmp, slice}; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::num::SignedInt; use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64}; use syntax::{abi, ast, ast_map}; diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 9e87153e64a..323b084afdc 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -23,7 +23,7 @@ use plugin::load::PluginMetadata; use util::nodemap::FnvHashMap; use std::rc::Rc; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; use syntax::ast; use syntax::abi; use syntax::attr; diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index e83f69b1e31..bc34b0b45e9 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -228,7 +228,7 @@ use util::fs; use std::c_str::ToCStr; use std::cmp; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::{HashMap, HashSet}; use std::io::fs::PathExtensions; use std::io; diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 9b943356547..62f1a30f8e7 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -28,7 +28,7 @@ use syntax::visit::{mod, Visitor}; use syntax::{ast_map, ast_util, codemap}; use std::rc::Rc; -use std::collections::hash_map::Vacant; +use std::collections::hash_map::Entry::Vacant; // // This pass classifies expressions by their constant-ness. diff --git a/src/librustc/middle/infer/freshen.rs b/src/librustc/middle/infer/freshen.rs index ebff854060c..a8bf7546559 100644 --- a/src/librustc/middle/infer/freshen.rs +++ b/src/librustc/middle/infer/freshen.rs @@ -34,7 +34,7 @@ use middle::ty::{mod, Ty}; use middle::ty_fold; use middle::ty_fold::TypeFoldable; use middle::ty_fold::TypeFolder; -use std::collections::hash_map; +use std::collections::hash_map::{mod, Entry}; use super::InferCtxt; use super::unify::InferCtxtMethodsForSimplyUnifiableTypes; @@ -67,8 +67,8 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { } match self.freshen_map.entry(key) { - hash_map::Occupied(entry) => *entry.get(), - hash_map::Vacant(entry) => { + Entry::Occupied(entry) => *entry.get(), + Entry::Vacant(entry) => { let index = self.freshen_count; self.freshen_count += 1; let t = ty::mk_infer(self.infcx.tcx, freshener(index)); diff --git a/src/librustc/middle/infer/region_inference/graphviz.rs b/src/librustc/middle/infer/region_inference/graphviz.rs index 720de357a27..3e55f6fa896 100644 --- a/src/librustc/middle/infer/region_inference/graphviz.rs +++ b/src/librustc/middle/infer/region_inference/graphviz.rs @@ -26,7 +26,7 @@ use session::config; use util::nodemap::{FnvHashMap, FnvHashSet}; use util::ppaux::Repr; -use std::collections::hash_map::Vacant; +use std::collections::hash_map::Entry::Vacant; use std::io::{mod, File}; use std::os; use std::sync::atomic; diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index 213d97b4b34..72e4eb5d1d6 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -12,7 +12,7 @@ use middle::infer::InferCtxt; use middle::mem_categorization::Typer; use middle::ty::{mod, Ty}; use std::collections::HashSet; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::default::Default; use std::rc::Rc; use syntax::ast; diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index d5c97bd6aa6..c2edcf1e3e2 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -77,7 +77,8 @@ use std::mem; use std::ops; use std::rc::Rc; use collections::enum_set::{EnumSet, CLike}; -use std::collections::hash_map::{HashMap, Occupied, Vacant}; +use std::collections::hash_map::HashMap; +use std::collections::hash_map::Entry::{Occupied, Vacant}; use syntax::abi; use syntax::ast::{CrateNum, DefId, DUMMY_NODE_ID, Ident, ItemTrait, LOCAL_CRATE}; use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId}; diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 25cdeb83d85..0652645907b 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -33,7 +33,7 @@ use syntax::parse; use syntax::parse::token::InternedString; use std::collections::HashMap; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; use getopts::{optopt, optmulti, optflag, optflagopt}; use getopts; use std::cell::{RefCell}; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 99f0a6cdfc3..ac8d5d1e977 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -90,7 +90,7 @@ use syntax::owned_slice::OwnedSlice; use syntax::visit::{mod, Visitor}; use std::collections::{HashMap, HashSet}; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::cell::{Cell, RefCell}; use std::mem::replace; use std::rc::{Rc, Weak}; diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 44cc5fce53d..081faaac1d7 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -21,7 +21,7 @@ use util::nodemap::FnvHashMap; use util::ppaux::Repr; use std::cmp; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; use syntax::ast; use syntax::ast_util; use syntax::codemap::{Span, Spanned}; diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 33c015a9a08..8e70b8ff0da 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -135,7 +135,7 @@ use syntax::visit; use syntax::visit::Visitor; use std::cell::{RefCell}; -use std::collections::hash_map::{Vacant, Occupied}; +use std::collections::hash_map::Entry::{Vacant, Occupied}; use self::RepeatingScope::Repeating; use self::SubjectNode::Subject; diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 8831b5e7d96..efec620bca7 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -35,7 +35,7 @@ pub use self::ExternalLocation::*; use std::cell::RefCell; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::{HashMap, HashSet}; use std::default::Default; use std::fmt; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 0f4968162be..182c83d805c 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -34,7 +34,7 @@ extern crate "test" as testing; use std::cell::RefCell; use std::collections::HashMap; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::io::File; use std::io; use std::rc::Rc; diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 0b04edf6776..c32fec67d66 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -10,7 +10,7 @@ // // ignore-lexer-test FIXME #15883 -pub use self::Entry::*; +use self::Entry::*; use self::SearchResult::*; use self::VacantEntryState::*; @@ -30,18 +30,20 @@ use option::Option::{Some, None}; use result::Result; use result::Result::{Ok, Err}; -use super::table; use super::table::{ + mod, Bucket, - Empty, EmptyBucket, - Full, FullBucket, FullBucketImm, FullBucketMut, RawTable, SafeHash }; +use super::table::BucketState::{ + Empty, + Full, +}; const INITIAL_LOG2_CAP: uint = 5; pub const INITIAL_CAPACITY: uint = 1 << INITIAL_LOG2_CAP; // 2^5 @@ -379,7 +381,7 @@ fn robin_hood<'a, K: 'a, V: 'a>(mut bucket: FullBucketMut<'a, K, V>, assert!(probe.index() != idx_end); let full_bucket = match probe.peek() { - table::Empty(bucket) => { + Empty(bucket) => { // Found a hole! let b = bucket.put(old_hash, old_key, old_val); // Now that it's stolen, just read the value's pointer @@ -390,7 +392,7 @@ fn robin_hood<'a, K: 'a, V: 'a>(mut bucket: FullBucketMut<'a, K, V>, .into_mut_refs() .1; }, - table::Full(bucket) => bucket + Full(bucket) => bucket }; let probe_ib = full_bucket.index() - full_bucket.distance(); @@ -1470,7 +1472,8 @@ mod test_map { use prelude::*; use super::HashMap; - use super::{Occupied, Vacant}; + use super::Entry::{Occupied, Vacant}; + use cmp::Equiv; use hash; use iter::{range_inclusive, range_step_inclusive}; use cell::RefCell; diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 115edcabca1..ce7dbd8ea5e 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -10,7 +10,7 @@ // // ignore-lexer-test FIXME #15883 -pub use self::BucketState::*; +use self::BucketState::*; use clone::Clone; use cmp; diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs index e520c70824e..4d8c7d67b8c 100644 --- a/src/libstd/dynamic_lib.rs +++ b/src/libstd/dynamic_lib.rs @@ -200,7 +200,7 @@ mod test { target_os = "freebsd", target_os = "dragonfly"))] pub mod dl { - pub use self::Rtld::*; + use self::Rtld::*; use prelude::*; use c_str::CString; diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index d307e1f7415..951627b26ca 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -21,6 +21,9 @@ use intrinsics; use libc::c_int; use num::{Float, FloatMath}; use num::strconv; +use num::strconv::ExponentFormat::{ExpNone, ExpDec}; +use num::strconv::SignificantDigits::{DigAll, DigMax, DigExact}; +use num::strconv::SignFormat::SignNeg; pub use core::f32::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE}; pub use core::f32::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP}; @@ -252,7 +255,7 @@ impl FloatMath for f32 { #[experimental = "may be removed or relocated"] pub fn to_string(num: f32) -> String { let (r, _) = strconv::float_to_str_common( - num, 10u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false); + num, 10u, true, SignNeg, DigAll, ExpNone, false); r } @@ -265,7 +268,7 @@ pub fn to_string(num: f32) -> String { #[experimental = "may be removed or relocated"] pub fn to_str_hex(num: f32) -> String { let (r, _) = strconv::float_to_str_common( - num, 16u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false); + num, 16u, true, SignNeg, DigAll, ExpNone, false); r } @@ -279,8 +282,7 @@ pub fn to_str_hex(num: f32) -> String { #[inline] #[experimental = "may be removed or relocated"] pub fn to_str_radix_special(num: f32, rdx: uint) -> (String, bool) { - strconv::float_to_str_common(num, rdx, true, - strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false) + strconv::float_to_str_common(num, rdx, true, SignNeg, DigAll, ExpNone, false) } /// Converts a float to a string with exactly the number of @@ -294,7 +296,7 @@ pub fn to_str_radix_special(num: f32, rdx: uint) -> (String, bool) { #[experimental = "may be removed or relocated"] pub fn to_str_exact(num: f32, dig: uint) -> String { let (r, _) = strconv::float_to_str_common( - num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpNone, false); + num, 10u, true, SignNeg, DigExact(dig), ExpNone, false); r } @@ -309,7 +311,7 @@ pub fn to_str_exact(num: f32, dig: uint) -> String { #[experimental = "may be removed or relocated"] pub fn to_str_digits(num: f32, dig: uint) -> String { let (r, _) = strconv::float_to_str_common( - num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpNone, false); + num, 10u, true, SignNeg, DigMax(dig), ExpNone, false); r } @@ -325,7 +327,7 @@ pub fn to_str_digits(num: f32, dig: uint) -> String { #[experimental = "may be removed or relocated"] pub fn to_str_exp_exact(num: f32, dig: uint, upper: bool) -> String { let (r, _) = strconv::float_to_str_common( - num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpDec, upper); + num, 10u, true, SignNeg, DigExact(dig), ExpDec, upper); r } @@ -341,7 +343,7 @@ pub fn to_str_exp_exact(num: f32, dig: uint, upper: bool) -> String { #[experimental = "may be removed or relocated"] pub fn to_str_exp_digits(num: f32, dig: uint, upper: bool) -> String { let (r, _) = strconv::float_to_str_common( - num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpDec, upper); + num, 10u, true, SignNeg, DigMax(dig), ExpDec, upper); r } diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index dfe20d59c82..7cc94b9ebbb 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -20,6 +20,9 @@ use intrinsics; use libc::c_int; use num::{Float, FloatMath}; use num::strconv; +use num::strconv::ExponentFormat::{ExpNone, ExpDec}; +use num::strconv::SignificantDigits::{DigAll, DigMax, DigExact}; +use num::strconv::SignFormat::SignNeg; pub use core::f64::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE}; pub use core::f64::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP}; @@ -260,7 +263,7 @@ impl FloatMath for f64 { #[experimental = "may be removed or relocated"] pub fn to_string(num: f64) -> String { let (r, _) = strconv::float_to_str_common( - num, 10u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false); + num, 10u, true, SignNeg, DigAll, ExpNone, false); r } @@ -273,7 +276,7 @@ pub fn to_string(num: f64) -> String { #[experimental = "may be removed or relocated"] pub fn to_str_hex(num: f64) -> String { let (r, _) = strconv::float_to_str_common( - num, 16u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false); + num, 16u, true, SignNeg, DigAll, ExpNone, false); r } @@ -287,8 +290,7 @@ pub fn to_str_hex(num: f64) -> String { #[inline] #[experimental = "may be removed or relocated"] pub fn to_str_radix_special(num: f64, rdx: uint) -> (String, bool) { - strconv::float_to_str_common(num, rdx, true, - strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false) + strconv::float_to_str_common(num, rdx, true, SignNeg, DigAll, ExpNone, false) } /// Converts a float to a string with exactly the number of @@ -302,7 +304,7 @@ pub fn to_str_radix_special(num: f64, rdx: uint) -> (String, bool) { #[experimental = "may be removed or relocated"] pub fn to_str_exact(num: f64, dig: uint) -> String { let (r, _) = strconv::float_to_str_common( - num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpNone, false); + num, 10u, true, SignNeg, DigExact(dig), ExpNone, false); r } @@ -317,7 +319,7 @@ pub fn to_str_exact(num: f64, dig: uint) -> String { #[experimental = "may be removed or relocated"] pub fn to_str_digits(num: f64, dig: uint) -> String { let (r, _) = strconv::float_to_str_common( - num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpNone, false); + num, 10u, true, SignNeg, DigMax(dig), ExpNone, false); r } @@ -333,7 +335,7 @@ pub fn to_str_digits(num: f64, dig: uint) -> String { #[experimental = "may be removed or relocated"] pub fn to_str_exp_exact(num: f64, dig: uint, upper: bool) -> String { let (r, _) = strconv::float_to_str_common( - num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpDec, upper); + num, 10u, true, SignNeg, DigExact(dig), ExpDec, upper); r } @@ -349,7 +351,7 @@ pub fn to_str_exp_exact(num: f64, dig: uint, upper: bool) -> String { #[experimental = "may be removed or relocated"] pub fn to_str_exp_digits(num: f64, dig: uint, upper: bool) -> String { let (r, _) = strconv::float_to_str_common( - num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpDec, upper); + num, 10u, true, SignNeg, DigMax(dig), ExpDec, upper); r } diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index 016c4bd532a..b3e4dd52f89 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -12,9 +12,9 @@ #![allow(missing_docs)] -pub use self::ExponentFormat::*; -pub use self::SignificantDigits::*; -pub use self::SignFormat::*; +use self::ExponentFormat::*; +use self::SignificantDigits::*; +use self::SignFormat::*; use char::{mod, Char}; use num::{mod, Int, Float, FPNaN, FPInfinite, ToPrimitive}; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 20a72f45fbf..258e8964a9f 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -28,9 +28,9 @@ #![allow(non_snake_case)] #![allow(unused_imports)] -pub use self::MemoryMapKind::*; -pub use self::MapOption::*; -pub use self::MapError::*; +use self::MemoryMapKind::*; +use self::MapOption::*; +use self::MapError::*; use clone::Clone; use error::{FromError, Error}; @@ -1617,8 +1617,8 @@ mod tests { use result::Result::{Ok, Err}; let chunk = match os::MemoryMap::new(16, &[ - os::MapReadable, - os::MapWritable + os::MapOption::MapReadable, + os::MapOption::MapWritable ]) { Ok(chunk) => chunk, Err(msg) => panic!("{}", msg) @@ -1660,10 +1660,10 @@ mod tests { file.write_u8(0); let chunk = MemoryMap::new(size / 2, &[ - MapReadable, - MapWritable, - MapFd(get_fd(&file)), - MapOffset(size / 2) + MapOption::MapReadable, + MapOption::MapWritable, + MapOption::MapFd(get_fd(&file)), + MapOption::MapOffset(size / 2) ]).unwrap(); assert!(chunk.len > 0); diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index b498b3e8ad0..c2c17103554 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -12,7 +12,7 @@ //! Windows file path handling -pub use self::PathPrefix::*; +use self::PathPrefix::*; use ascii::AsciiCast; use c_str::{CString, ToCStr}; @@ -1117,6 +1117,7 @@ fn prefix_len(p: Option) -> uint { mod tests { use prelude::*; use super::*; + use super::PathPrefix::*; use super::parse_prefix; macro_rules! t { diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index 73da200e162..382f6875b28 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub use self::SocketStatus::*; -pub use self::InAddr::*; +use self::SocketStatus::*; +use self::InAddr::*; use alloc::arc::Arc; use libc::{mod, c_char, c_int}; diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index 26fd410a7a9..348b7cfad33 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -19,6 +19,7 @@ use prelude::*; use sys::{mod, timer, retry, c, set_nonblocking, wouldblock}; use sys::fs::{fd_t, FileDesc}; use sys_common::net::*; +use sys_common::net::SocketStatus::*; use sys_common::{eof, mkerr_libc}; fn unix_socket(ty: libc::c_int) -> IoResult { diff --git a/src/libstd/sys/unix/tcp.rs b/src/libstd/sys/unix/tcp.rs index dacd754582b..5c99ad1e0ce 100644 --- a/src/libstd/sys/unix/tcp.rs +++ b/src/libstd/sys/unix/tcp.rs @@ -21,6 +21,7 @@ use sys::{set_nonblocking, wouldblock}; use sys; use sys_common; use sys_common::net; +use sys_common::net::SocketStatus::Readable; pub use sys_common::net::TcpStream; @@ -124,7 +125,7 @@ impl TcpAcceptor { fd => return Ok(TcpStream::new(fd as sock_t)), } try!(net::await(&[self.fd(), self.inner.reader.fd()], - deadline, net::Readable)); + deadline, Readable)); } Err(sys_common::eof()) diff --git a/src/libstd/sys/unix/timer.rs b/src/libstd/sys/unix/timer.rs index 79a6a871f8d..fe393b81e3d 100644 --- a/src/libstd/sys/unix/timer.rs +++ b/src/libstd/sys/unix/timer.rs @@ -46,7 +46,7 @@ //! //! Note that all time units in this file are in *milliseconds*. -pub use self::Req::*; +use self::Req::*; use libc; use mem; diff --git a/src/libstd/sys/windows/timer.rs b/src/libstd/sys/windows/timer.rs index e2f9e2a9201..7e4dd768aa9 100644 --- a/src/libstd/sys/windows/timer.rs +++ b/src/libstd/sys/windows/timer.rs @@ -20,7 +20,7 @@ //! Other than that, the implementation is pretty straightforward in terms of //! the other two implementations of timers with nothing *that* new showing up. -pub use self::Req::*; +use self::Req::*; use libc; use ptr; diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs index ae979020bc7..f0392912878 100644 --- a/src/libsyntax/ext/mtwt.rs +++ b/src/libsyntax/ext/mtwt.rs @@ -21,7 +21,7 @@ use ast::{Ident, Mrk, Name, SyntaxContext}; use std::cell::RefCell; use std::collections::HashMap; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; /// The SCTable contains a table of SyntaxContext_'s. It /// represents a flattened tree structure, to avoid having diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 4785fe37293..bc639c32380 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -98,7 +98,7 @@ use ptr::P; use std::mem; use std::rc::Rc; use std::collections::HashMap; -use std::collections::hash_map::{Vacant, Occupied}; +use std::collections::hash_map::Entry::{Vacant, Occupied}; // To avoid costly uniqueness checks, we require that `MatchSeq` always has // a nonempty body. diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs index 7441b39f35b..41146cded70 100644 --- a/src/libtest/stats.rs +++ b/src/libtest/stats.rs @@ -11,7 +11,7 @@ #![allow(missing_docs)] use std::collections::hash_map; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::fmt::Show; use std::hash::Hash; use std::io; diff --git a/src/test/run-pass/exponential-notation.rs b/src/test/run-pass/exponential-notation.rs index f63ab7fb7c9..38d10937624 100644 --- a/src/test/run-pass/exponential-notation.rs +++ b/src/test/run-pass/exponential-notation.rs @@ -10,25 +10,27 @@ #![feature(macro_rules)] -use std::num::strconv as s; +use std::num::strconv::ExponentFormat::{ExpBin, ExpDec}; +use std::num::strconv::SignificantDigits::DigMax; +use std::num::strconv::SignFormat::{SignAll, SignNeg}; use std::num::strconv::float_to_str_common as to_string; macro_rules! t(($a:expr, $b:expr) => { { let (r, _) = $a; assert_eq!(r, $b.to_string()); } }); pub fn main() { // Basic usage - t!(to_string(1.2345678e-5f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpDec, false), + t!(to_string(1.2345678e-5f64, 10u, true, SignNeg, DigMax(6), ExpDec, false), "1.234568e-5"); // Hexadecimal output - t!(to_string(7.281738281250e+01f64, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false), + t!(to_string(7.281738281250e+01f64, 16u, true, SignAll, DigMax(6), ExpBin, false), "+1.2345p+6"); - t!(to_string(-1.777768135071e-02f64, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false), + t!(to_string(-1.777768135071e-02f64, 16u, true, SignAll, DigMax(6), ExpBin, false), "-1.2345p-6"); // Some denormals - t!(to_string(4.9406564584124654e-324f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false), + t!(to_string(4.9406564584124654e-324f64, 10u, true, SignNeg, DigMax(6), ExpBin, false), "1p-1074"); - t!(to_string(2.2250738585072009e-308f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false), + t!(to_string(2.2250738585072009e-308f64, 10u, true, SignNeg, DigMax(6), ExpBin, false), "1p-1022"); } From 1c80446d1b7b55b9e59d718e299d53a22df99c5d Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Sun, 21 Dec 2014 00:37:07 +0100 Subject: [PATCH 56/58] Create a snapshot for 8443b09 --- src/snapshots.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/snapshots.txt b/src/snapshots.txt index 071d9f758eb..653097e8993 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -1,3 +1,12 @@ +S 2014-12-20 8443b09 + freebsd-x86_64 004f54dce86faeebc15abf92c8742634b53987e6 + linux-i386 3daf531aed03f5769402f2fef852377e2838db98 + linux-x86_64 4f3c8b092dd4fe159d6f25a217cf62e0e899b365 + macos-i386 2a3e647b9c400505bd49cfe56091e866c83574ca + macos-x86_64 78f952a3e77a9921a23c957bb133131017b57324 + winnt-i386 8ea056043de82096d5ce5abc98c8c74ebac7e77d + winnt-x86_64 9804100dafae9b64a76e0ea7e1be157719dae151 + S 2014-12-15 1b97cd3 freebsd-x86_64 a5d7ff81ec04e01e64dc201c7aa2d875ebd0cbbb linux-i386 47e13c2f1d26a0d13e593e0881a80ca103aa7b2e From a666105b4c273d128a0a15c3342412c69c89fb98 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 20 Dec 2014 23:21:27 -0800 Subject: [PATCH 57/58] std: Don't parse argv as a String Instead, just pass everything through as a Vec to get worried about later. Closes #20091 --- src/libstd/rt/args.rs | 13 ++++++++----- src/test/run-pass/issue-20091.rs | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 src/test/run-pass/issue-20091.rs diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs index 3a4705f58b4..b1f268597c7 100644 --- a/src/libstd/rt/args.rs +++ b/src/libstd/rt/args.rs @@ -44,12 +44,10 @@ pub fn clone() -> Option>> { imp::clone() } target_os = "freebsd", target_os = "dragonfly"))] mod imp { - use core::prelude::*; + use prelude::*; - use boxed::Box; - use vec::Vec; - use string::String; use mem; + use slice; use sync::{StaticMutex, MUTEX_INIT}; @@ -98,7 +96,12 @@ mod imp { unsafe fn load_argc_and_argv(argc: int, argv: *const *const u8) -> Vec> { Vec::from_fn(argc as uint, |i| { - String::from_raw_buf(*argv.offset(i as int)).into_bytes() + let arg = *argv.offset(i as int); + let mut len = 0u; + while *arg.offset(len as int) != 0 { + len += 1u; + } + slice::from_raw_buf(&arg, len).to_vec() }) } diff --git a/src/test/run-pass/issue-20091.rs b/src/test/run-pass/issue-20091.rs new file mode 100644 index 00000000000..daf898faef7 --- /dev/null +++ b/src/test/run-pass/issue-20091.rs @@ -0,0 +1,19 @@ +// Copyright 2012-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. + +use std::io::Command; +use std::os; + +fn main() { + if os::args().len() == 1 { + assert!(Command::new(os::self_exe_name().unwrap()).arg(b"\xff") + .status().unwrap().success()) + } +} From fb7c08876e7b29c1b9d57df905f3ee0deec46aa1 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 21 Dec 2014 00:12:56 -0800 Subject: [PATCH 58/58] Test fixes and rebase conflicts --- mk/tests.mk | 2 +- src/liballoc/arc.rs | 15 ++++++++------- src/libcollections/vec.rs | 1 + src/librustc/middle/stability.rs | 2 +- src/librustc/util/ppaux.rs | 2 ++ src/libstd/collections/hash/map.rs | 1 - src/snapshots.txt | 2 +- src/test/compile-fail/issue-13359.rs | 4 ++-- src/test/run-pass/issue-20091.rs | 2 ++ 9 files changed, 18 insertions(+), 13 deletions(-) diff --git a/mk/tests.mk b/mk/tests.mk index 3d66ce86d7b..1a122572e43 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -285,7 +285,7 @@ tidy: | xargs -n 10 $(CFG_PYTHON) $(S)src/etc/tidy.py $(Q)echo $(ALL_HS) \ | xargs -n 10 $(CFG_PYTHON) $(S)src/etc/tidy.py - $(Q)find $(S)src -type f -perm /a+x \ + $(Q)find $(S)src -type f -perm +a+x \ -not -name '*.rs' -and -not -name '*.py' \ -and -not -name '*.sh' \ | grep '^$(S)src/jemalloc' -v \ diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 271cab393c4..893c9d250b7 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -33,36 +33,37 @@ //! //! ``` //! use std::sync::Arc; +//! use std::thread::Thread; //! //! let five = Arc::new(5i); //! //! for i in range(0u, 10) { //! let five = five.clone(); //! -//! spawn(move || { +//! Thread::spawn(move || { //! println!("{}", five); -//! }); +//! }).detach(); //! } //! ``` //! //! Sharing mutable data safely between tasks with a `Mutex`: //! //! ``` -//! use std::sync::Arc; -//! use std::sync::Mutex; +//! use std::sync::{Arc, Mutex}; +//! use std::thread::Thread; //! //! let five = Arc::new(Mutex::new(5i)); //! //! for _ in range(0u, 10) { //! let five = five.clone(); //! -//! spawn(move || { +//! Thread::spawn(move || { //! let mut number = five.lock(); //! -//! number += 1; +//! *number += 1; //! //! println!("{}", *number); // prints 6 -//! }); +//! }).detach(); //! } //! ``` diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index ec2a7c7a06c..b82c7e4cba2 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -53,6 +53,7 @@ use core::cmp::max; use core::default::Default; use core::fmt; use core::hash::{mod, Hash}; +use core::iter::repeat; use core::kinds::marker::{ContravariantLifetime, InvariantType}; use core::mem; use core::num::{Int, UnsignedInt}; diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 9d032df67dc..d793f49efe5 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -131,7 +131,7 @@ impl<'v> Visitor<'v> for Annotator { } fn visit_foreign_item(&mut self, i: &ast::ForeignItem) { - self.annotate(i.id, &i.attrs, |_| {}); + self.annotate(i.id, true, &i.attrs, |_| {}); } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 34d89162249..85a06125e23 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -535,6 +535,8 @@ pub fn parameterized<'tcx>(cx: &ctxt<'tcx>, base, if strs[0].starts_with("(") && strs[0].ends_with(",)") { strs[0][1 .. strs[0].len() - 2] // Remove '(' and ',)' + } else if strs[0].starts_with("(") && strs[0].ends_with(")") { + strs[0][1 .. strs[0].len() - 1] // Remove '(' and ')' } else { strs[0][] }, diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index c32fec67d66..8149864afd4 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1473,7 +1473,6 @@ mod test_map { use super::HashMap; use super::Entry::{Occupied, Vacant}; - use cmp::Equiv; use hash; use iter::{range_inclusive, range_step_inclusive}; use cell::RefCell; diff --git a/src/snapshots.txt b/src/snapshots.txt index 653097e8993..c3cdf4acba1 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -3,7 +3,7 @@ S 2014-12-20 8443b09 linux-i386 3daf531aed03f5769402f2fef852377e2838db98 linux-x86_64 4f3c8b092dd4fe159d6f25a217cf62e0e899b365 macos-i386 2a3e647b9c400505bd49cfe56091e866c83574ca - macos-x86_64 78f952a3e77a9921a23c957bb133131017b57324 + macos-x86_64 5e730efc34d79a33f464a87686c10eace0760a2e winnt-i386 8ea056043de82096d5ce5abc98c8c74ebac7e77d winnt-x86_64 9804100dafae9b64a76e0ea7e1be157719dae151 diff --git a/src/test/compile-fail/issue-13359.rs b/src/test/compile-fail/issue-13359.rs index 227ed3fb834..5c72c7388a9 100644 --- a/src/test/compile-fail/issue-13359.rs +++ b/src/test/compile-fail/issue-13359.rs @@ -14,8 +14,8 @@ fn bar(_s: u32) { } fn main() { foo(1*(1 as int)); - //~^ ERROR: mismatched types: expected `i16`, found `int` (expected `i16`, found `int`) + //~^ ERROR: mismatched types: expected `i16`, found `int` (expected i16, found int) bar(1*(1 as uint)); - //~^ ERROR: mismatched types: expected `u32`, found `uint` (expected `u32`, found `uint`) + //~^ ERROR: mismatched types: expected `u32`, found `uint` (expected u32, found uint) } diff --git a/src/test/run-pass/issue-20091.rs b/src/test/run-pass/issue-20091.rs index daf898faef7..d653843ba05 100644 --- a/src/test/run-pass/issue-20091.rs +++ b/src/test/run-pass/issue-20091.rs @@ -8,6 +8,8 @@ // 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::io::Command; use std::os;