diff --git a/src/liballoc/btree/map.rs b/src/liballoc/btree/map.rs index 28c42144b2af..9b6f91c039fe 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 /// /// ``` diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index 03d295d16e6a..75306ac82dfd 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/alloc.rs b/src/libcore/alloc.rs index 6172a98bca61..229758803c87 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,7 +201,7 @@ 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 { let len = self.size(); @@ -227,7 +225,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 +237,19 @@ 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)) + + 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,16 +262,15 @@ 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`. + #[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 new_align = cmp::max(self.align(), next.align()); + let pad = self.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 +288,11 @@ impl Layout { /// guaranteed that all elements in the array will be properly /// aligned. /// - /// On arithmetic overflow, returns `None`. + /// 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) + Layout::from_size_align(size, self.align()) } /// Creates a layout describing the record for `self` followed by @@ -305,17 +309,19 @@ impl Layout { /// signature out of convenience in matching the signature of /// `extend`.) /// - /// On arithmetic overflow, returns `None`. + /// 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: () })?; - 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`. + #[inline] pub fn array(n: usize) -> Result { Layout::new::() .repeat(n) @@ -842,7 +848,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] @@ -897,7 +903,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] diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 3169893fcde1..5e1a9c25a219 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. /// diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index fedd0774df44..4c282f037a5c 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/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 6031984350b9..86cd8d0fb2c5 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/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 83abf35c8548..2876f0d71adf 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 765ef0cd415b..f96dcd9ec1c8 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 5971dc43deda..54cf50cfffd1 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; } diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 935ea4b62b5e..5cbd8891364d 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 /// /// ``` @@ -2261,10 +2266,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 { @@ -2274,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 /// /// ``` diff --git a/src/test/ui/deriving-with-repr-packed.rs b/src/test/ui/deriving-with-repr-packed.rs index 0c52829799ea..43375098cb5b 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 64aefbcd5df6..a7599c1e7db3 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)] diff --git a/src/test/ui/issue-23217.stderr b/src/test/ui/issue-23217.stderr index d542a10e9b60..d87f239bca69 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 df114351ff57..c04e21f7c585 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