From a83e6c7328f3fe8c78445fdb8088d7a7fa6f8897 Mon Sep 17 00:00:00 2001 From: "Joshua M. Clulow" Date: Mon, 16 Mar 2020 23:15:34 -0700 Subject: [PATCH 1/8] use "gcc" instead of "cc" on *-sun-solaris systems when linking On illumos and Solaris systems, Rust will use GCC as the link editor. Rust does this by invoking "cc", which on many (Linux and perhaps BSD) systems is generally either GCC or a GCC-compatible front-end. On historical Solaris systems, "cc" was often the Sun Studio compiler. This history casts a long shadow, and as such, even most modern illumos-based operating systems tend to install GCC as "gcc", without also making it available as "cc". We should invoke GCC as "gcc" on such systems to ensure we get the right compiler driver. --- src/librustc_codegen_ssa/back/link.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index a4eef2374c241..d7081e60bd1fc 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -839,7 +839,13 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { "emcc" } } - LinkerFlavor::Gcc => "cc", + LinkerFlavor::Gcc => { + if cfg!(target_os = "solaris") { + "gcc" + } else { + "cc" + } + } LinkerFlavor::Ld => "ld", LinkerFlavor::Msvc => "link.exe", LinkerFlavor::Lld(_) => "lld", From 1c191c304aa5629e31c93bec395fe4255ecca9ce Mon Sep 17 00:00:00 2001 From: "Joshua M. Clulow" Date: Tue, 17 Mar 2020 15:04:29 -0700 Subject: [PATCH 2/8] review feedback: add a comment describing the situation --- src/librustc_codegen_ssa/back/link.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index d7081e60bd1fc..fb6154eb39261 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -841,6 +841,12 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { } LinkerFlavor::Gcc => { if cfg!(target_os = "solaris") { + // On historical Solaris systems, "cc" may have + // been Sun Studio, which is not flag-compatible + // with "gcc". This history casts a long shadow, + // and many modern illumos distributions today + // ship GCC as "gcc" without also making it + // available as "cc". "gcc" } else { "cc" From 9b429fd1219bfd15ec3fd9ce3cb073cdae6ed03c Mon Sep 17 00:00:00 2001 From: Nathan West Date: Mon, 6 Jan 2020 17:06:19 -0500 Subject: [PATCH 3/8] Add fold_self - Added `Iterator::fold_first`, which is like `fold`, but uses the first element in the iterator as the initial accumulator - Includes doc and doctest - Rebase commit; see #65222 for details Co-Authored-By: Tim Vermeulen --- src/libcore/iter/traits/iterator.rs | 56 ++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index 39bd270da8680..c066d535f24e5 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -2005,6 +2005,44 @@ pub trait Iterator { self.try_fold(init, ok(f)).unwrap() } + /// The same as [`fold()`](#method.fold), but uses the first element in the + /// iterator as the initial value, folding every subsequent element into it. + /// If the iterator is empty, return `None`; otherwise, return the result + /// of the fold. + /// + /// # Example + /// + /// Find the maximum value: + /// + /// ``` + /// fn find_max(iter: I) -> Option + /// where I: Iterator, + /// I::Item: Ord, + /// { + /// iter.fold_first(|a, b| { + /// a.partial_cmp(b).map(move |cmp| match cmp { + /// Ordering::Greater | Ordering::Equal => a, + /// Ordering::Less => b, + /// }) + /// }) + /// } + /// let a = [10, 20, 5, -23, 0]; + /// let b = []; + /// + /// assert_eq!(find_max(a.iter()), Some(20)); + /// assert_eq!(find_max(b.iter()), None); + /// ``` + #[inline] + #[unstable(feature = "iterator_fold_self", issue = "68125")] + fn fold_first(mut self, f: F) -> Option + where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item, + { + let first = self.next()?; + Some(self.fold(first, f)) + } + /// Tests if every element of the iterator matches a predicate. /// /// `all()` takes a closure that returns `true` or `false`. It applies @@ -2497,7 +2535,7 @@ pub trait Iterator { move |x, y| cmp::max_by(x, y, &mut compare) } - fold1(self, fold(compare)) + self.fold_first(fold(compare)) } /// Returns the element that gives the minimum value from the @@ -2561,7 +2599,7 @@ pub trait Iterator { move |x, y| cmp::min_by(x, y, &mut compare) } - fold1(self, fold(compare)) + self.fold_first(fold(compare)) } /// Reverses an iterator's direction. @@ -3214,20 +3252,6 @@ pub trait Iterator { } } -/// Fold an iterator without having to provide an initial value. -#[inline] -fn fold1(mut it: I, f: F) -> Option -where - I: Iterator, - F: FnMut(I::Item, I::Item) -> I::Item, -{ - // start with the first element as our selection. This avoids - // having to use `Option`s inside the loop, translating to a - // sizeable performance gain (6x in one case). - let first = it.next()?; - Some(it.fold(first, f)) -} - #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for &mut I { type Item = I::Item; From a9a2a319afbeb7e2a54f343a9360bd9bc4863b4f Mon Sep 17 00:00:00 2001 From: dylan_DPC Date: Thu, 26 Mar 2020 23:18:37 +0100 Subject: [PATCH 4/8] fix docs --- src/libcore/iter/traits/iterator.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index c066d535f24e5..853059f98a609 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -2015,6 +2015,9 @@ pub trait Iterator { /// Find the maximum value: /// /// ``` + /// #![feature(iterator_fold_self)] + /// use std::cmp::Ordering; + /// /// fn find_max(iter: I) -> Option /// where I: Iterator, /// I::Item: Ord, @@ -2027,9 +2030,9 @@ pub trait Iterator { /// }) /// } /// let a = [10, 20, 5, -23, 0]; - /// let b = []; + /// let b: [u32; 0] = []; /// - /// assert_eq!(find_max(a.iter()), Some(20)); + /// assert_eq!(find_max(a.iter()), Some(&20)); /// assert_eq!(find_max(b.iter()), None); /// ``` #[inline] From 7e7c2f19a3ab215fd4ef4ba983d52aeacf35d3c4 Mon Sep 17 00:00:00 2001 From: dylan_DPC Date: Fri, 27 Mar 2020 02:45:56 +0100 Subject: [PATCH 5/8] simplify test --- src/libcore/iter/traits/iterator.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index 853059f98a609..62492f639e45b 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -2023,10 +2023,7 @@ pub trait Iterator { /// I::Item: Ord, /// { /// iter.fold_first(|a, b| { - /// a.partial_cmp(b).map(move |cmp| match cmp { - /// Ordering::Greater | Ordering::Equal => a, - /// Ordering::Less => b, - /// }) + /// if a >= b { a } else { b } /// }) /// } /// let a = [10, 20, 5, -23, 0]; From 268408f495f5fe225269842837ec1e49b498c881 Mon Sep 17 00:00:00 2001 From: dylan_DPC Date: Fri, 27 Mar 2020 03:21:15 +0100 Subject: [PATCH 6/8] remove unused import --- src/libcore/iter/traits/iterator.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index 62492f639e45b..daa880e7cd53b 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -2016,7 +2016,6 @@ pub trait Iterator { /// /// ``` /// #![feature(iterator_fold_self)] - /// use std::cmp::Ordering; /// /// fn find_max(iter: I) -> Option /// where I: Iterator, From 346bc41086419874e3b3cc0f394c3c4a4d0d75ba Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 27 Mar 2020 13:35:00 +0100 Subject: [PATCH 7/8] Clean up E0463 explanation --- src/librustc_error_codes/error_codes/E0463.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc_error_codes/error_codes/E0463.md b/src/librustc_error_codes/error_codes/E0463.md index 41add698cdc90..e46938c607d34 100644 --- a/src/librustc_error_codes/error_codes/E0463.md +++ b/src/librustc_error_codes/error_codes/E0463.md @@ -1,4 +1,6 @@ -A plugin/crate was declared but cannot be found. Erroneous code example: +A plugin/crate was declared but cannot be found. + +Erroneous code example: ```compile_fail,E0463 #![feature(plugin)] From 88100baa2cbb5491d0a1ea5ff64e7adaf973f2a3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 10 Mar 2020 12:54:17 +0100 Subject: [PATCH 8/8] clean up E0404 explanation --- src/librustc_error_codes/error_codes/E0404.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0404.md b/src/librustc_error_codes/error_codes/E0404.md index 201107c05a02c..1360cc99afcc4 100644 --- a/src/librustc_error_codes/error_codes/E0404.md +++ b/src/librustc_error_codes/error_codes/E0404.md @@ -1,5 +1,5 @@ -You tried to use something which is not a trait in a trait position, such as -a bound or `impl`. +A type that is not a trait was used in a trait position, such as a bound +or `impl`. Erroneous code example: @@ -18,8 +18,8 @@ struct Foo; fn bar(t: T) {} // error: `Foo` is not a trait ``` -Please verify that you didn't misspell the trait's name or otherwise use the -wrong identifier. Example: +Please verify that the trait's name was not misspelled or that the right +identifier was used. Example: ``` trait Foo { @@ -32,7 +32,7 @@ impl Foo for Bar { // ok! } ``` -or +or: ``` trait Foo {