diff options
| author | bors <bors@rust-lang.org> | 2018-04-24 05:43:32 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-04-24 05:43:32 +0000 |
| commit | 52ed3d8761dc42e51429eb3bbf56a94d14fdd5c6 (patch) | |
| tree | fe2dca988e2194b65e4103ff6012bdce4ab3433e /src/libcore | |
| parent | f305b025cf907d0bbdd2135ec59d89cd32e5cbe9 (diff) | |
| parent | 893774e119b3197e12c1891b39d0e1e2830a362d (diff) | |
| download | rust-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.rs | 27 | ||||
| -rw-r--r-- | src/libcore/char/decode.rs | 11 | ||||
| -rw-r--r-- | src/libcore/char/mod.rs | 3 | ||||
| -rw-r--r-- | src/libcore/hint.rs | 61 | ||||
| -rw-r--r-- | src/libcore/intrinsics.rs | 3 | ||||
| -rw-r--r-- | src/libcore/lib.rs | 1 | ||||
| -rw-r--r-- | src/libcore/macros.rs | 8 | ||||
| -rw-r--r-- | src/libcore/mem.rs | 12 | ||||
| -rw-r--r-- | src/libcore/num/mod.rs | 6 | ||||
| -rw-r--r-- | src/libcore/tests/cell.rs | 11 | ||||
| -rw-r--r-- | src/libcore/tests/char.rs | 1 | ||||
| -rw-r--r-- | src/libcore/tests/lib.rs | 2 | ||||
| -rw-r--r-- | src/libcore/tests/num/int_macros.rs | 5 |
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); |
