From 1acec4cbd9d10727b221779f99df36d840f0beec Mon Sep 17 00:00:00 2001 From: Son Date: Mon, 20 Aug 2018 15:46:59 +1000 Subject: [PATCH 01/16] Add doc for impl From in char_convert --- src/libcore/char/convert.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libcore/char/convert.rs b/src/libcore/char/convert.rs index 803a924eb3a4..6c2c02951af6 100644 --- a/src/libcore/char/convert.rs +++ b/src/libcore/char/convert.rs @@ -115,6 +115,10 @@ pub unsafe fn from_u32_unchecked(i: u32) -> char { #[stable(feature = "char_convert", since = "1.13.0")] impl From for u32 { + /// Converts a [`char`] into a [`u32`]. + /// + /// [`char`]: primitive.char.html + /// [`u32`]: primitive.u32.html #[inline] fn from(c: char) -> Self { c as u32 @@ -141,6 +145,10 @@ impl From for u32 { /// C0 and C1 control codes. #[stable(feature = "char_convert", since = "1.13.0")] impl From for char { + /// Converts a [`u8`] into a [`char`]. + /// + /// [`u8`]: primitive.u8.html + /// [`char`]: primitive.char.html #[inline] fn from(i: u8) -> Self { i as char From 9d5ca397c73325a32801b3d4b619368ac7c54b94 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 16 Sep 2018 21:22:32 +0200 Subject: [PATCH 02/16] Improve search box display --- src/doc/index.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/doc/index.md b/src/doc/index.md index b1788d8c32f0..33ee76739c5b 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -4,6 +4,23 @@ nav { display: none; } +#search-input { + width: calc(100% - 58px); +} +#search-but { + cursor: pointer; +} +#search-but, #search-input { + padding: 4px; + border: 1px solid #ccc; + border-radius: 3px; + outline: none; + font-size: 0.7em; + background-color: #fff; +} +#search-but:hover, #search-input:focus { + border-color: #55a9ff; +} Welcome to an overview of the documentation provided by the Rust project. @@ -45,8 +62,9 @@ accomplishing various tasks.
- - + +
From 2099b3c75cdadc60d488b924f07dbf890a2dc2ea Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 19 Sep 2018 22:59:35 +0200 Subject: [PATCH 03/16] Reduce code block sides padding --- src/librustdoc/html/static/rustdoc.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 923a486060a3..ee811f337923 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -139,7 +139,7 @@ code, pre { } .docblock code, .docblock-short code { border-radius: 3px; - padding: 0 0.2em; + padding: 0 0.1em; } .docblock pre code, .docblock-short pre code, .docblock code.spotlight { padding: 0; From d14db1165a5abfbdcaa302742b6f0ec8ca709917 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 23 Sep 2018 08:26:34 +0200 Subject: [PATCH 04/16] The project moved under the Mozilla umbrella --- src/doc/unstable-book/src/compiler-flags/profile.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/unstable-book/src/compiler-flags/profile.md b/src/doc/unstable-book/src/compiler-flags/profile.md index 66d14fd09978..deef624802bd 100644 --- a/src/doc/unstable-book/src/compiler-flags/profile.md +++ b/src/doc/unstable-book/src/compiler-flags/profile.md @@ -18,4 +18,4 @@ cargo run ``` Once you've built and run your program, files with the `gcno` (after build) and `gcda` (after execution) extensions will be created. -You can parse them with [llvm-cov gcov](http://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-gcov) or [grcov](/~https://github.com/marco-c/grcov). +You can parse them with [llvm-cov gcov](http://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-gcov) or [grcov](/~https://github.com/mozilla/grcov). From 5139865af10a825e5770911054666f3e6003be3a Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 23 Sep 2018 08:27:39 +0200 Subject: [PATCH 05/16] and llvm has https now --- src/doc/unstable-book/src/compiler-flags/profile.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/unstable-book/src/compiler-flags/profile.md b/src/doc/unstable-book/src/compiler-flags/profile.md index deef624802bd..452aca51532c 100644 --- a/src/doc/unstable-book/src/compiler-flags/profile.md +++ b/src/doc/unstable-book/src/compiler-flags/profile.md @@ -18,4 +18,4 @@ cargo run ``` Once you've built and run your program, files with the `gcno` (after build) and `gcda` (after execution) extensions will be created. -You can parse them with [llvm-cov gcov](http://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-gcov) or [grcov](/~https://github.com/mozilla/grcov). +You can parse them with [llvm-cov gcov](https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-gcov) or [grcov](/~https://github.com/mozilla/grcov). From 78bccb3540ae8082d34e45be5abb19ed720e9a32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Renault?= Date: Sat, 8 Sep 2018 15:33:02 +0200 Subject: [PATCH 06/16] Introduce the partition_dedup/by/by_key methods for slices --- src/liballoc/vec.rs | 10 +-- src/libcore/slice/mod.rs | 172 +++++++++++++++++++++++++++++++++++++ src/libcore/tests/lib.rs | 1 + src/libcore/tests/slice.rs | 59 +++++++++++++ 4 files changed, 237 insertions(+), 5 deletions(-) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 7fc4453fec5b..3f49d99989de 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -947,10 +947,9 @@ impl Vec { /// Removes all but the first of consecutive elements in the vector satisfying a given equality /// relation. /// - /// The `same_bucket` function is passed references to two elements from the vector, and - /// returns `true` if the elements compare equal, or `false` if they do not. The elements are - /// passed in opposite order from their order in the vector, so if `same_bucket(a, b)` returns - /// `true`, `a` is removed. + /// The `same_bucket` function is passed references to two elements from the vector and + /// must determine if the elements compare equal. The elements are passed in opposite order + /// from their order in the slice, so if `same_bucket(a, b)` returns `true`, `a` is removed. /// /// If the vector is sorted, this removes all duplicates. /// @@ -1533,7 +1532,8 @@ impl<'a> Drop for SetLenOnDrop<'a> { } impl Vec { - /// Removes consecutive repeated elements in the vector. + /// Removes consecutive repeated elements in the vector according to the + /// [`PartialEq`] trait implementation. /// /// If the vector is sorted, this removes all duplicates. /// diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index aed9020d9d14..97aada385553 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1402,6 +1402,178 @@ impl [T] { sort::quicksort(self, |a, b| f(a).lt(&f(b))); } + /// Moves all consecutive repeated elements to the end of the slice according to the + /// [`PartialEq`] trait implementation. + /// + /// Returns two slices. The first contains no consecutive repeated elements. + /// The second contains all the duplicates in no specified order. + /// + /// If the slice is sorted, the first returned slice contains no duplicates. + /// + /// # Examples + /// + /// ``` + /// #![feature(slice_partition_dedup)] + /// + /// let mut slice = [1, 2, 2, 3, 3, 2, 1, 1]; + /// + /// let (dedup, duplicates) = slice.partition_dedup(); + /// + /// assert_eq!(dedup, [1, 2, 3, 2, 1]); + /// assert_eq!(duplicates, [2, 3, 1]); + /// ``` + #[unstable(feature = "slice_partition_dedup", issue = "54279")] + #[inline] + pub fn partition_dedup(&mut self) -> (&mut [T], &mut [T]) + where T: PartialEq + { + self.partition_dedup_by(|a, b| a == b) + } + + /// Moves all but the first of consecutive elements to the end of the slice satisfying + /// a given equality relation. + /// + /// Returns two slices. The first contains no consecutive repeated elements. + /// The second contains all the duplicates in no specified order. + /// + /// The `same_bucket` function is passed references to two elements from the slice and + /// must determine if the elements compare equal. The elements are passed in opposite order + /// from their order in the slice, so if `same_bucket(a, b)` returns `true`, `a` is moved + /// at the end of the slice. + /// + /// If the slice is sorted, the first returned slice contains no duplicates. + /// + /// # Examples + /// + /// ``` + /// #![feature(slice_partition_dedup)] + /// + /// let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"]; + /// + /// let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b)); + /// + /// assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]); + /// assert_eq!(duplicates, ["bar", "Foo", "BAZ"]); + /// ``` + #[unstable(feature = "slice_partition_dedup", issue = "54279")] + #[inline] + pub fn partition_dedup_by(&mut self, mut same_bucket: F) -> (&mut [T], &mut [T]) + where F: FnMut(&mut T, &mut T) -> bool + { + // Although we have a mutable reference to `self`, we cannot make + // *arbitrary* changes. The `same_bucket` calls could panic, so we + // must ensure that the slice is in a valid state at all times. + // + // The way that we handle this is by using swaps; we iterate + // over all the elements, swapping as we go so that at the end + // the elements we wish to keep are in the front, and those we + // wish to reject are at the back. We can then split the slice. + // This operation is still O(n). + // + // Example: We start in this state, where `r` represents "next + // read" and `w` represents "next_write`. + // + // r + // +---+---+---+---+---+---+ + // | 0 | 1 | 1 | 2 | 3 | 3 | + // +---+---+---+---+---+---+ + // w + // + // Comparing self[r] against self[w-1], this is not a duplicate, so + // we swap self[r] and self[w] (no effect as r==w) and then increment both + // r and w, leaving us with: + // + // r + // +---+---+---+---+---+---+ + // | 0 | 1 | 1 | 2 | 3 | 3 | + // +---+---+---+---+---+---+ + // w + // + // Comparing self[r] against self[w-1], this value is a duplicate, + // so we increment `r` but leave everything else unchanged: + // + // r + // +---+---+---+---+---+---+ + // | 0 | 1 | 1 | 2 | 3 | 3 | + // +---+---+---+---+---+---+ + // w + // + // Comparing self[r] against self[w-1], this is not a duplicate, + // so swap self[r] and self[w] and advance r and w: + // + // r + // +---+---+---+---+---+---+ + // | 0 | 1 | 2 | 1 | 3 | 3 | + // +---+---+---+---+---+---+ + // w + // + // Not a duplicate, repeat: + // + // r + // +---+---+---+---+---+---+ + // | 0 | 1 | 2 | 3 | 1 | 3 | + // +---+---+---+---+---+---+ + // w + // + // Duplicate, advance r. End of slice. Split at w. + + let len = self.len(); + if len <= 1 { + return (self, &mut []) + } + + let ptr = self.as_mut_ptr(); + let mut next_read: usize = 1; + let mut next_write: usize = 1; + + unsafe { + // Avoid bounds checks by using raw pointers. + while next_read < len { + let ptr_read = ptr.add(next_read); + let prev_ptr_write = ptr.add(next_write - 1); + if !same_bucket(&mut *ptr_read, &mut *prev_ptr_write) { + if next_read != next_write { + let ptr_write = prev_ptr_write.offset(1); + mem::swap(&mut *ptr_read, &mut *ptr_write); + } + next_write += 1; + } + next_read += 1; + } + } + + self.split_at_mut(next_write) + } + + /// Moves all but the first of consecutive elements to the end of the slice that resolve + /// to the same key. + /// + /// Returns two slices. The first contains no consecutive repeated elements. + /// The second contains all the duplicates in no specified order. + /// + /// If the slice is sorted, the first returned slice contains no duplicates. + /// + /// # Examples + /// + /// ``` + /// #![feature(slice_partition_dedup)] + /// + /// let mut slice = [10, 20, 21, 30, 30, 20, 11, 13]; + /// + /// let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10); + /// + /// assert_eq!(dedup, [10, 20, 30, 20, 11]); + /// assert_eq!(duplicates, [21, 30, 13]); + /// ``` + #[unstable(feature = "slice_partition_dedup", issue = "54279")] + #[inline] + pub fn partition_dedup_by_key(&mut self, mut key: F) -> (&mut [T], &mut [T]) + where F: FnMut(&mut T) -> K, + K: PartialEq, + { + self.partition_dedup_by(|a, b| key(a) == key(b)) + } + /// Rotates the slice in-place such that the first `mid` elements of the /// slice move to the end while the last `self.len() - mid` elements move to /// the front. After calling `rotate_left`, the element previously at index diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 8fc32f40b992..d05f6e07331c 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -39,6 +39,7 @@ #![feature(inner_deref)] #![feature(slice_internals)] #![feature(option_replace)] +#![feature(slice_partition_dedup)] #![feature(copy_within)] extern crate core; diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index d46a35ab82cf..6f11880eb72d 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -1001,6 +1001,65 @@ fn test_align_to_empty_mid() { } } +#[test] +fn test_slice_partition_dedup_by() { + let mut slice: [i32; 9] = [1, -1, 2, 3, 1, -5, 5, -2, 2]; + + let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.abs() == b.abs()); + + assert_eq!(dedup, [1, 2, 3, 1, -5, -2]); + assert_eq!(duplicates, [5, -1, 2]); +} + +#[test] +fn test_slice_partition_dedup_empty() { + let mut slice: [i32; 0] = []; + + let (dedup, duplicates) = slice.partition_dedup(); + + assert_eq!(dedup, []); + assert_eq!(duplicates, []); +} + +#[test] +fn test_slice_partition_dedup_one() { + let mut slice = [12]; + + let (dedup, duplicates) = slice.partition_dedup(); + + assert_eq!(dedup, [12]); + assert_eq!(duplicates, []); +} + +#[test] +fn test_slice_partition_dedup_multiple_ident() { + let mut slice = [12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11]; + + let (dedup, duplicates) = slice.partition_dedup(); + + assert_eq!(dedup, [12, 11]); + assert_eq!(duplicates, [12, 12, 12, 12, 11, 11, 11, 11, 11]); +} + +#[test] +fn test_slice_partition_dedup_partialeq() { + #[derive(Debug)] + struct Foo(i32, i32); + + impl PartialEq for Foo { + fn eq(&self, other: &Foo) -> bool { + self.0 == other.0 + } + } + + let mut slice = [Foo(0, 1), Foo(0, 5), Foo(1, 7), Foo(1, 9)]; + + let (dedup, duplicates) = slice.partition_dedup(); + + assert_eq!(dedup, [Foo(0, 1), Foo(1, 7)]); + assert_eq!(duplicates, [Foo(0, 5), Foo(1, 9)]); +} + #[test] fn test_copy_within() { // Start to end, with a RangeTo. From d560292a87a89587e0345e13b9714c90495ea50f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Renault?= Date: Sun, 16 Sep 2018 23:32:16 +0200 Subject: [PATCH 07/16] Make the `Vec::dedup` method use `slice::partition_dedup` internally --- src/liballoc/lib.rs | 1 + src/liballoc/vec.rs | 90 +++------------------------------------------ 2 files changed, 7 insertions(+), 84 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 089480c06d20..6ce24b659906 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -119,6 +119,7 @@ #![feature(exact_chunks)] #![feature(rustc_const_unstable)] #![feature(const_vec_new)] +#![feature(slice_partition_dedup)] #![feature(maybe_uninit)] // Allow testing this library diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 3f49d99989de..e845438c0a83 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -963,90 +963,12 @@ impl Vec { /// assert_eq!(vec, ["foo", "bar", "baz", "bar"]); /// ``` #[stable(feature = "dedup_by", since = "1.16.0")] - pub fn dedup_by(&mut self, mut same_bucket: F) where F: FnMut(&mut T, &mut T) -> bool { - unsafe { - // Although we have a mutable reference to `self`, we cannot make - // *arbitrary* changes. The `same_bucket` calls could panic, so we - // must ensure that the vector is in a valid state at all time. - // - // The way that we handle this is by using swaps; we iterate - // over all the elements, swapping as we go so that at the end - // the elements we wish to keep are in the front, and those we - // wish to reject are at the back. We can then truncate the - // vector. This operation is still O(n). - // - // Example: We start in this state, where `r` represents "next - // read" and `w` represents "next_write`. - // - // r - // +---+---+---+---+---+---+ - // | 0 | 1 | 1 | 2 | 3 | 3 | - // +---+---+---+---+---+---+ - // w - // - // Comparing self[r] against self[w-1], this is not a duplicate, so - // we swap self[r] and self[w] (no effect as r==w) and then increment both - // r and w, leaving us with: - // - // r - // +---+---+---+---+---+---+ - // | 0 | 1 | 1 | 2 | 3 | 3 | - // +---+---+---+---+---+---+ - // w - // - // Comparing self[r] against self[w-1], this value is a duplicate, - // so we increment `r` but leave everything else unchanged: - // - // r - // +---+---+---+---+---+---+ - // | 0 | 1 | 1 | 2 | 3 | 3 | - // +---+---+---+---+---+---+ - // w - // - // Comparing self[r] against self[w-1], this is not a duplicate, - // so swap self[r] and self[w] and advance r and w: - // - // r - // +---+---+---+---+---+---+ - // | 0 | 1 | 2 | 1 | 3 | 3 | - // +---+---+---+---+---+---+ - // w - // - // Not a duplicate, repeat: - // - // r - // +---+---+---+---+---+---+ - // | 0 | 1 | 2 | 3 | 1 | 3 | - // +---+---+---+---+---+---+ - // w - // - // Duplicate, advance r. End of vec. Truncate to w. - - let ln = self.len(); - if ln <= 1 { - return; - } - - // Avoid bounds checks by using raw pointers. - let p = self.as_mut_ptr(); - let mut r: usize = 1; - let mut w: usize = 1; - - while r < ln { - let p_r = p.add(r); - let p_wm1 = p.add(w - 1); - if !same_bucket(&mut *p_r, &mut *p_wm1) { - if r != w { - let p_w = p_wm1.offset(1); - mem::swap(&mut *p_r, &mut *p_w); - } - w += 1; - } - r += 1; - } - - self.truncate(w); - } + pub fn dedup_by(&mut self, same_bucket: F) where F: FnMut(&mut T, &mut T) -> bool { + let len = { + let (dedup, _) = self.as_mut_slice().partition_dedup_by(same_bucket); + dedup.len() + }; + self.truncate(len); } /// Appends an element to the back of a collection. From 1b9da678114a6485f7bb20ba382c52097f6bfb29 Mon Sep 17 00:00:00 2001 From: gardrek Date: Sun, 23 Sep 2018 23:47:52 -0500 Subject: [PATCH 08/16] Fixed three small typos. --- src/libstd/primitive_docs.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 4c1fdc4f8953..8d54728a75f4 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -208,7 +208,7 @@ mod prim_bool { } /// # `!` and traits /// /// When writing your own traits, `!` should have an `impl` whenever there is an obvious `impl` -/// which doesn't `panic!`. As is turns out, most traits can have an `impl` for `!`. Take [`Debug`] +/// which doesn't `panic!`. As it turns out, most traits can have an `impl` for `!`. Take [`Debug`] /// for example: /// /// ``` @@ -228,9 +228,9 @@ mod prim_bool { } /// [`fmt::Result`]. Since this method takes a `&!` as an argument we know that it can never be /// called (because there is no value of type `!` for it to be called with). Writing `*self` /// essentially tells the compiler "We know that this code can never be run, so just treat the -/// entire function body has having type [`fmt::Result`]". This pattern can be used a lot when +/// entire function body as having type [`fmt::Result`]". This pattern can be used a lot when /// implementing traits for `!`. Generally, any trait which only has methods which take a `self` -/// parameter should have such as impl. +/// parameter should have such an impl. /// /// On the other hand, one trait which would not be appropriate to implement is [`Default`]: /// From f2bf92a4e8ee93dd033a35a810c64e56aee67825 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 24 Sep 2018 14:37:09 +0200 Subject: [PATCH 09/16] aarch64-pc-windows-msvc: Don't link libpanic_unwind to libtest. --- src/libtest/lib.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 6ffa6e9be937..f6383c19cb5e 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -45,9 +45,17 @@ extern crate getopts; #[cfg(any(unix, target_os = "cloudabi"))] extern crate libc; -extern crate panic_unwind; extern crate term; +// FIXME(#54291): rustc and/or LLVM don't yet support building with panic-unwind +// on aarch64-pc-windows-msvc, so we don't link libtest against +// libunwind (for the time being), even though it means that +// libtest won't be fully functional on this platform. +// +// See also: /~https://github.com/rust-lang/rust/issues/54190#issuecomment-422904437 +#[cfg(not(all(windows, target_arch = "aarch64")))] +extern crate panic_unwind; + pub use self::TestFn::*; pub use self::ColorConfig::*; pub use self::TestResult::*; From e09e45041b5cab9d849b554824c6683de6372e41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 24 Sep 2018 22:43:06 +0300 Subject: [PATCH 10/16] Rename slice::exact_chunks() to slice::chunks_exact() See /~https://github.com/rust-lang/rust/issues/47115#issuecomment-403090815 and /~https://github.com/rust-lang/rust/issues/47115#issuecomment-424053547 --- src/liballoc/lib.rs | 2 +- src/liballoc/slice.rs | 2 +- src/liballoc/tests/lib.rs | 2 +- src/liballoc/tests/slice.rs | 30 +++++++++---------- src/libcore/slice/mod.rs | 58 ++++++++++++++++++------------------- src/libcore/tests/lib.rs | 2 +- src/libcore/tests/slice.rs | 58 ++++++++++++++++++------------------- 7 files changed, 77 insertions(+), 77 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 089480c06d20..63ab5043ec51 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -116,7 +116,7 @@ #![feature(unsize)] #![feature(allocator_internals)] #![feature(on_unimplemented)] -#![feature(exact_chunks)] +#![feature(chunks_exact)] #![feature(rustc_const_unstable)] #![feature(const_vec_new)] #![feature(maybe_uninit)] diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 6c0b1c33a1f7..22c15fd8a519 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -123,7 +123,7 @@ pub use core::slice::{from_raw_parts, from_raw_parts_mut}; pub use core::slice::{from_ref, from_mut}; #[stable(feature = "slice_get_slice", since = "1.28.0")] pub use core::slice::SliceIndex; -#[unstable(feature = "exact_chunks", issue = "47115")] +#[unstable(feature = "chunks_exact", issue = "47115")] pub use core::slice::{ExactChunks, ExactChunksMut}; //////////////////////////////////////////////////////////////////////////////// diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 710c659ac539..6ff39227555f 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -20,7 +20,7 @@ #![feature(str_escape)] #![feature(try_reserve)] #![feature(unboxed_closures)] -#![feature(exact_chunks)] +#![feature(chunks_exact)] #![feature(repeat_generic_slice)] extern crate alloc_system; diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index f33bf64d40bd..c214c59618d3 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -975,27 +975,27 @@ fn test_chunksator_0() { } #[test] -fn test_exact_chunksator() { +fn test_chunks_exactator() { let v = &[1, 2, 3, 4, 5]; - assert_eq!(v.exact_chunks(2).len(), 2); + assert_eq!(v.chunks_exact(2).len(), 2); let chunks: &[&[_]] = &[&[1, 2], &[3, 4]]; - assert_eq!(v.exact_chunks(2).collect::>(), chunks); + assert_eq!(v.chunks_exact(2).collect::>(), chunks); let chunks: &[&[_]] = &[&[1, 2, 3]]; - assert_eq!(v.exact_chunks(3).collect::>(), chunks); + assert_eq!(v.chunks_exact(3).collect::>(), chunks); let chunks: &[&[_]] = &[]; - assert_eq!(v.exact_chunks(6).collect::>(), chunks); + assert_eq!(v.chunks_exact(6).collect::>(), chunks); let chunks: &[&[_]] = &[&[3, 4], &[1, 2]]; - assert_eq!(v.exact_chunks(2).rev().collect::>(), chunks); + assert_eq!(v.chunks_exact(2).rev().collect::>(), chunks); } #[test] #[should_panic] -fn test_exact_chunksator_0() { +fn test_chunks_exactator_0() { let v = &[1, 2, 3, 4]; - let _it = v.exact_chunks(0); + let _it = v.chunks_exact(0); } #[test] @@ -1235,10 +1235,10 @@ fn test_mut_chunks_0() { } #[test] -fn test_mut_exact_chunks() { +fn test_mut_chunks_exact() { let mut v = [0, 1, 2, 3, 4, 5, 6]; - assert_eq!(v.exact_chunks_mut(2).len(), 3); - for (i, chunk) in v.exact_chunks_mut(3).enumerate() { + assert_eq!(v.chunks_exact_mut(2).len(), 3); + for (i, chunk) in v.chunks_exact_mut(3).enumerate() { for x in chunk { *x = i as u8; } @@ -1248,9 +1248,9 @@ fn test_mut_exact_chunks() { } #[test] -fn test_mut_exact_chunks_rev() { +fn test_mut_chunks_exact_rev() { let mut v = [0, 1, 2, 3, 4, 5, 6]; - for (i, chunk) in v.exact_chunks_mut(3).rev().enumerate() { + for (i, chunk) in v.chunks_exact_mut(3).rev().enumerate() { for x in chunk { *x = i as u8; } @@ -1261,9 +1261,9 @@ fn test_mut_exact_chunks_rev() { #[test] #[should_panic] -fn test_mut_exact_chunks_0() { +fn test_mut_chunks_exact_0() { let mut v = [1, 2, 3, 4]; - let _it = v.exact_chunks_mut(0); + let _it = v.chunks_exact_mut(0); } #[test] diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index aed9020d9d14..68cefe4b6a8a 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -624,7 +624,7 @@ impl [T] { /// not divide the length of the slice, then the last chunk will /// not have length `chunk_size`. /// - /// See [`exact_chunks`] for a variant of this iterator that returns chunks + /// See [`chunks_exact`] for a variant of this iterator that returns chunks /// of always exactly `chunk_size` elements. /// /// # Panics @@ -642,7 +642,7 @@ impl [T] { /// assert!(iter.next().is_none()); /// ``` /// - /// [`exact_chunks`]: #method.exact_chunks + /// [`chunks_exact`]: #method.chunks_exact #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn chunks(&self, chunk_size: usize) -> Chunks { @@ -655,7 +655,7 @@ impl [T] { /// not divide the length of the slice, then the last chunk will not /// have length `chunk_size`. /// - /// See [`exact_chunks_mut`] for a variant of this iterator that returns chunks + /// See [`chunks_exact_mut`] for a variant of this iterator that returns chunks /// of always exactly `chunk_size` elements. /// /// # Panics @@ -677,7 +677,7 @@ impl [T] { /// assert_eq!(v, &[1, 1, 2, 2, 3]); /// ``` /// - /// [`exact_chunks_mut`]: #method.exact_chunks_mut + /// [`chunks_exact_mut`]: #method.chunks_exact_mut #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut { @@ -702,19 +702,19 @@ impl [T] { /// # Examples /// /// ``` - /// #![feature(exact_chunks)] + /// #![feature(chunks_exact)] /// /// let slice = ['l', 'o', 'r', 'e', 'm']; - /// let mut iter = slice.exact_chunks(2); + /// let mut iter = slice.chunks_exact(2); /// assert_eq!(iter.next().unwrap(), &['l', 'o']); /// assert_eq!(iter.next().unwrap(), &['r', 'e']); /// assert!(iter.next().is_none()); /// ``` /// /// [`chunks`]: #method.chunks - #[unstable(feature = "exact_chunks", issue = "47115")] + #[unstable(feature = "chunks_exact", issue = "47115")] #[inline] - pub fn exact_chunks(&self, chunk_size: usize) -> ExactChunks { + pub fn chunks_exact(&self, chunk_size: usize) -> ExactChunks { assert!(chunk_size != 0); let rem = self.len() % chunk_size; let len = self.len() - rem; @@ -739,12 +739,12 @@ impl [T] { /// # Examples /// /// ``` - /// #![feature(exact_chunks)] + /// #![feature(chunks_exact)] /// /// let v = &mut [0, 0, 0, 0, 0]; /// let mut count = 1; /// - /// for chunk in v.exact_chunks_mut(2) { + /// for chunk in v.chunks_exact_mut(2) { /// for elem in chunk.iter_mut() { /// *elem += count; /// } @@ -754,9 +754,9 @@ impl [T] { /// ``` /// /// [`chunks_mut`]: #method.chunks_mut - #[unstable(feature = "exact_chunks", issue = "47115")] + #[unstable(feature = "chunks_exact", issue = "47115")] #[inline] - pub fn exact_chunks_mut(&mut self, chunk_size: usize) -> ExactChunksMut { + pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ExactChunksMut { assert!(chunk_size != 0); let rem = self.len() % chunk_size; let len = self.len() - rem; @@ -3657,20 +3657,20 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> { /// up to `chunk_size-1` elements will be omitted but can be retrieved from /// the [`remainder`] function from the iterator. /// -/// This struct is created by the [`exact_chunks`] method on [slices]. +/// This struct is created by the [`chunks_exact`] method on [slices]. /// -/// [`exact_chunks`]: ../../std/primitive.slice.html#method.exact_chunks +/// [`chunks_exact`]: ../../std/primitive.slice.html#method.chunks_exact /// [`remainder`]: ../../std/slice/struct.ExactChunks.html#method.remainder /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] -#[unstable(feature = "exact_chunks", issue = "47115")] +#[unstable(feature = "chunks_exact", issue = "47115")] pub struct ExactChunks<'a, T:'a> { v: &'a [T], rem: &'a [T], chunk_size: usize } -#[unstable(feature = "exact_chunks", issue = "47115")] +#[unstable(feature = "chunks_exact", issue = "47115")] impl<'a, T> ExactChunks<'a, T> { /// Return the remainder of the original slice that is not going to be /// returned by the iterator. The returned slice has at most `chunk_size-1` @@ -3681,7 +3681,7 @@ impl<'a, T> ExactChunks<'a, T> { } // FIXME(#26925) Remove in favor of `#[derive(Clone)]` -#[unstable(feature = "exact_chunks", issue = "47115")] +#[unstable(feature = "chunks_exact", issue = "47115")] impl<'a, T> Clone for ExactChunks<'a, T> { fn clone(&self) -> ExactChunks<'a, T> { ExactChunks { @@ -3692,7 +3692,7 @@ impl<'a, T> Clone for ExactChunks<'a, T> { } } -#[unstable(feature = "exact_chunks", issue = "47115")] +#[unstable(feature = "chunks_exact", issue = "47115")] impl<'a, T> Iterator for ExactChunks<'a, T> { type Item = &'a [T]; @@ -3737,7 +3737,7 @@ impl<'a, T> Iterator for ExactChunks<'a, T> { } } -#[unstable(feature = "exact_chunks", issue = "47115")] +#[unstable(feature = "chunks_exact", issue = "47115")] impl<'a, T> DoubleEndedIterator for ExactChunks<'a, T> { #[inline] fn next_back(&mut self) -> Option<&'a [T]> { @@ -3751,7 +3751,7 @@ impl<'a, T> DoubleEndedIterator for ExactChunks<'a, T> { } } -#[unstable(feature = "exact_chunks", issue = "47115")] +#[unstable(feature = "chunks_exact", issue = "47115")] impl<'a, T> ExactSizeIterator for ExactChunks<'a, T> { fn is_empty(&self) -> bool { self.v.is_empty() @@ -3761,7 +3761,7 @@ impl<'a, T> ExactSizeIterator for ExactChunks<'a, T> { #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl<'a, T> TrustedLen for ExactChunks<'a, T> {} -#[unstable(feature = "exact_chunks", issue = "47115")] +#[unstable(feature = "chunks_exact", issue = "47115")] impl<'a, T> FusedIterator for ExactChunks<'a, T> {} #[doc(hidden)] @@ -3780,20 +3780,20 @@ unsafe impl<'a, T> TrustedRandomAccess for ExactChunks<'a, T> { /// `chunk_size-1` elements will be omitted but can be retrieved from the /// [`into_remainder`] function from the iterator. /// -/// This struct is created by the [`exact_chunks_mut`] method on [slices]. +/// This struct is created by the [`chunks_exact_mut`] method on [slices]. /// -/// [`exact_chunks_mut`]: ../../std/primitive.slice.html#method.exact_chunks_mut +/// [`chunks_exact_mut`]: ../../std/primitive.slice.html#method.chunks_exact_mut /// [`into_remainder`]: ../../std/slice/struct.ExactChunksMut.html#method.into_remainder /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] -#[unstable(feature = "exact_chunks", issue = "47115")] +#[unstable(feature = "chunks_exact", issue = "47115")] pub struct ExactChunksMut<'a, T:'a> { v: &'a mut [T], rem: &'a mut [T], chunk_size: usize } -#[unstable(feature = "exact_chunks", issue = "47115")] +#[unstable(feature = "chunks_exact", issue = "47115")] impl<'a, T> ExactChunksMut<'a, T> { /// Return the remainder of the original slice that is not going to be /// returned by the iterator. The returned slice has at most `chunk_size-1` @@ -3803,7 +3803,7 @@ impl<'a, T> ExactChunksMut<'a, T> { } } -#[unstable(feature = "exact_chunks", issue = "47115")] +#[unstable(feature = "chunks_exact", issue = "47115")] impl<'a, T> Iterator for ExactChunksMut<'a, T> { type Item = &'a mut [T]; @@ -3850,7 +3850,7 @@ impl<'a, T> Iterator for ExactChunksMut<'a, T> { } } -#[unstable(feature = "exact_chunks", issue = "47115")] +#[unstable(feature = "chunks_exact", issue = "47115")] impl<'a, T> DoubleEndedIterator for ExactChunksMut<'a, T> { #[inline] fn next_back(&mut self) -> Option<&'a mut [T]> { @@ -3866,7 +3866,7 @@ impl<'a, T> DoubleEndedIterator for ExactChunksMut<'a, T> { } } -#[unstable(feature = "exact_chunks", issue = "47115")] +#[unstable(feature = "chunks_exact", issue = "47115")] impl<'a, T> ExactSizeIterator for ExactChunksMut<'a, T> { fn is_empty(&self) -> bool { self.v.is_empty() @@ -3876,7 +3876,7 @@ impl<'a, T> ExactSizeIterator for ExactChunksMut<'a, T> { #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl<'a, T> TrustedLen for ExactChunksMut<'a, T> {} -#[unstable(feature = "exact_chunks", issue = "47115")] +#[unstable(feature = "chunks_exact", issue = "47115")] impl<'a, T> FusedIterator for ExactChunksMut<'a, T> {} #[doc(hidden)] diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 8fc32f40b992..97e5a5cee39d 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -33,7 +33,7 @@ #![feature(trusted_len)] #![feature(try_from)] #![feature(try_trait)] -#![feature(exact_chunks)] +#![feature(chunks_exact)] #![feature(align_offset)] #![feature(reverse_bits)] #![feature(inner_deref)] diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index d46a35ab82cf..b82ffb60b895 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -221,115 +221,115 @@ fn test_chunks_mut_zip() { } #[test] -fn test_exact_chunks_count() { +fn test_chunks_exact_count() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; - let c = v.exact_chunks(3); + let c = v.chunks_exact(3); assert_eq!(c.count(), 2); let v2: &[i32] = &[0, 1, 2, 3, 4]; - let c2 = v2.exact_chunks(2); + let c2 = v2.chunks_exact(2); assert_eq!(c2.count(), 2); let v3: &[i32] = &[]; - let c3 = v3.exact_chunks(2); + let c3 = v3.chunks_exact(2); assert_eq!(c3.count(), 0); } #[test] -fn test_exact_chunks_nth() { +fn test_chunks_exact_nth() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; - let mut c = v.exact_chunks(2); + let mut c = v.chunks_exact(2); assert_eq!(c.nth(1).unwrap(), &[2, 3]); assert_eq!(c.next().unwrap(), &[4, 5]); let v2: &[i32] = &[0, 1, 2, 3, 4, 5, 6]; - let mut c2 = v2.exact_chunks(3); + let mut c2 = v2.chunks_exact(3); assert_eq!(c2.nth(1).unwrap(), &[3, 4, 5]); assert_eq!(c2.next(), None); } #[test] -fn test_exact_chunks_last() { +fn test_chunks_exact_last() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; - let c = v.exact_chunks(2); + let c = v.chunks_exact(2); assert_eq!(c.last().unwrap(), &[4, 5]); let v2: &[i32] = &[0, 1, 2, 3, 4]; - let c2 = v2.exact_chunks(2); + let c2 = v2.chunks_exact(2); assert_eq!(c2.last().unwrap(), &[2, 3]); } #[test] -fn test_exact_chunks_remainder() { +fn test_chunks_exact_remainder() { let v: &[i32] = &[0, 1, 2, 3, 4]; - let c = v.exact_chunks(2); + let c = v.chunks_exact(2); assert_eq!(c.remainder(), &[4]); } #[test] -fn test_exact_chunks_zip() { +fn test_chunks_exact_zip() { let v1: &[i32] = &[0, 1, 2, 3, 4]; let v2: &[i32] = &[6, 7, 8, 9, 10]; - let res = v1.exact_chunks(2) - .zip(v2.exact_chunks(2)) + let res = v1.chunks_exact(2) + .zip(v2.chunks_exact(2)) .map(|(a, b)| a.iter().sum::() + b.iter().sum::()) .collect::>(); assert_eq!(res, vec![14, 22]); } #[test] -fn test_exact_chunks_mut_count() { +fn test_chunks_exact_mut_count() { let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5]; - let c = v.exact_chunks_mut(3); + let c = v.chunks_exact_mut(3); assert_eq!(c.count(), 2); let v2: &mut [i32] = &mut [0, 1, 2, 3, 4]; - let c2 = v2.exact_chunks_mut(2); + let c2 = v2.chunks_exact_mut(2); assert_eq!(c2.count(), 2); let v3: &mut [i32] = &mut []; - let c3 = v3.exact_chunks_mut(2); + let c3 = v3.chunks_exact_mut(2); assert_eq!(c3.count(), 0); } #[test] -fn test_exact_chunks_mut_nth() { +fn test_chunks_exact_mut_nth() { let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5]; - let mut c = v.exact_chunks_mut(2); + let mut c = v.chunks_exact_mut(2); assert_eq!(c.nth(1).unwrap(), &[2, 3]); assert_eq!(c.next().unwrap(), &[4, 5]); let v2: &mut [i32] = &mut [0, 1, 2, 3, 4, 5, 6]; - let mut c2 = v2.exact_chunks_mut(3); + let mut c2 = v2.chunks_exact_mut(3); assert_eq!(c2.nth(1).unwrap(), &[3, 4, 5]); assert_eq!(c2.next(), None); } #[test] -fn test_exact_chunks_mut_last() { +fn test_chunks_exact_mut_last() { let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5]; - let c = v.exact_chunks_mut(2); + let c = v.chunks_exact_mut(2); assert_eq!(c.last().unwrap(), &[4, 5]); let v2: &mut [i32] = &mut [0, 1, 2, 3, 4]; - let c2 = v2.exact_chunks_mut(2); + let c2 = v2.chunks_exact_mut(2); assert_eq!(c2.last().unwrap(), &[2, 3]); } #[test] -fn test_exact_chunks_mut_remainder() { +fn test_chunks_exact_mut_remainder() { let v: &mut [i32] = &mut [0, 1, 2, 3, 4]; - let c = v.exact_chunks_mut(2); + let c = v.chunks_exact_mut(2); assert_eq!(c.into_remainder(), &[4]); } #[test] -fn test_exact_chunks_mut_zip() { +fn test_chunks_exact_mut_zip() { let v1: &mut [i32] = &mut [0, 1, 2, 3, 4]; let v2: &[i32] = &[6, 7, 8, 9, 10]; - for (a, b) in v1.exact_chunks_mut(2).zip(v2.exact_chunks(2)) { + for (a, b) in v1.chunks_exact_mut(2).zip(v2.chunks_exact(2)) { let sum = b.iter().sum::(); for v in a { *v += sum; From 827047c18b840ceefb1f082dfed94437c930984f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 24 Sep 2018 22:04:23 +0200 Subject: [PATCH 11/16] Fix JS error --- src/librustdoc/html/static/main.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 3dbefabace18..0b56692bc2e7 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1991,8 +1991,11 @@ } }; if (getCurrentValue('rustdoc-trait-implementations') !== "false") { - onEach(document.getElementById('implementations-list') - .getElementsByClassName("collapse-toggle"), collapser); + var impl_list = document.getElementById('implementations-list'); + + if (impl_list !== null) { + onEach(impl_list.getElementsByClassName("collapse-toggle"), collapser); + } } if (getCurrentValue('rustdoc-method-docs') !== "false") { var implItems = document.getElementsByClassName('impl-items'); From 068c92b2cc0620d18eee1066cd3460f37c9ed9f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 25 Sep 2018 08:56:48 +0300 Subject: [PATCH 12/16] Also rename ExactChunks iterator name to ChunksExact --- src/liballoc/slice.rs | 2 +- src/libcore/slice/mod.rs | 50 ++++++++++++++++++++-------------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 22c15fd8a519..33d28bef2d70 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -124,7 +124,7 @@ pub use core::slice::{from_ref, from_mut}; #[stable(feature = "slice_get_slice", since = "1.28.0")] pub use core::slice::SliceIndex; #[unstable(feature = "chunks_exact", issue = "47115")] -pub use core::slice::{ExactChunks, ExactChunksMut}; +pub use core::slice::{ChunksExact, ChunksExactMut}; //////////////////////////////////////////////////////////////////////////////// // Basic slice extension methods diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 68cefe4b6a8a..b3f90e3eee88 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -714,12 +714,12 @@ impl [T] { /// [`chunks`]: #method.chunks #[unstable(feature = "chunks_exact", issue = "47115")] #[inline] - pub fn chunks_exact(&self, chunk_size: usize) -> ExactChunks { + pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact { assert!(chunk_size != 0); let rem = self.len() % chunk_size; let len = self.len() - rem; let (fst, snd) = self.split_at(len); - ExactChunks { v: fst, rem: snd, chunk_size } + ChunksExact { v: fst, rem: snd, chunk_size } } /// Returns an iterator over `chunk_size` elements of the slice at a time. @@ -756,12 +756,12 @@ impl [T] { /// [`chunks_mut`]: #method.chunks_mut #[unstable(feature = "chunks_exact", issue = "47115")] #[inline] - pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ExactChunksMut { + pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut { assert!(chunk_size != 0); let rem = self.len() % chunk_size; let len = self.len() - rem; let (fst, snd) = self.split_at_mut(len); - ExactChunksMut { v: fst, rem: snd, chunk_size } + ChunksExactMut { v: fst, rem: snd, chunk_size } } /// Divides one slice into two at an index. @@ -3660,18 +3660,18 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> { /// This struct is created by the [`chunks_exact`] method on [slices]. /// /// [`chunks_exact`]: ../../std/primitive.slice.html#method.chunks_exact -/// [`remainder`]: ../../std/slice/struct.ExactChunks.html#method.remainder +/// [`remainder`]: ../../std/slice/struct.ChunksExact.html#method.remainder /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] #[unstable(feature = "chunks_exact", issue = "47115")] -pub struct ExactChunks<'a, T:'a> { +pub struct ChunksExact<'a, T:'a> { v: &'a [T], rem: &'a [T], chunk_size: usize } #[unstable(feature = "chunks_exact", issue = "47115")] -impl<'a, T> ExactChunks<'a, T> { +impl<'a, T> ChunksExact<'a, T> { /// Return the remainder of the original slice that is not going to be /// returned by the iterator. The returned slice has at most `chunk_size-1` /// elements. @@ -3682,9 +3682,9 @@ impl<'a, T> ExactChunks<'a, T> { // FIXME(#26925) Remove in favor of `#[derive(Clone)]` #[unstable(feature = "chunks_exact", issue = "47115")] -impl<'a, T> Clone for ExactChunks<'a, T> { - fn clone(&self) -> ExactChunks<'a, T> { - ExactChunks { +impl<'a, T> Clone for ChunksExact<'a, T> { + fn clone(&self) -> ChunksExact<'a, T> { + ChunksExact { v: self.v, rem: self.rem, chunk_size: self.chunk_size, @@ -3693,7 +3693,7 @@ impl<'a, T> Clone for ExactChunks<'a, T> { } #[unstable(feature = "chunks_exact", issue = "47115")] -impl<'a, T> Iterator for ExactChunks<'a, T> { +impl<'a, T> Iterator for ChunksExact<'a, T> { type Item = &'a [T]; #[inline] @@ -3738,7 +3738,7 @@ impl<'a, T> Iterator for ExactChunks<'a, T> { } #[unstable(feature = "chunks_exact", issue = "47115")] -impl<'a, T> DoubleEndedIterator for ExactChunks<'a, T> { +impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> { #[inline] fn next_back(&mut self) -> Option<&'a [T]> { if self.v.len() < self.chunk_size { @@ -3752,20 +3752,20 @@ impl<'a, T> DoubleEndedIterator for ExactChunks<'a, T> { } #[unstable(feature = "chunks_exact", issue = "47115")] -impl<'a, T> ExactSizeIterator for ExactChunks<'a, T> { +impl<'a, T> ExactSizeIterator for ChunksExact<'a, T> { fn is_empty(&self) -> bool { self.v.is_empty() } } #[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl<'a, T> TrustedLen for ExactChunks<'a, T> {} +unsafe impl<'a, T> TrustedLen for ChunksExact<'a, T> {} #[unstable(feature = "chunks_exact", issue = "47115")] -impl<'a, T> FusedIterator for ExactChunks<'a, T> {} +impl<'a, T> FusedIterator for ChunksExact<'a, T> {} #[doc(hidden)] -unsafe impl<'a, T> TrustedRandomAccess for ExactChunks<'a, T> { +unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> { unsafe fn get_unchecked(&mut self, i: usize) -> &'a [T] { let start = i * self.chunk_size; from_raw_parts(self.v.as_ptr().add(start), self.chunk_size) @@ -3783,18 +3783,18 @@ unsafe impl<'a, T> TrustedRandomAccess for ExactChunks<'a, T> { /// This struct is created by the [`chunks_exact_mut`] method on [slices]. /// /// [`chunks_exact_mut`]: ../../std/primitive.slice.html#method.chunks_exact_mut -/// [`into_remainder`]: ../../std/slice/struct.ExactChunksMut.html#method.into_remainder +/// [`into_remainder`]: ../../std/slice/struct.ChunksExactMut.html#method.into_remainder /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] #[unstable(feature = "chunks_exact", issue = "47115")] -pub struct ExactChunksMut<'a, T:'a> { +pub struct ChunksExactMut<'a, T:'a> { v: &'a mut [T], rem: &'a mut [T], chunk_size: usize } #[unstable(feature = "chunks_exact", issue = "47115")] -impl<'a, T> ExactChunksMut<'a, T> { +impl<'a, T> ChunksExactMut<'a, T> { /// Return the remainder of the original slice that is not going to be /// returned by the iterator. The returned slice has at most `chunk_size-1` /// elements. @@ -3804,7 +3804,7 @@ impl<'a, T> ExactChunksMut<'a, T> { } #[unstable(feature = "chunks_exact", issue = "47115")] -impl<'a, T> Iterator for ExactChunksMut<'a, T> { +impl<'a, T> Iterator for ChunksExactMut<'a, T> { type Item = &'a mut [T]; #[inline] @@ -3851,7 +3851,7 @@ impl<'a, T> Iterator for ExactChunksMut<'a, T> { } #[unstable(feature = "chunks_exact", issue = "47115")] -impl<'a, T> DoubleEndedIterator for ExactChunksMut<'a, T> { +impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> { #[inline] fn next_back(&mut self) -> Option<&'a mut [T]> { if self.v.len() < self.chunk_size { @@ -3867,20 +3867,20 @@ impl<'a, T> DoubleEndedIterator for ExactChunksMut<'a, T> { } #[unstable(feature = "chunks_exact", issue = "47115")] -impl<'a, T> ExactSizeIterator for ExactChunksMut<'a, T> { +impl<'a, T> ExactSizeIterator for ChunksExactMut<'a, T> { fn is_empty(&self) -> bool { self.v.is_empty() } } #[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl<'a, T> TrustedLen for ExactChunksMut<'a, T> {} +unsafe impl<'a, T> TrustedLen for ChunksExactMut<'a, T> {} #[unstable(feature = "chunks_exact", issue = "47115")] -impl<'a, T> FusedIterator for ExactChunksMut<'a, T> {} +impl<'a, T> FusedIterator for ChunksExactMut<'a, T> {} #[doc(hidden)] -unsafe impl<'a, T> TrustedRandomAccess for ExactChunksMut<'a, T> { +unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> { unsafe fn get_unchecked(&mut self, i: usize) -> &'a mut [T] { let start = i * self.chunk_size; from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) From 992e220935f1d4c60ada2b0da625a83b85724f04 Mon Sep 17 00:00:00 2001 From: Son Date: Tue, 25 Sep 2018 21:59:58 +1000 Subject: [PATCH 13/16] Add examples for doc --- src/libcore/char/convert.rs | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/libcore/char/convert.rs b/src/libcore/char/convert.rs index 6c2c02951af6..e9ccdd0ea3c5 100644 --- a/src/libcore/char/convert.rs +++ b/src/libcore/char/convert.rs @@ -117,8 +117,17 @@ pub unsafe fn from_u32_unchecked(i: u32) -> char { impl From for u32 { /// Converts a [`char`] into a [`u32`]. /// - /// [`char`]: primitive.char.html - /// [`u32`]: primitive.u32.html + /// # Examples + /// + /// ``` + /// use std::mem; + /// + /// fn main() { + /// let c = 'c'; + /// let u = u32::from(c); + /// assert!(4 == mem::size_of_val(&u)) + /// } + /// ``` #[inline] fn from(c: char) -> Self { c as u32 @@ -147,8 +156,17 @@ impl From for u32 { impl From for char { /// Converts a [`u8`] into a [`char`]. /// - /// [`u8`]: primitive.u8.html - /// [`char`]: primitive.char.html + /// # Examples + /// + /// ``` + /// use std::mem; + /// + /// fn main() { + /// let u = 32 as u8; + /// let c = char::from(u); + /// assert!(4 == mem::size_of_val(&c)) + /// } + /// ``` #[inline] fn from(i: u8) -> Self { i as char From 8fc7b5d12bfe6b2d7f8705db8bfc7fdcd6704d2e Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 25 Sep 2018 17:06:18 +0200 Subject: [PATCH 14/16] incr.comp.: Don't automatically enable -Zshare-generics for incr.comp. builds. --- src/librustc/session/config.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 1fdbf687be8f..8fa15d48a5dc 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -646,7 +646,6 @@ impl Options { match self.debugging_opts.share_generics { Some(setting) => setting, None => { - self.incremental.is_some() || match self.optimize { OptLevel::No | OptLevel::Less | From f4b4939f3e024c53355d4f99c0762135a613dae0 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Tue, 25 Sep 2018 09:13:02 -0600 Subject: [PATCH 15/16] Improvements to finding LLVM's FileCheck This patch adds a few improvements to how the build system finds LLVM's FileCheck program. * On Fedora, the system LLVM installs FileCheck in the "llvm" subdirectory of the LLVM libdir. This patch teaches the build system to look there. * This adds a configure option to specify which llvm-config executable to use. This is handy on systems that can parallel install multiple versions of LLVM; for example I can now: ./configure --llvm-config=/bin/llvm-config-5.0-64 ... to build against LLVM 5, rather than whatever the default llvm-config might be. * Finally, this adds a configure- and config.toml- option to set the path to FileCheck. This is handy when building against an LLVM where FileCheck was not installed. This happens on compatibility installs of LLVM on Fedora. --- config.toml.example | 5 +++++ src/bootstrap/config.rs | 6 ++++++ src/bootstrap/configure.py | 6 ++++++ src/bootstrap/lib.rs | 23 +++++++++++++++++++++-- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/config.toml.example b/config.toml.example index 3159c19528af..66eaab236f7c 100644 --- a/config.toml.example +++ b/config.toml.example @@ -322,6 +322,7 @@ # Flag indicating whether codegen tests will be run or not. If you get an error # saying that the FileCheck executable is missing, you may want to disable this. +# Also see the target's llvm-filecheck option. #codegen-tests = true # Flag indicating whether git info will be retrieved from .git automatically. @@ -416,6 +417,10 @@ # target. #llvm-config = "../path/to/llvm/root/bin/llvm-config" +# Normally the build system can find LLVM's FileCheck utility, but if +# not, you can specify an explicit file name for it. +#llvm-filecheck = "/path/to/FileCheck" + # Path to the custom jemalloc static library to link into the standard library # by default. This is only used if jemalloc is still enabled above #jemalloc = "/path/to/jemalloc/libjemalloc_pic.a" diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index cc6d76c76f2f..3a4bc526d03b 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -162,6 +162,8 @@ pub struct Config { pub struct Target { /// Some(path to llvm-config) if using an external LLVM. pub llvm_config: Option, + /// Some(path to FileCheck) if one was specified. + pub llvm_filecheck: Option, pub jemalloc: Option, pub cc: Option, pub cxx: Option, @@ -330,6 +332,7 @@ struct Rust { #[serde(deny_unknown_fields, rename_all = "kebab-case")] struct TomlTarget { llvm_config: Option, + llvm_filecheck: Option, jemalloc: Option, cc: Option, cxx: Option, @@ -583,6 +586,9 @@ impl Config { if let Some(ref s) = cfg.llvm_config { target.llvm_config = Some(config.src.join(s)); } + if let Some(ref s) = cfg.llvm_filecheck { + target.llvm_filecheck = Some(config.src.join(s)); + } if let Some(ref s) = cfg.jemalloc { target.jemalloc = Some(config.src.join(s)); } diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index cf7f78eeba04..75831dbe262a 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -95,6 +95,8 @@ def v(*args): v("bindir", "install.bindir", "install binaries") v("llvm-root", None, "set LLVM root") +v("llvm-config", None, "set path to llvm-config") +v("llvm-filecheck", None, "set path to LLVM's FileCheck utility") v("python", "build.python", "set path to python") v("jemalloc-root", None, "set directory where libjemalloc_pic.a is located") v("android-cross-path", "target.arm-linux-androideabi.android-ndk", @@ -323,6 +325,10 @@ def set(key, value): set('build.cargo', value + '/bin/cargo') elif option.name == 'llvm-root': set('target.{}.llvm-config'.format(build()), value + '/bin/llvm-config') + elif option.name == 'llvm-config': + set('target.{}.llvm-config'.format(build()), value) + elif option.name == 'llvm-filecheck': + set('target.{}.llvm-filecheck'.format(build()), value) elif option.name == 'jemalloc-root': set('target.{}.jemalloc'.format(build()), value + '/libjemalloc_pic.a') elif option.name == 'tools': diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 6b88516bacd8..75c18cd2dd41 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -641,9 +641,28 @@ impl Build { /// Returns the path to `FileCheck` binary for the specified target fn llvm_filecheck(&self, target: Interned) -> PathBuf { let target_config = self.config.target_config.get(&target); - if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) { + if let Some(s) = target_config.and_then(|c| c.llvm_filecheck.as_ref()) { + s.to_path_buf() + } else if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) { let llvm_bindir = output(Command::new(s).arg("--bindir")); - Path::new(llvm_bindir.trim()).join(exe("FileCheck", &*target)) + let filecheck = Path::new(llvm_bindir.trim()).join(exe("FileCheck", &*target)); + if filecheck.exists() { + filecheck + } else { + // On Fedora the system LLVM installs FileCheck in the + // llvm subdirectory of the libdir. + let llvm_libdir = output(Command::new(s).arg("--libdir")); + let lib_filecheck = Path::new(llvm_libdir.trim()) + .join("llvm").join(exe("FileCheck", &*target)); + if lib_filecheck.exists() { + lib_filecheck + } else { + // Return the most normal file name, even though + // it doesn't exist, so that any error message + // refers to that. + filecheck + } + } } else { let base = self.llvm_out(self.config.build).join("build"); let base = if !self.config.ninja && self.config.build.contains("msvc") { From ee05f6eef4f97188a94874eacf2dad59f9f11f47 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 24 Sep 2018 02:26:26 +0300 Subject: [PATCH 16/16] resolve: Do not block derive helper resolutions on single import resolutions Derive helpers conflict currently conflict with anything else, so if some resolution from a single import appears later, it will result in error anyway --- src/librustc_resolve/macros.rs | 20 ++++++------- .../proc-macro/proc-macro-attributes.rs | 6 ++-- .../custom-derive/auxiliary/plugin.rs | 10 +++++++ .../helper-attr-blocked-by-import-ambig.rs | 13 +++++++++ ...helper-attr-blocked-by-import-ambig.stderr | 20 +++++++++++++ .../helper-attr-blocked-by-import.rs | 29 +++++++++++++++++++ .../proc-macro/derive-helper-shadowing.stderr | 13 ++++----- 7 files changed, 90 insertions(+), 21 deletions(-) create mode 100644 src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.rs create mode 100644 src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr create mode 100644 src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import.rs diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 35d96b9302b4..89bc2f2709a3 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -575,6 +575,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // 5. Standard library prelude (de-facto closed, controlled). // 6. Language prelude (closed, controlled). // (Macro NS) + // 0. Derive helpers (open, not controlled). All ambiguities with other names + // are currently reported as errors. They should be higher in priority than preludes + // and probably even names in modules according to the "general principles" above. They + // also should be subject to restricted shadowing because are effectively produced by + // derives (you need to resolve the derive first to add helpers into scope), but they + // should be available before the derive is expanded for compatibility. + // It's mess in general, so we are being conservative for now. // 1. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents // (open, not controlled). // 2. `macro_use` prelude (open, the open part is from macro expansions, not controlled). @@ -583,13 +590,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // 2b. Standard library prelude is currently implemented as `macro-use` (closed, controlled) // 3. Language prelude: builtin macros (closed, controlled, except for legacy plugins). // 4. Language prelude: builtin attributes (closed, controlled). - // N (unordered). Derive helpers (open, not controlled). All ambiguities with other names - // are currently reported as errors. They should be higher in priority than preludes - // and maybe even names in modules according to the "general principles" above. They - // also should be subject to restricted shadowing because are effectively produced by - // derives (you need to resolve the derive first to add helpers into scope), but they - // should be available before the derive is expanded for compatibility. - // It's mess in general, so we are being conservative for now. assert!(ns == TypeNS || ns == MacroNS); assert!(force || !record_used); // `record_used` implies `force` @@ -621,7 +621,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } // Go through all the scopes and try to resolve the name. - let mut where_to_resolve = WhereToResolve::Module(parent_scope.module); + let mut where_to_resolve = WhereToResolve::DeriveHelpers; let mut use_prelude = !parent_scope.module.no_implicit_prelude; loop { let result = match where_to_resolve { @@ -751,8 +751,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } WhereToResolve::MacroUsePrelude => WhereToResolve::BuiltinMacros, WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs, - WhereToResolve::BuiltinAttrs => WhereToResolve::DeriveHelpers, - WhereToResolve::DeriveHelpers => break, // nowhere else to search + WhereToResolve::BuiltinAttrs => break, // nowhere else to search + WhereToResolve::DeriveHelpers => WhereToResolve::Module(parent_scope.module), WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude, WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude, WhereToResolve::StdLibPrelude => WhereToResolve::BuiltinTypes, diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs index 83bbb7c13c43..d0aed8b16248 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs @@ -11,13 +11,11 @@ // aux-build:derive-b.rs // ignore-stage1 -#![allow(warnings)] - #[macro_use] extern crate derive_b; -#[B] //~ ERROR `B` is a derive mode -#[C] +#[B] +#[C] //~ ERROR attribute `C` is currently unknown to the compiler #[B(D)] #[B(E = "foo")] #[B(arbitrary tokens)] diff --git a/src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs b/src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs index 7be909c3c9e8..124bc05b7a34 100644 --- a/src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs +++ b/src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs @@ -25,3 +25,13 @@ pub fn derive_foo(input: TokenStream) -> TokenStream { pub fn derive_bar(input: TokenStream) -> TokenStream { panic!("lolnope"); } + +#[proc_macro_derive(WithHelper, attributes(helper))] +pub fn with_helper(input: TokenStream) -> TokenStream { + TokenStream::new() +} + +#[proc_macro_attribute] +pub fn helper(_: TokenStream, input: TokenStream) -> TokenStream { + input +} diff --git a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.rs b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.rs new file mode 100644 index 000000000000..b750a8bb0d93 --- /dev/null +++ b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.rs @@ -0,0 +1,13 @@ +// aux-build:plugin.rs +// ignore-stage1 + +#[macro_use(WithHelper)] +extern crate plugin; + +use plugin::helper; + +#[derive(WithHelper)] +#[helper] //~ ERROR `helper` is ambiguous +struct S; + +fn main() {} diff --git a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr new file mode 100644 index 000000000000..059629c0b62d --- /dev/null +++ b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr @@ -0,0 +1,20 @@ +error[E0659]: `helper` is ambiguous + --> $DIR/helper-attr-blocked-by-import-ambig.rs:10:3 + | +LL | #[helper] //~ ERROR `helper` is ambiguous + | ^^^^^^ ambiguous name + | +note: `helper` could refer to the name defined here + --> $DIR/helper-attr-blocked-by-import-ambig.rs:9:10 + | +LL | #[derive(WithHelper)] + | ^^^^^^^^^^ +note: `helper` could also refer to the name imported here + --> $DIR/helper-attr-blocked-by-import-ambig.rs:7:5 + | +LL | use plugin::helper; + | ^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import.rs b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import.rs new file mode 100644 index 000000000000..03b774f6c640 --- /dev/null +++ b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import.rs @@ -0,0 +1,29 @@ +// compile-pass +// aux-build:plugin.rs +// ignore-stage1 + +#[macro_use(WithHelper)] +extern crate plugin; + +use self::one::*; +use self::two::*; + +mod helper {} + +mod one { + use helper; + + #[derive(WithHelper)] + #[helper] + struct One; +} + +mod two { + use helper; + + #[derive(WithHelper)] + #[helper] + struct Two; +} + +fn main() {} diff --git a/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr b/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr index cdfecb3d1014..e0aeae4ba6c5 100644 --- a/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr +++ b/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr @@ -4,17 +4,16 @@ error[E0659]: `my_attr` is ambiguous LL | #[my_attr] //~ ERROR `my_attr` is ambiguous | ^^^^^^^ ambiguous name | -note: `my_attr` could refer to the name imported here - --> $DIR/derive-helper-shadowing.rs:4:5 - | -LL | use derive_helper_shadowing::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: `my_attr` could also refer to the name defined here +note: `my_attr` could refer to the name defined here --> $DIR/derive-helper-shadowing.rs:7:10 | LL | #[derive(MyTrait)] | ^^^^^^^ - = note: consider adding an explicit import of `my_attr` to disambiguate +note: `my_attr` could also refer to the name imported here + --> $DIR/derive-helper-shadowing.rs:4:5 + | +LL | use derive_helper_shadowing::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error