about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-07-03 23:39:36 +0000
committerbors <bors@rust-lang.org>2019-07-03 23:39:36 +0000
commitb43eb4235ac43c822d903ad26ed806f34cc1a14a (patch)
tree124c3531ddc1815ad1586b3c78373f9e9117ce3c /src/libcore
parent088b987307b91612ab164026e1dcdd0129fdb62b (diff)
parent6363a58e9af1b00669ebf1e343a67e3d1815f463 (diff)
downloadrust-b43eb4235ac43c822d903ad26ed806f34cc1a14a.tar.gz
rust-b43eb4235ac43c822d903ad26ed806f34cc1a14a.zip
Auto merge of #62355 - Centril:rollup-xnxtcgm, r=Centril
Rollup of 16 pull requests

Successful merges:

 - #62039 (Remove needless lifetimes (rustc))
 - #62173 (rename InterpretCx -> InterpCx)
 - #62240 (wfcheck: resolve the type-vars in `AdtField` types)
 - #62249 (Use mem::take instead of mem::replace with default)
 - #62252 (Update mem::replace example to not be identical to mem::take)
 - #62258 (syntax: Unsupport `foo! bar { ... }` macros in the parser)
 - #62268 (Clean up inherent_impls)
 - #62287 (Use link attributes on extern "C" blocks with llvm-libuwind)
 - #62295 (miri realloc: do not require giving old size+align)
 - #62297 (refactor check_for_substitution)
 - #62316 (When possible without changing semantics, implement Iterator::last in terms of DoubleEndedIterator::next_back for types in liballoc and libcore.)
 - #62317 (Migrate `compile-pass` annotations to `build-pass`)
 - #62337 (Fix bucket in CPU usage script)
 - #62344 (simplify Option::get_or_insert)
 - #62346 (enable a few more tests in Miri and update the comment for others)
 - #62351 (remove bogus example from drop_in_place)

Failed merges:

r? @ghost
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/ascii.rs1
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/libcore/mem/mod.rs28
-rw-r--r--src/libcore/option.rs12
-rw-r--r--src/libcore/ptr/mod.rs32
-rw-r--r--src/libcore/str/mod.rs15
-rw-r--r--src/libcore/tests/fmt/mod.rs2
-rw-r--r--src/libcore/tests/ptr.rs5
-rw-r--r--src/libcore/tests/slice.rs4
9 files changed, 48 insertions, 52 deletions
diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs
index c0ab364380f..e6a6fdde540 100644
--- a/src/libcore/ascii.rs
+++ b/src/libcore/ascii.rs
@@ -117,6 +117,7 @@ impl Iterator for EscapeDefault {
     type Item = u8;
     fn next(&mut self) -> Option<u8> { self.range.next().map(|i| self.data[i]) }
     fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() }
+    fn last(mut self) -> Option<u8> { self.next_back() }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl DoubleEndedIterator for EscapeDefault {
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 04c50329de3..d2d08a075b9 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -126,6 +126,7 @@
 #![feature(adx_target_feature)]
 #![feature(maybe_uninit_slice, maybe_uninit_array)]
 #![feature(external_doc)]
+#![feature(mem_take)]
 
 #[prelude_import]
 #[allow(unused)]
diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs
index e110e93a954..b31522db474 100644
--- a/src/libcore/mem/mod.rs
+++ b/src/libcore/mem/mod.rs
@@ -552,6 +552,12 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
 ///         mem::take(&mut self.buf)
 ///     }
 /// }
+///
+/// let mut buffer = Buffer { buf: vec![0, 1] };
+/// assert_eq!(buffer.buf.len(), 2);
+///
+/// assert_eq!(buffer.get_and_reset(), vec![0, 1]);
+/// assert_eq!(buffer.buf.len(), 0);
 /// ```
 ///
 /// [`Clone`]: ../../std/clone/trait.Clone.html
@@ -586,17 +592,17 @@ pub fn take<T: Default>(dest: &mut T) -> T {
 /// struct Buffer<T> { buf: Vec<T> }
 ///
 /// impl<T> Buffer<T> {
-///     fn get_and_reset(&mut self) -> Vec<T> {
+///     fn replace_index(&mut self, i: usize, v: T) -> T {
 ///         // error: cannot move out of dereference of `&mut`-pointer
-///         let buf = self.buf;
-///         self.buf = Vec::new();
-///         buf
+///         let t = self.buf[i];
+///         self.buf[i] = v;
+///         t
 ///     }
 /// }
 /// ```
 ///
-/// Note that `T` does not necessarily implement [`Clone`], so it can't even clone and reset
-/// `self.buf`. But `replace` can be used to disassociate the original value of `self.buf` from
+/// Note that `T` does not necessarily implement [`Clone`], so we can't even clone `self.buf[i]` to
+/// avoid the move. But `replace` can be used to disassociate the original value at that index from
 /// `self`, allowing it to be returned:
 ///
 /// ```
@@ -605,10 +611,16 @@ pub fn take<T: Default>(dest: &mut T) -> T {
 ///
 /// # struct Buffer<T> { buf: Vec<T> }
 /// impl<T> Buffer<T> {
-///     fn get_and_reset(&mut self) -> Vec<T> {
-///         mem::replace(&mut self.buf, Vec::new())
+///     fn replace_index(&mut self, i: usize, v: T) -> T {
+///         mem::replace(&mut self.buf[i], v)
 ///     }
 /// }
+///
+/// let mut buffer = Buffer { buf: vec![0, 1] };
+/// assert_eq!(buffer.buf[0], 0);
+///
+/// assert_eq!(buffer.replace_index(0, 2), 0);
+/// assert_eq!(buffer.buf[0], 2);
 /// ```
 ///
 /// [`Clone`]: ../../std/clone/trait.Clone.html
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index eec4b149ddc..b27fd4098e1 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -777,15 +777,7 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "option_entry", since = "1.20.0")]
     pub fn get_or_insert(&mut self, v: T) -> &mut T {
-        match *self {
-            None => *self = Some(v),
-            _ => (),
-        }
-
-        match *self {
-            Some(ref mut v) => v,
-            None => unsafe { hint::unreachable_unchecked() },
-        }
+        self.get_or_insert_with(|| v)
     }
 
     /// Inserts a value computed from `f` into the option if it is [`None`], then
@@ -845,7 +837,7 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn take(&mut self) -> Option<T> {
-        mem::replace(self, None)
+        mem::take(self)
     }
 
     /// Replaces the actual value in the option by the value given in parameter,
diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs
index fccb00d768c..da781d7e9fe 100644
--- a/src/libcore/ptr/mod.rs
+++ b/src/libcore/ptr/mod.rs
@@ -100,7 +100,11 @@ pub use unique::Unique;
 ///   as the compiler doesn't need to prove that it's sound to elide the
 ///   copy.
 ///
+/// Unaligned values cannot be dropped in place, they must be copied to an aligned
+/// location first using [`ptr::read_unaligned`].
+///
 /// [`ptr::read`]: ../ptr/fn.read.html
+/// [`ptr::read_unaligned`]: ../ptr/fn.read_unaligned.html
 ///
 /// # Safety
 ///
@@ -108,8 +112,7 @@ pub use unique::Unique;
 ///
 /// * `to_drop` must be [valid] for reads.
 ///
-/// * `to_drop` must be properly aligned. See the example below for how to drop
-///   an unaligned pointer.
+/// * `to_drop` must be properly aligned.
 ///
 /// Additionally, if `T` is not [`Copy`], using the pointed-to value after
 /// calling `drop_in_place` can cause undefined behavior. Note that `*to_drop =
@@ -153,31 +156,6 @@ pub use unique::Unique;
 /// assert!(weak.upgrade().is_none());
 /// ```
 ///
-/// Unaligned values cannot be dropped in place, they must be copied to an aligned
-/// location first:
-/// ```
-/// use std::ptr;
-/// use std::mem::{self, MaybeUninit};
-///
-/// unsafe fn drop_after_copy<T>(to_drop: *mut T) {
-///     let mut copy: MaybeUninit<T> = MaybeUninit::uninit();
-///     ptr::copy(to_drop, copy.as_mut_ptr(), 1);
-///     drop(copy.assume_init());
-/// }
-///
-/// #[repr(packed, C)]
-/// struct Packed {
-///     _padding: u8,
-///     unaligned: Vec<i32>,
-/// }
-///
-/// let mut p = Packed { _padding: 0, unaligned: vec![42] };
-/// unsafe {
-///     drop_after_copy(&mut p.unaligned as *mut _);
-///     mem::forget(p);
-/// }
-/// ```
-///
 /// Notice that the compiler performs this copy automatically when dropping packed structs,
 /// i.e., you do not usually have to worry about such issues unless you call `drop_in_place`
 /// manually.
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index f7b4e4ea782..b027e6bc051 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1333,6 +1333,11 @@ impl<'a> Iterator for Lines<'a> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.0.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a str> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -4241,6 +4246,11 @@ impl<'a> Iterator for SplitWhitespace<'a> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a str> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "split_whitespace", since = "1.1.0")]
@@ -4267,6 +4277,11 @@ impl<'a> Iterator for SplitAsciiWhitespace<'a> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a str> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
diff --git a/src/libcore/tests/fmt/mod.rs b/src/libcore/tests/fmt/mod.rs
index df1deeaeb97..d86e21cf40b 100644
--- a/src/libcore/tests/fmt/mod.rs
+++ b/src/libcore/tests/fmt/mod.rs
@@ -3,7 +3,6 @@ mod float;
 mod num;
 
 #[test]
-#[cfg(not(miri))] // Miri cannot print pointers
 fn test_format_flags() {
     // No residual flags left by pointer formatting
     let p = "".as_ptr();
@@ -13,7 +12,6 @@ fn test_format_flags() {
 }
 
 #[test]
-#[cfg(not(miri))] // Miri cannot print pointers
 fn test_pointer_formats_data_pointer() {
     let b: &[u8] = b"";
     let s: &str = "";
diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs
index 03fe1fe5a7c..569b3197d09 100644
--- a/src/libcore/tests/ptr.rs
+++ b/src/libcore/tests/ptr.rs
@@ -253,7 +253,6 @@ fn test_unsized_nonnull() {
 
 #[test]
 #[allow(warnings)]
-#[cfg(not(miri))] // Miri cannot hash pointers
 // Have a symbol for the test below. It doesn’t need to be an actual variadic function, match the
 // ABI, or even point to an actual executable code, because the function itself is never invoked.
 #[no_mangle]
@@ -293,7 +292,7 @@ fn write_unaligned_drop() {
 }
 
 #[test]
-#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation
+#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
 fn align_offset_zst() {
     // For pointers of stride = 0, the pointer is already aligned or it cannot be aligned at
     // all, because no amount of elements will align the pointer.
@@ -308,7 +307,7 @@ fn align_offset_zst() {
 }
 
 #[test]
-#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation
+#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
 fn align_offset_stride1() {
     // For pointers of stride = 1, the pointer can always be aligned. The offset is equal to
     // number of bytes.
diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs
index 13b02c71842..42ec9d451f7 100644
--- a/src/libcore/tests/slice.rs
+++ b/src/libcore/tests/slice.rs
@@ -1415,7 +1415,7 @@ pub mod memchr {
 }
 
 #[test]
-#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation
+#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
 fn test_align_to_simple() {
     let bytes = [1u8, 2, 3, 4, 5, 6, 7];
     let (prefix, aligned, suffix) = unsafe { bytes.align_to::<u16>() };
@@ -1439,7 +1439,7 @@ fn test_align_to_zst() {
 }
 
 #[test]
-#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation
+#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
 fn test_align_to_non_trivial() {
     #[repr(align(8))] struct U64(u64, u64);
     #[repr(align(8))] struct U64U64U32(u64, u64, u32);