From 3bd6e46687b0d7ea347b6bb860bb1c35dfe2e7cc Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Wed, 8 Feb 2017 12:19:50 +0100 Subject: [PATCH 01/13] Specialize `PartialOrd for [A] where A: Ord` This way we can call `cmp` instead of `partial_cmp` in the loop, removing some burden of optimizing `Option`s away from the compiler. PR #39538 introduced a regression where sorting slices suddenly became slower, since `slice1.lt(slice2)` was much slower than `slice1.cmp(slice2) == Less`. This problem is now fixed. To verify, I benchmarked this simple program: ```rust fn main() { let mut v = (0..2_000_000).map(|x| x * x * x * 18913515181).map(|x| vec![x, x ^ 3137831591]).collect::>(); v.sort(); } ``` Before this PR, it would take 0.95 sec, and now it takes 0.58 sec. I also tried changing the `is_less` lambda to use `cmp` and `partial_cmp`. Now all three versions (`lt`, `cmp`, `partial_cmp`) are equally performant for sorting slices - all of them take 0.58 sec on the benchmark. --- src/libcore/slice.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 1a482b75731c1..18244cec7c78b 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -2290,6 +2290,28 @@ impl SlicePartialOrd for [A] } } +impl SlicePartialOrd for [A] + where A: Ord +{ + default fn partial_compare(&self, other: &[A]) -> Option { + let l = cmp::min(self.len(), other.len()); + + // Slice to the loop iteration range to enable bound check + // elimination in the compiler + let lhs = &self[..l]; + let rhs = &other[..l]; + + for i in 0..l { + match lhs[i].cmp(&rhs[i]) { + Ordering::Equal => (), + non_eq => return Some(non_eq), + } + } + + self.len().partial_cmp(&other.len()) + } +} + impl SlicePartialOrd for [u8] { #[inline] fn partial_compare(&self, other: &[u8]) -> Option { From ececbb26875c7aa2d9a6b20af5280a700dba11c8 Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Wed, 8 Feb 2017 16:01:32 +0100 Subject: [PATCH 02/13] Simplify by calling SliceOrd::compare --- src/libcore/slice.rs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 18244cec7c78b..7d052c218fe55 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -2294,21 +2294,7 @@ impl SlicePartialOrd for [A] where A: Ord { default fn partial_compare(&self, other: &[A]) -> Option { - let l = cmp::min(self.len(), other.len()); - - // Slice to the loop iteration range to enable bound check - // elimination in the compiler - let lhs = &self[..l]; - let rhs = &other[..l]; - - for i in 0..l { - match lhs[i].cmp(&rhs[i]) { - Ordering::Equal => (), - non_eq => return Some(non_eq), - } - } - - self.len().partial_cmp(&other.len()) + Some(SliceOrd::compare(self, other)) } } From a344c126d03729a9d147f18dfc9cc6432bc790fd Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Wed, 8 Feb 2017 18:03:10 +0100 Subject: [PATCH 03/13] Remove unnecessary specialization for [u8] --- src/libcore/slice.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 7d052c218fe55..3e0b842557353 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -2298,13 +2298,6 @@ impl SlicePartialOrd for [A] } } -impl SlicePartialOrd for [u8] { - #[inline] - fn partial_compare(&self, other: &[u8]) -> Option { - Some(SliceOrd::compare(self, other)) - } -} - #[doc(hidden)] // intermediate trait for specialization of slice's Ord trait SliceOrd { From 67574ccd5352746c8040de05f469a3bb86e2fa97 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 8 Feb 2017 15:08:30 -0800 Subject: [PATCH 04/13] Don't include directory names in shasums Right now we just run `shasum` on an absolute path but right now the shasum files only include filenames, so let's use `current_dir` and just the file name to only have the file name emitted. --- src/tools/build-manifest/src/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 8c15a6630a33c..8afe0cfd102b0 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -350,7 +350,8 @@ impl Builder { fn hash(&self, path: &Path) -> String { let sha = t!(Command::new("shasum") .arg("-a").arg("256") - .arg(path) + .arg(path.file_name().unwrap()) + .current_dir(path.parent().unwrap()) .output()); assert!(sha.status.success()); From de59d5d73775f8ccf948480cbd5d90dc72e1b40f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 8 Feb 2017 20:49:58 -0800 Subject: [PATCH 05/13] Actually fix manifest generation The previous fix contained an error where `toml::encode` returned a runtime error, so this version just constructs a literal `toml::Value`. --- src/tools/build-manifest/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 548a11439f5cc..eceba7411ac5c 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -178,8 +178,8 @@ impl Builder { // and wrap it up in a `Value::Table`. let mut manifest = BTreeMap::new(); manifest.insert("manifest-version".to_string(), - toml::encode(&manifest_version)); - manifest.insert("date".to_string(), toml::encode(&date)); + toml::Value::String(manifest_version)); + manifest.insert("date".to_string(), toml::Value::String(date)); manifest.insert("pkg".to_string(), toml::encode(&pkg)); let manifest = toml::Value::Table(manifest).to_string(); From 1095082eea65a4bfb577221ae1cac07330770aaa Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 9 Feb 2017 17:55:39 +0100 Subject: [PATCH 06/13] remove wrong packed struct test --- src/test/run-pass/dst-field-align.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/test/run-pass/dst-field-align.rs b/src/test/run-pass/dst-field-align.rs index cf2acfe986c21..3a2cf28a24f86 100644 --- a/src/test/run-pass/dst-field-align.rs +++ b/src/test/run-pass/dst-field-align.rs @@ -55,12 +55,6 @@ fn main() { // The pointers should be the same assert_eq!(ptr1, ptr2); - // Test that packed structs are handled correctly - let p : Packed = Packed { a: 0, b: 13 }; - assert_eq!(p.b.get(), 13); - let p : &Packed = &p; - assert_eq!(p.b.get(), 13); - // Test that nested DSTs work properly let f : Foo> = Foo { a: 0, b: Foo { a: 1, b: 17 }}; assert_eq!(f.b.b.get(), 17); From c7f9811abab9289eac9b577aba4c60a5afb0bef4 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 9 Feb 2017 17:58:26 +0100 Subject: [PATCH 07/13] removed unused struct --- src/test/run-pass/dst-field-align.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/test/run-pass/dst-field-align.rs b/src/test/run-pass/dst-field-align.rs index 3a2cf28a24f86..c36833f2fb627 100644 --- a/src/test/run-pass/dst-field-align.rs +++ b/src/test/run-pass/dst-field-align.rs @@ -25,12 +25,6 @@ struct Baz { a: T } -#[repr(packed)] -struct Packed { - a: u8, - b: T -} - struct HasDrop { ptr: Box, data: T From b3937ea862e15321e85537ac6bd63ad51099c23f Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Thu, 9 Feb 2017 13:58:48 -0500 Subject: [PATCH 08/13] Explicitly mention that `Vec::reserve` is based on len not capacity I spent a good chunk of time tracking down a buffer overrun bug that resulted from me mistakenly thinking that `reserve` was based on the current capacity not the current length. It would be helpful if this were called out explicitly in the docs. --- src/libcollections/vec.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index dc0f33d9bc3e0..3873b3535a07b 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -437,7 +437,9 @@ impl Vec { /// Reserves capacity for at least `additional` more elements to be inserted /// in the given `Vec`. The collection may reserve more space to avoid - /// frequent reallocations. + /// frequent reallocations. After calling `reserve`, capacity will be + /// greater than or equal to `self.len() + additional`. Does nothing if + /// capacity is already sufficient. /// /// # Panics /// @@ -456,8 +458,9 @@ impl Vec { } /// Reserves the minimum capacity for exactly `additional` more elements to - /// be inserted in the given `Vec`. Does nothing if the capacity is already - /// sufficient. + /// be inserted in the given `Vec`. After calling `reserve_exact`, + /// capacity will be greater than or equal to `self.len() + additional`. + /// Does nothing if the capacity is already sufficient. /// /// Note that the allocator may give the collection more space than it /// requests. Therefore capacity can not be relied upon to be precisely From e491f399147aaf09f631878d009396fc5400ddfd Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 10 Feb 2017 00:30:02 +0000 Subject: [PATCH 09/13] Update 1.15.1 relnotes --- RELEASES.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 2df1a83db81ff..1de44ef7e6d05 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,9 +1,11 @@ -Version 1.15.1 (2017-02-08) +Version 1.15.1 (2017-02-09) =========================== * [Fix IntoIter::as_mut_slice's signature][39466] +* [Compile compiler builtins with `-fPIC` on 32-bit platforms][39523] [39466]: https://github.com/rust-lang/rust/pull/39466 +[39523]: https://github.com/rust-lang/rust/pull/39523 Version 1.15.0 (2017-02-02) From 5cc5e0851e5bd14b9855462408ecb9058ed5eaad Mon Sep 17 00:00:00 2001 From: Rob Speer Date: Thu, 19 Jan 2017 02:51:29 -0500 Subject: [PATCH 10/13] Fix a misleading statement in `Iterator.nth()` The `Iterator.nth()` documentation says "Note that all preceding elements will be consumed". I assumed from that that the preceding elements would be the *only* ones that were consumed, but in fact the returned element is consumed as well. The way I read the documentation, I assumed that `nth(0)` would not discard anything (as there are 0 preceding elements), so I added a sentence clarifying that it does. I also rephrased it to avoid the stunted "i.e." phrasing. --- src/libcore/iter/iterator.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 3b406873d4b19..0e14a93d25396 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -209,7 +209,10 @@ pub trait Iterator { /// Returns the `n`th element of the iterator. /// - /// Note that all preceding elements will be consumed (i.e. discarded). + /// Note that all preceding elements, as well as the returned element, will be + /// consumed. That means that the preceding elements will be discarded, and also + /// that calling `nth(0)` multiple times on the same iterator will return different + /// objects. /// /// Like most indexing operations, the count starts from zero, so `nth(0)` /// returns the first value, `nth(1)` the second, and so on. From ebf29ef0733ec0ac13ef16eb42bac17e3b94da3c Mon Sep 17 00:00:00 2001 From: Rob Speer Date: Thu, 19 Jan 2017 02:53:33 -0500 Subject: [PATCH 11/13] Rephrase my proposed edit ("objects" -> "elements") --- src/libcore/iter/iterator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 0e14a93d25396..4a8c8b53a8c29 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -212,7 +212,7 @@ pub trait Iterator { /// Note that all preceding elements, as well as the returned element, will be /// consumed. That means that the preceding elements will be discarded, and also /// that calling `nth(0)` multiple times on the same iterator will return different - /// objects. + /// elements. /// /// Like most indexing operations, the count starts from zero, so `nth(0)` /// returns the first value, `nth(1)` the second, and so on. From 11d36aec8317dba64e30b98aad75c70e4eed6b3e Mon Sep 17 00:00:00 2001 From: Rob Speer Date: Fri, 10 Feb 2017 01:35:29 -0500 Subject: [PATCH 12/13] iterator docs: Move paragraph about discarding; clarify "consumed" --- src/libcore/iter/iterator.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 4a8c8b53a8c29..d41767cce18fe 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -209,14 +209,14 @@ pub trait Iterator { /// Returns the `n`th element of the iterator. /// - /// Note that all preceding elements, as well as the returned element, will be - /// consumed. That means that the preceding elements will be discarded, and also - /// that calling `nth(0)` multiple times on the same iterator will return different - /// elements. - /// /// Like most indexing operations, the count starts from zero, so `nth(0)` /// returns the first value, `nth(1)` the second, and so on. /// + /// Note that all preceding elements, as well as the returned element, will be + /// consumed from the iterator. That means that the preceding elements will be + /// discarded, and also that calling `nth(0)` multiple times on the same iterator + /// will return different elements. + /// /// `nth()` will return [`None`] if `n` is greater than or equal to the length of the /// iterator. /// From 5c295110fddf386b0a42b3896541c5669d333b30 Mon Sep 17 00:00:00 2001 From: Aaron Power Date: Fri, 10 Feb 2017 18:44:32 +0000 Subject: [PATCH 13/13] Updated installing nightly instructions --- src/doc/book/nightly-rust.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/doc/book/nightly-rust.md b/src/doc/book/nightly-rust.md index 25570cb5503c9..f55bb0784202a 100644 --- a/src/doc/book/nightly-rust.md +++ b/src/doc/book/nightly-rust.md @@ -6,10 +6,13 @@ process, see ‘[Stability as a deliverable][stability]’. [stability]: http://blog.rust-lang.org/2014/10/30/Stability.html -To install nightly Rust, you can use `rustup.sh`: +To install nightly Rust, you can use [rustup.rs][rustup]: + +[rustup]: https://rustup.rs ```bash -$ curl -s https://static.rust-lang.org/rustup.sh | sh -s -- --channel=nightly +$ curl https://sh.rustup.rs -sSf | sh +$ rustup install nightly ``` If you're concerned about the [potential insecurity][insecurity] of using `curl @@ -17,31 +20,28 @@ If you're concerned about the [potential insecurity][insecurity] of using `curl use a two-step version of the installation and examine our installation script: ```bash -$ curl -f -L https://static.rust-lang.org/rustup.sh -O -$ sh rustup.sh --channel=nightly +$ curl https://sh.rustup.rs -sSf -o rustup.sh +$ sh rustup.sh +$ rustup install nightly ``` [insecurity]: http://curlpipesh.tumblr.com -If you're on Windows, please download either the [32-bit installer][win32] or -the [64-bit installer][win64] and run it. +If you're on Windows, please download the [rustup installer][installer] +and run it. -[win32]: https://static.rust-lang.org/dist/rust-nightly-i686-pc-windows-gnu.msi -[win64]: https://static.rust-lang.org/dist/rust-nightly-x86_64-pc-windows-gnu.msi +[installer]: https://win.rustup.rs ## Uninstalling If you decide you don't want Rust anymore, we'll be a bit sad, but that's okay. Not every programming language is great for everyone. Just run the uninstall -script: +command: ```bash -$ sudo /usr/local/lib/rustlib/uninstall.sh +$ rustup self uninstall ``` -If you used the Windows installer, re-run the `.msi` and it will give you -an uninstall option. - Some people, and somewhat rightfully so, get very upset when we tell you to `curl | sh`. Basically, when you do this, you are trusting that the good people who maintain Rust aren't going to hack your computer and do bad things.