about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-04-24 05:43:32 +0000
committerbors <bors@rust-lang.org>2018-04-24 05:43:32 +0000
commit52ed3d8761dc42e51429eb3bbf56a94d14fdd5c6 (patch)
treefe2dca988e2194b65e4103ff6012bdce4ab3433e /src/libcore
parentf305b025cf907d0bbdd2135ec59d89cd32e5cbe9 (diff)
parent893774e119b3197e12c1891b39d0e1e2830a362d (diff)
downloadrust-52ed3d8761dc42e51429eb3bbf56a94d14fdd5c6.tar.gz
rust-52ed3d8761dc42e51429eb3bbf56a94d14fdd5c6.zip
Auto merge of #50191 - kennytm:rollup, r=kennytm
Rollup of 11 pull requests

Successful merges:

 - #49461 (std: Child::kill() returns error if process has already exited)
 - #49727 (Add Cell::update)
 - #49812 (Fix revision support for UI tests.)
 - #49829 (Add doc links to `std::os` extension traits)
 - #49906 (Stabilize `std::hint::unreachable_unchecked`.)
 - #49970 (Deprecate Read::chars and char::decode_utf8)
 - #49985 (don't see issue #0)
 - #50118 (fix search bar bug)
 - #50139 (encourage descriptive issue titles)
 - #50174 (Use FxHashMap in syntax_pos::symbol::Interner::intern.)
 - #50185 (core: Fix overflow in `int::mod_euc` when `self < 0 && rhs == MIN`)

Failed merges:
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/cell.rs27
-rw-r--r--src/libcore/char/decode.rs11
-rw-r--r--src/libcore/char/mod.rs3
-rw-r--r--src/libcore/hint.rs61
-rw-r--r--src/libcore/intrinsics.rs3
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/libcore/macros.rs8
-rw-r--r--src/libcore/mem.rs12
-rw-r--r--src/libcore/num/mod.rs6
-rw-r--r--src/libcore/tests/cell.rs11
-rw-r--r--src/libcore/tests/char.rs1
-rw-r--r--src/libcore/tests/lib.rs2
-rw-r--r--src/libcore/tests/num/int_macros.rs5
13 files changed, 134 insertions, 17 deletions
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index c8ee166fee3..1ff187ed3f1 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -256,6 +256,33 @@ impl<T:Copy> Cell<T> {
     pub fn get(&self) -> T {
         unsafe{ *self.value.get() }
     }
+
+    /// Updates the contained value using a function and returns the new value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(cell_update)]
+    ///
+    /// use std::cell::Cell;
+    ///
+    /// let c = Cell::new(5);
+    /// let new = c.update(|x| x + 1);
+    ///
+    /// assert_eq!(new, 6);
+    /// assert_eq!(c.get(), 6);
+    /// ```
+    #[inline]
+    #[unstable(feature = "cell_update", issue = "50186")]
+    pub fn update<F>(&self, f: F) -> T
+    where
+        F: FnOnce(T) -> T,
+    {
+        let old = self.get();
+        let new = f(old);
+        self.set(new);
+        new
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/char/decode.rs b/src/libcore/char/decode.rs
index 48b531104f8..45a73191db2 100644
--- a/src/libcore/char/decode.rs
+++ b/src/libcore/char/decode.rs
@@ -17,11 +17,17 @@ use super::from_u32_unchecked;
 /// An iterator over an iterator of bytes of the characters the bytes represent
 /// as UTF-8
 #[unstable(feature = "decode_utf8", issue = "33906")]
+#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead:
+    https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")]
 #[derive(Clone, Debug)]
+#[allow(deprecated)]
 pub struct DecodeUtf8<I: Iterator<Item = u8>>(::iter::Peekable<I>);
 
 /// Decodes an `Iterator` of bytes as UTF-8.
 #[unstable(feature = "decode_utf8", issue = "33906")]
+#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead:
+    https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")]
+#[allow(deprecated)]
 #[inline]
 pub fn decode_utf8<I: IntoIterator<Item = u8>>(i: I) -> DecodeUtf8<I::IntoIter> {
     DecodeUtf8(i.into_iter().peekable())
@@ -29,10 +35,14 @@ pub fn decode_utf8<I: IntoIterator<Item = u8>>(i: I) -> DecodeUtf8<I::IntoIter>
 
 /// `<DecodeUtf8 as Iterator>::next` returns this for an invalid input sequence.
 #[unstable(feature = "decode_utf8", issue = "33906")]
+#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead:
+    https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")]
 #[derive(PartialEq, Eq, Debug)]
+#[allow(deprecated)]
 pub struct InvalidSequence(());
 
 #[unstable(feature = "decode_utf8", issue = "33906")]
+#[allow(deprecated)]
 impl<I: Iterator<Item = u8>> Iterator for DecodeUtf8<I> {
     type Item = Result<char, InvalidSequence>;
     #[inline]
@@ -127,6 +137,7 @@ impl<I: Iterator<Item = u8>> Iterator for DecodeUtf8<I> {
 }
 
 #[unstable(feature = "decode_utf8", issue = "33906")]
+#[allow(deprecated)]
 impl<I: FusedIterator<Item = u8>> FusedIterator for DecodeUtf8<I> {}
 
 /// An iterator that decodes UTF-16 encoded code points from an iterator of `u16`s.
diff --git a/src/libcore/char/mod.rs b/src/libcore/char/mod.rs
index 210eceebc51..4f6c302247d 100644
--- a/src/libcore/char/mod.rs
+++ b/src/libcore/char/mod.rs
@@ -51,6 +51,9 @@ pub use unicode::tables::UNICODE_VERSION;
 #[unstable(feature = "unicode_version", issue = "49726")]
 pub use unicode::version::UnicodeVersion;
 #[unstable(feature = "decode_utf8", issue = "33906")]
+#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead:
+    https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")]
+#[allow(deprecated)]
 pub use self::decode::{decode_utf8, DecodeUtf8, InvalidSequence};
 
 use fmt::{self, Write};
diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
new file mode 100644
index 00000000000..f4e96e67b2c
--- /dev/null
+++ b/src/libcore/hint.rs
@@ -0,0 +1,61 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![stable(feature = "core_hint", since = "1.27.0")]
+
+//! Hints to compiler that affects how code should be emitted or optimized.
+
+use intrinsics;
+
+/// Informs the compiler that this point in the code is not reachable, enabling
+/// further optimizations.
+///
+/// # Safety
+///
+/// Reaching this function is completely *undefined behavior* (UB). In
+/// particular, the compiler assumes that all UB must never happen, and
+/// therefore will eliminate all branches that reach to a call to
+/// `unreachable_unchecked()`.
+///
+/// Like all instances of UB, if this assumption turns out to be wrong, i.e. the
+/// `unreachable_unchecked()` call is actually reachable among all possible
+/// control flow, the compiler will apply the wrong optimization strategy, and
+/// may sometimes even corrupt seemingly unrelated code, causing
+/// difficult-to-debug problems.
+///
+/// Use this function only when you can prove that the code will never call it.
+///
+/// The [`unreachable!()`] macro is the safe counterpart of this function, which
+/// will panic instead when executed.
+///
+/// [`unreachable!()`]: ../macro.unreachable.html
+///
+/// # Example
+///
+/// ```
+/// fn div_1(a: u32, b: u32) -> u32 {
+///     use std::hint::unreachable_unchecked;
+///
+///     // `b.saturating_add(1)` is always positive (not zero),
+///     // hence `checked_div` will never return None.
+///     // Therefore, the else branch is unreachable.
+///     a.checked_div(b.saturating_add(1))
+///         .unwrap_or_else(|| unsafe { unreachable_unchecked() })
+/// }
+///
+/// assert_eq!(div_1(7, 0), 7);
+/// assert_eq!(div_1(9, 1), 4);
+/// assert_eq!(div_1(11, std::u32::MAX), 0);
+/// ```
+#[inline]
+#[stable(feature = "unreachable", since = "1.27.0")]
+pub unsafe fn unreachable_unchecked() -> ! {
+    intrinsics::unreachable()
+}
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 83274682250..fb0d2d9c882 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -638,6 +638,9 @@ extern "rust-intrinsic" {
     /// NB: This is very different from the `unreachable!()` macro: Unlike the
     /// macro, which panics when it is executed, it is *undefined behavior* to
     /// reach code marked with this function.
+    ///
+    /// The stabilized version of this intrinsic is
+    /// [`std::hint::unreachable_unchecked`](../../std/hint/fn.unreachable_unchecked.html).
     pub fn unreachable() -> !;
 
     /// Informs the optimizer that a condition is always true.
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 7da5d9f76b5..0e21a3327fd 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -163,6 +163,7 @@ pub mod intrinsics;
 pub mod mem;
 pub mod nonzero;
 pub mod ptr;
+pub mod hint;
 
 /* Core language traits */
 
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index 346d404fa8c..f9371ed0575 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -421,13 +421,13 @@ macro_rules! writeln {
 /// * Iterators that dynamically terminate.
 ///
 /// If the determination that the code is unreachable proves incorrect, the
-/// program immediately terminates with a [`panic!`].  The function [`unreachable`],
-/// which belongs to the [`std::intrinsics`] module, informs the compilier to
+/// program immediately terminates with a [`panic!`].  The function [`unreachable_unchecked`],
+/// which belongs to the [`std::hint`] module, informs the compilier to
 /// optimize the code out of the release version entirely.
 ///
 /// [`panic!`]:  ../std/macro.panic.html
-/// [`unreachable`]: ../std/intrinsics/fn.unreachable.html
-/// [`std::intrinsics`]: ../std/intrinsics/index.html
+/// [`unreachable_unchecked`]: ../std/hint/fn.unreachable_unchecked.html
+/// [`std::hint`]: ../std/hint/index.html
 ///
 /// # Panics
 ///
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index e3f08926610..10efab82ddf 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -1094,18 +1094,6 @@ impl<T: ::hash::Hash> ::hash::Hash for ManuallyDrop<T> {
     }
 }
 
-/// Tells LLVM that this point in the code is not reachable, enabling further
-/// optimizations.
-///
-/// NB: This is very different from the `unreachable!()` macro: Unlike the
-/// macro, which panics when it is executed, it is *undefined behavior* to
-/// reach code marked with this function.
-#[inline]
-#[unstable(feature = "unreachable", issue = "43751")]
-pub unsafe fn unreachable() -> ! {
-    intrinsics::unreachable()
-}
-
 /// A pinned reference.
 ///
 /// A pinned reference is a lot like a mutable reference, except that it is not
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index aa4d4bc638b..a062fbda5ba 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -1765,7 +1765,11 @@ assert_eq!((-a).mod_euc(-b), 1);
             pub fn mod_euc(self, rhs: Self) -> Self {
                 let r = self % rhs;
                 if r < 0 {
-                    r + rhs.abs()
+                    if rhs < 0 {
+                        r - rhs
+                    } else {
+                        r + rhs
+                    }
                 } else {
                     r
                 }
diff --git a/src/libcore/tests/cell.rs b/src/libcore/tests/cell.rs
index cc0ef6a6f17..962fb2f0e02 100644
--- a/src/libcore/tests/cell.rs
+++ b/src/libcore/tests/cell.rs
@@ -27,6 +27,17 @@ fn smoketest_cell() {
 }
 
 #[test]
+fn cell_update() {
+    let x = Cell::new(10);
+
+    assert_eq!(x.update(|x| x + 5), 15);
+    assert_eq!(x.get(), 15);
+
+    assert_eq!(x.update(|x| x / 3), 5);
+    assert_eq!(x.get(), 5);
+}
+
+#[test]
 fn cell_has_sensible_show() {
     let x = Cell::new("foo bar");
     assert!(format!("{:?}", x).contains(x.get()));
diff --git a/src/libcore/tests/char.rs b/src/libcore/tests/char.rs
index 4e10ceac878..ab90763abf8 100644
--- a/src/libcore/tests/char.rs
+++ b/src/libcore/tests/char.rs
@@ -364,6 +364,7 @@ fn eu_iterator_specializations() {
 }
 
 #[test]
+#[allow(deprecated)]
 fn test_decode_utf8() {
     macro_rules! assert_decode_utf8 {
         ($input_bytes: expr, $expected_str: expr) => {
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 7d3852d2f2a..e4d27717938 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -10,11 +10,13 @@
 
 #![feature(ascii_ctype)]
 #![feature(box_syntax)]
+#![feature(cell_update)]
 #![feature(core_float)]
 #![feature(core_private_bignum)]
 #![feature(core_private_diy_float)]
 #![feature(dec2flt)]
 #![feature(decode_utf8)]
+#![feature(euclidean_division)]
 #![feature(exact_size_is_empty)]
 #![feature(fixed_size_array)]
 #![feature(float_internals)]
diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs
index 8d791283ab8..71d2e794538 100644
--- a/src/libcore/tests/num/int_macros.rs
+++ b/src/libcore/tests/num/int_macros.rs
@@ -31,6 +31,11 @@ mod tests {
     }
 
     #[test]
+    fn test_mod_euc() {
+        assert!((-1 as $T).mod_euc(MIN) == MAX);
+    }
+
+    #[test]
     pub fn test_abs() {
         assert!((1 as $T).abs() == 1 as $T);
         assert!((0 as $T).abs() == 0 as $T);