From 6c3ebcd223af3ebd4d45cd4a648b8b25ef6d3ba3 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 30 May 2018 21:00:37 +0200 Subject: [PATCH 01/11] make Layout's align a NonZeroUsize --- src/libcore/alloc.rs | 74 +++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 674c4fb57c7f0..064c7514112b5 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -20,6 +20,7 @@ use fmt; use mem; use usize; use ptr::{self, NonNull}; +use num::NonZeroUsize; extern { /// An opaque, unsized type. Used for pointers to allocated memory. @@ -66,7 +67,7 @@ fn size_align() -> (usize, usize) { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Layout { // size of the requested block of memory, measured in bytes. - size: usize, + size_: usize, // alignment of the requested block of memory, measured in bytes. // we ensure that this is always a power-of-two, because API's @@ -75,17 +76,12 @@ pub struct Layout { // // (However, we do not analogously require `align >= sizeof(void*)`, // even though that is *also* a requirement of `posix_memalign`.) - align: usize, + align_: NonZeroUsize, } - -// FIXME: audit default implementations for overflow errors, -// (potentially switching to overflowing_add and -// overflowing_mul as necessary). - impl Layout { /// Constructs a `Layout` from a given `size` and `align`, - /// or returns `None` if either of the following conditions + /// or returns `LayoutErr` if either of the following conditions /// are not met: /// /// * `align` must be a power of two, @@ -126,23 +122,23 @@ impl Layout { /// /// # Safety /// - /// This function is unsafe as it does not verify that `align` is - /// a power-of-two nor `size` aligned to `align` fits within the - /// address space (i.e. the `Layout::from_size_align` preconditions). + /// This function is unsafe as it does not verify the preconditions from + /// [`Layout::from_size_align`](#method.from_size_align). #[inline] pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self { - Layout { size: size, align: align } + Layout { size_: size, align_: NonZeroUsize::new_unchecked(align) } } /// The minimum size in bytes for a memory block of this layout. #[inline] - pub fn size(&self) -> usize { self.size } + pub fn size(&self) -> usize { self.size_ } /// The minimum byte alignment for a memory block of this layout. #[inline] - pub fn align(&self) -> usize { self.align } + pub fn align(&self) -> usize { self.align_.get() } /// Constructs a `Layout` suitable for holding a value of type `T`. + #[inline] pub fn new() -> Self { let (size, align) = size_align::(); // Note that the align is guaranteed by rustc to be a power of two and @@ -158,6 +154,7 @@ impl Layout { /// Produces layout describing a record that could be used to /// allocate backing structure for `T` (which could be a trait /// or other unsized type like a slice). + #[inline] pub fn for_value(t: &T) -> Self { let (size, align) = (mem::size_of_val(t), mem::align_of_val(t)); // See rationale in `new` for why this us using an unsafe variant below @@ -181,18 +178,19 @@ impl Layout { /// /// # Panics /// - /// Panics if the combination of `self.size` and the given `align` - /// violates the conditions listed in `from_size_align`. + /// Panics if the combination of `self.size()` and the given `align` + /// violates the conditions listed in + /// [`Layout::from_size_align`](#method.from_size_align). #[inline] pub fn align_to(&self, align: usize) -> Self { - Layout::from_size_align(self.size, cmp::max(self.align, align)).unwrap() + Layout::from_size_align(self.size(), cmp::max(self.align(), align)).unwrap() } /// Returns the amount of padding we must insert after `self` /// to ensure that the following address will satisfy `align` /// (measured in bytes). /// - /// E.g. if `self.size` is 9, then `self.padding_needed_for(4)` + /// E.g. if `self.size()` is 9, then `self.padding_needed_for(4)` /// returns 3, because that is the minimum number of bytes of /// padding required to get a 4-aligned address (assuming that the /// corresponding memory block starts at a 4-aligned address). @@ -203,9 +201,12 @@ impl Layout { /// Note that the utility of the returned value requires `align` /// to be less than or equal to the alignment of the starting /// address for the whole allocated block of memory. One way to - /// satisfy this constraint is to ensure `align <= self.align`. + /// satisfy this constraint is to ensure `align <= self.align()`. #[inline] pub fn padding_needed_for(&self, align: usize) -> usize { + // **FIXME**: This function is only called with proper power-of-two + // alignments. Maybe we should turn this into a real assert!. + debug_assert!(align.is_power_of_two()); let len = self.size(); // Rounded up value is: @@ -227,7 +228,8 @@ impl Layout { // size and padding overflow in the above manner should cause // the allocator to yield an error anyway.) - let len_rounded_up = len.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1); + let len_rounded_up = len.wrapping_add(align).wrapping_sub(1) + & !align.wrapping_sub(1); return len_rounded_up.wrapping_sub(len); } @@ -238,14 +240,14 @@ impl Layout { /// layout of the array and `offs` is the distance between the start /// of each element in the array. /// - /// On arithmetic overflow, returns `None`. + /// On arithmetic overflow, returns `LayoutErr`. #[inline] pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutErr> { - let padded_size = self.size.checked_add(self.padding_needed_for(self.align)) + let padded_size = self.size().checked_add(self.padding_needed_for(self.align())) .ok_or(LayoutErr { private: () })?; let alloc_size = padded_size.checked_mul(n) .ok_or(LayoutErr { private: () })?; - Ok((Layout::from_size_align(alloc_size, self.align)?, padded_size)) + Ok((Layout::from_size_align(alloc_size, self.align())?, padded_size)) } /// Creates a layout describing the record for `self` followed by @@ -258,16 +260,16 @@ impl Layout { /// start of the `next` embedded within the concatenated record /// (assuming that the record itself starts at offset 0). /// - /// On arithmetic overflow, returns `None`. + /// On arithmetic overflow, returns `LayoutErr`. pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> { - let new_align = cmp::max(self.align, next.align); - let realigned = Layout::from_size_align(self.size, new_align)?; + let new_align = cmp::max(self.align(), next.align()); + let realigned = Layout::from_size_align(self.size(), new_align)?; - let pad = realigned.padding_needed_for(next.align); + let pad = realigned.padding_needed_for(next.align()); - let offset = self.size.checked_add(pad) + let offset = self.size().checked_add(pad) .ok_or(LayoutErr { private: () })?; - let new_size = offset.checked_add(next.size) + let new_size = offset.checked_add(next.size()) .ok_or(LayoutErr { private: () })?; let layout = Layout::from_size_align(new_size, new_align)?; @@ -285,10 +287,10 @@ impl Layout { /// guaranteed that all elements in the array will be properly /// aligned. /// - /// On arithmetic overflow, returns `None`. + /// On arithmetic overflow, returns `LayoutErr`. pub fn repeat_packed(&self, n: usize) -> Result { let size = self.size().checked_mul(n).ok_or(LayoutErr { private: () })?; - Layout::from_size_align(size, self.align) + Layout::from_size_align(size, self.align()) } /// Creates a layout describing the record for `self` followed by @@ -305,17 +307,17 @@ impl Layout { /// signature out of convenience in matching the signature of /// `extend`.) /// - /// On arithmetic overflow, returns `None`. + /// On arithmetic overflow, returns `LayoutErr`. pub fn extend_packed(&self, next: Self) -> Result<(Self, usize), LayoutErr> { let new_size = self.size().checked_add(next.size()) .ok_or(LayoutErr { private: () })?; - let layout = Layout::from_size_align(new_size, self.align)?; + let layout = Layout::from_size_align(new_size, self.align())?; Ok((layout, self.size())) } /// Creates a layout describing the record for a `[T; n]`. /// - /// On arithmetic overflow, returns `None`. + /// On arithmetic overflow, returns `LayoutErr`. pub fn array(n: usize) -> Result { Layout::new::() .repeat(n) @@ -834,7 +836,7 @@ pub unsafe trait Alloc { layout: Layout, new_size: usize) -> Result<(), CannotReallocInPlace> { let _ = ptr; // this default implementation doesn't care about the actual address. - debug_assert!(new_size >= layout.size); + debug_assert!(new_size >= layout.size()); let (_l, u) = self.usable_size(&layout); // _l <= layout.size() [guaranteed by usable_size()] // layout.size() <= new_layout.size() [required by this method] @@ -889,7 +891,7 @@ pub unsafe trait Alloc { layout: Layout, new_size: usize) -> Result<(), CannotReallocInPlace> { let _ = ptr; // this default implementation doesn't care about the actual address. - debug_assert!(new_size <= layout.size); + debug_assert!(new_size <= layout.size()); let (l, _u) = self.usable_size(&layout); // layout.size() <= _u [guaranteed by usable_size()] // new_layout.size() <= layout.size() [required by this method] From 7585632052298f9c84cc12ac5afcb23786ae1d3d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 2 Jun 2018 13:47:42 +0200 Subject: [PATCH 02/11] Fix run button style --- src/librustdoc/html/static/rustdoc.css | 3 ++- src/librustdoc/html/static/themes/dark.css | 3 ++- src/librustdoc/html/static/themes/light.css | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 83abf35c85484..2876f0d71adf0 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -561,7 +561,8 @@ a { content: '\2002\00a7\2002'; } -.docblock a:not(.srclink):hover, .docblock-short a:not(.srclink):hover, .stability a { +.docblock a:not(.srclink):not(.test-arrow):hover, +.docblock-short a:not(.srclink):not(.test-arrow):hover, .stability a { text-decoration: underline; } diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 765ef0cd415b7..f96dcd9ec1c88 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -163,7 +163,8 @@ a { color: #ddd; } -.docblock a:not(.srclink), .docblock-short a:not(.srclink), .stability a { +.docblock a:not(.srclink):not(.test-arrow), .docblock-short a:not(.srclink):not(.test-arrow), +.stability a { color: #D2991D; } diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 5971dc43deda4..54cf50cfffd1e 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -163,7 +163,8 @@ a { color: #000; } -.docblock a:not(.srclink), .docblock-short a:not(.srclink), .stability a { +.docblock a:not(.srclink):not(.test-arrow), .docblock-short a:not(.srclink):not(.test-arrow), +.stability a { color: #3873AD; } From 5c374739b679612c2fe8d033b0607beb14a5c4d3 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Mon, 28 May 2018 17:54:12 -0600 Subject: [PATCH 03/11] Specify that packed types must derive, not implement, Copy --- src/librustc_mir/transform/check_unsafety.rs | 4 ++-- src/test/ui/deriving-with-repr-packed.rs | 2 +- src/test/ui/deriving-with-repr-packed.stderr | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index fedd0774df44c..4c282f037a5cc 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -362,8 +362,8 @@ fn unsafe_derive_on_repr_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: D format!("#[derive] can't be used on a #[repr(packed)] struct with \ type parameters (error E0133)") } else { - format!("#[derive] can't be used on a non-Copy #[repr(packed)] struct \ - (error E0133)") + format!("#[derive] can't be used on a #[repr(packed)] struct that \ + does not derive Copy (error E0133)") }; tcx.lint_node(SAFE_PACKED_BORROWS, lint_node_id, diff --git a/src/test/ui/deriving-with-repr-packed.rs b/src/test/ui/deriving-with-repr-packed.rs index 0c52829799ea8..43375098cb5b4 100644 --- a/src/test/ui/deriving-with-repr-packed.rs +++ b/src/test/ui/deriving-with-repr-packed.rs @@ -33,7 +33,7 @@ pub struct Bar(u32, u32, u32); struct Y(usize); #[derive(PartialEq)] -//~^ ERROR #[derive] can't be used on a non-Copy #[repr(packed)] +//~^ ERROR #[derive] can't be used //~| hard error #[repr(packed)] struct X(Y); diff --git a/src/test/ui/deriving-with-repr-packed.stderr b/src/test/ui/deriving-with-repr-packed.stderr index 64aefbcd5df63..a7599c1e7db34 100644 --- a/src/test/ui/deriving-with-repr-packed.stderr +++ b/src/test/ui/deriving-with-repr-packed.stderr @@ -21,7 +21,7 @@ LL | #[derive(Copy, Clone, PartialEq, Eq)] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #46043 -error: #[derive] can't be used on a non-Copy #[repr(packed)] struct (error E0133) +error: #[derive] can't be used on a #[repr(packed)] struct that does not derive Copy (error E0133) --> $DIR/deriving-with-repr-packed.rs:26:10 | LL | #[derive(PartialEq, Eq)] @@ -30,7 +30,7 @@ LL | #[derive(PartialEq, Eq)] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #46043 -error: #[derive] can't be used on a non-Copy #[repr(packed)] struct (error E0133) +error: #[derive] can't be used on a #[repr(packed)] struct that does not derive Copy (error E0133) --> $DIR/deriving-with-repr-packed.rs:35:10 | LL | #[derive(PartialEq)] From 6ff67ee0d7b4f9f962809a82d9078f353e200818 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Sat, 2 Jun 2018 16:03:33 +0200 Subject: [PATCH 04/11] remove debug_assert in padding_needed_for --- src/libcore/alloc.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 064c7514112b5..cddd142045ada 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -204,9 +204,6 @@ impl Layout { /// satisfy this constraint is to ensure `align <= self.align()`. #[inline] pub fn padding_needed_for(&self, align: usize) -> usize { - // **FIXME**: This function is only called with proper power-of-two - // alignments. Maybe we should turn this into a real assert!. - debug_assert!(align.is_power_of_two()); let len = self.size(); // Rounded up value is: From 2d7cd70b1ac0dc1ce3a2602b51301dedae6a25a6 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Sat, 2 Jun 2018 16:11:57 +0200 Subject: [PATCH 05/11] add missing inline's and optimizations --- src/libcore/alloc.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index cddd142045ada..4a817ebc43b34 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -244,7 +244,12 @@ impl Layout { .ok_or(LayoutErr { private: () })?; let alloc_size = padded_size.checked_mul(n) .ok_or(LayoutErr { private: () })?; - Ok((Layout::from_size_align(alloc_size, self.align())?, padded_size)) + + unsafe { + // self.align is already known to be valid and alloc_size has been + // padded already. + Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size)) + } } /// Creates a layout describing the record for `self` followed by @@ -258,11 +263,10 @@ impl Layout { /// (assuming that the record itself starts at offset 0). /// /// On arithmetic overflow, returns `LayoutErr`. + #[inline] pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> { let new_align = cmp::max(self.align(), next.align()); - let realigned = Layout::from_size_align(self.size(), new_align)?; - - let pad = realigned.padding_needed_for(next.align()); + let pad = self.padding_needed_for(next.align()); let offset = self.size().checked_add(pad) .ok_or(LayoutErr { private: () })?; @@ -285,6 +289,7 @@ impl Layout { /// aligned. /// /// On arithmetic overflow, returns `LayoutErr`. + #[inline] pub fn repeat_packed(&self, n: usize) -> Result { let size = self.size().checked_mul(n).ok_or(LayoutErr { private: () })?; Layout::from_size_align(size, self.align()) @@ -305,6 +310,7 @@ impl Layout { /// `extend`.) /// /// On arithmetic overflow, returns `LayoutErr`. + #[inline] pub fn extend_packed(&self, next: Self) -> Result<(Self, usize), LayoutErr> { let new_size = self.size().checked_add(next.size()) .ok_or(LayoutErr { private: () })?; @@ -315,6 +321,7 @@ impl Layout { /// Creates a layout describing the record for a `[T; n]`. /// /// On arithmetic overflow, returns `LayoutErr`. + #[inline] pub fn array(n: usize) -> Result { Layout::new::() .repeat(n) From 0ff8d40fa1c6be4428a65f6539ffe98c83245eab Mon Sep 17 00:00:00 2001 From: kennytm Date: Sun, 3 Jun 2018 00:29:50 +0800 Subject: [PATCH 06/11] impl Default for &mut str --- src/liballoc/tests/str.rs | 1 + src/libcore/str/mod.rs | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index 03d295d16e6a0..75306ac82dfd5 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -1326,6 +1326,7 @@ fn test_str_default() { t::<&str>(); t::(); + t::<&mut str>(); } #[test] diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 3169893fcde14..5e1a9c25a2190 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -3875,6 +3875,12 @@ impl<'a> Default for &'a str { fn default() -> &'a str { "" } } +#[stable(feature = "default_mut_str", since = "1.28.0")] +impl<'a> Default for &'a mut str { + /// Creates an empty mutable str + fn default() -> &'a mut str { unsafe { from_utf8_unchecked_mut(&mut []) } } +} + /// An iterator over the non-whitespace substrings of a string, /// separated by any amount of whitespace. /// From 1bc6c4b10e7036be6fe61999fabf3462eeed39be Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Fri, 6 Apr 2018 15:32:54 -0400 Subject: [PATCH 07/11] Clarify the difference between get_mut and into_mut for OccupiedEntry The examples for both hash_map::OccupiedEntry::get_mut and hash_map::OccupiedEntry::into_mut were almost identical. This led to some confusion over the difference, namely why you would ever use get_mut when into_mut gives alonger lifetime. Reddit thread: https://www.reddit.com/r/rust/comments/8a5swr/why_does_hashmaps This commit adds two lines and a comment to the example, to show that the entry object can be re-used after calling get_mut. --- src/libstd/collections/hash/map.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 935ea4b62b5eb..e733b0b804810 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2261,10 +2261,14 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { /// /// assert_eq!(map["poneyland"], 12); /// if let Entry::Occupied(mut o) = map.entry("poneyland") { - /// *o.get_mut() += 10; + /// *o.get_mut() += 10; + /// assert_eq!(o.get(), 22); + /// + /// // We can use the same Entry multiple times. + /// *o.get_mut() += 2; /// } /// - /// assert_eq!(map["poneyland"], 22); + /// assert_eq!(map["poneyland"], 24); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self) -> &mut V { From ed1a8fff6282e1e9ed49e3638f365c358385fd99 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Fri, 6 Apr 2018 17:10:35 -0400 Subject: [PATCH 08/11] Fixed typo --- src/libstd/collections/hash/map.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index e733b0b804810..4a67c444ed658 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2262,7 +2262,7 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { /// assert_eq!(map["poneyland"], 12); /// if let Entry::Occupied(mut o) = map.entry("poneyland") { /// *o.get_mut() += 10; - /// assert_eq!(o.get(), 22); + /// assert_eq!(*o.get(), 22); /// /// // We can use the same Entry multiple times. /// *o.get_mut() += 2; From 9eb70c3cf5c36b71db409ec845dddb7b7da5d587 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Sat, 2 Jun 2018 16:23:26 -0400 Subject: [PATCH 09/11] use type name in E0599 enum variant suggestion Also, rename the variable from "type_str" to "item_kind" to avoid the ambiguity that caused this bug. --- src/librustc_typeck/check/method/suggest.rs | 12 ++++++------ src/test/ui/issue-23217.stderr | 2 +- src/test/ui/issue-28971.stderr | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 6031984350b95..86cd8d0fb2c52 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -195,7 +195,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let ty_string = self.ty_to_string(actual); let is_method = mode == Mode::MethodCall; let mut suggestion = None; - let type_str = if is_method { + let item_kind = if is_method { "method" } else if actual.is_enum() { if let TyAdt(ref adt_def, _) = actual.sty { @@ -235,7 +235,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span, E0689, "can't call {} `{}` on ambiguous numeric type `{}`", - type_str, + item_kind, item_name, ty_string ); @@ -284,12 +284,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span, E0599, "no {} named `{}` found for type `{}` in the current scope", - type_str, + item_kind, item_name, ty_string ); if let Some(suggestion) = suggestion { - err.note(&format!("did you mean `{}::{}`?", type_str, suggestion)); + err.note(&format!("did you mean `{}::{}`?", ty_string, suggestion)); } err } @@ -301,7 +301,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(full_sp) = tcx.hir.span_if_local(def.did) { let def_sp = tcx.sess.codemap().def_span(full_sp); err.span_label(def_sp, format!("{} `{}` not found {}", - type_str, + item_kind, item_name, if def.is_enum() && !is_method { "here" @@ -355,7 +355,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } } else { - err.span_label(span, format!("{} not found in `{}`", type_str, ty_string)); + err.span_label(span, format!("{} not found in `{}`", item_kind, ty_string)); } if self.is_fn_ty(&rcvr_ty, span) { diff --git a/src/test/ui/issue-23217.stderr b/src/test/ui/issue-23217.stderr index d542a10e9b605..d87f239bca690 100644 --- a/src/test/ui/issue-23217.stderr +++ b/src/test/ui/issue-23217.stderr @@ -6,7 +6,7 @@ LL | pub enum SomeEnum { LL | B = SomeEnum::A, | ^^^^^^^^^^^ variant not found in `SomeEnum` | - = note: did you mean `variant::B`? + = note: did you mean `SomeEnum::B`? error: aborting due to previous error diff --git a/src/test/ui/issue-28971.stderr b/src/test/ui/issue-28971.stderr index df114351ff571..c04e21f7c5857 100644 --- a/src/test/ui/issue-28971.stderr +++ b/src/test/ui/issue-28971.stderr @@ -7,7 +7,7 @@ LL | enum Foo { LL | Foo::Baz(..) => (), | ^^^^^^^^^^^^ variant not found in `Foo` | - = note: did you mean `variant::Bar`? + = note: did you mean `Foo::Bar`? error: aborting due to previous error From a86f556ee37c13047f966c35effab8b334b7de67 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 2 Jun 2018 16:04:53 -0400 Subject: [PATCH 10/11] Add a couple lines describing differences between into_mut/get_mut. --- src/libstd/collections/hash/map.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 4a67c444ed658..5cbd8891364dd 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2250,6 +2250,11 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { /// Gets a mutable reference to the value in the entry. /// + /// If you need a reference to the `OccupiedEntry` which may outlive the + /// destruction of the `Entry` value, see [`into_mut`]. + /// + /// [`into_mut`]: #method.into_mut + /// /// # Examples /// /// ``` @@ -2278,6 +2283,10 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { /// Converts the OccupiedEntry into a mutable reference to the value in the entry /// with a lifetime bound to the map itself. /// + /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`]. + /// + /// [`get_mut`]: #method.get_mut + /// /// # Examples /// /// ``` From dd88f88c02c901dd14e18a65c0b7132c36f530ee Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 2 Jun 2018 16:06:17 -0400 Subject: [PATCH 11/11] Copy changes from HashMap over to BTreeMap. --- src/liballoc/btree/map.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/liballoc/btree/map.rs b/src/liballoc/btree/map.rs index 28c42144b2af5..9b6f91c039fea 100644 --- a/src/liballoc/btree/map.rs +++ b/src/liballoc/btree/map.rs @@ -2369,6 +2369,11 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> { /// Gets a mutable reference to the value in the entry. /// + /// If you need a reference to the `OccupiedEntry` which may outlive the + /// destruction of the `Entry` value, see [`into_mut`]. + /// + /// [`into_mut`]: #method.into_mut + /// /// # Examples /// /// ``` @@ -2380,9 +2385,13 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> { /// /// assert_eq!(map["poneyland"], 12); /// if let Entry::Occupied(mut o) = map.entry("poneyland") { - /// *o.get_mut() += 10; + /// *o.get_mut() += 10; + /// assert_eq!(*o.get(), 22); + /// + /// // We can use the same Entry multiple times. + /// *o.get_mut() += 2; /// } - /// assert_eq!(map["poneyland"], 22); + /// assert_eq!(map["poneyland"], 24); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self) -> &mut V { @@ -2391,6 +2400,10 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> { /// Converts the entry into a mutable reference to its value. /// + /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`]. + /// + /// [`get_mut`]: #method.get_mut + /// /// # Examples /// /// ```