Skip to content

Commit

Permalink
Auto merge of #48203 - kennytm:rollup, r=kennytm
Browse files Browse the repository at this point in the history
Rollup of 22 pull requests

- Successful merges: #47784, #47806, #47846, #48005, #48033, #48065, #48087, #48114, #48126, #48130, #48133, #48151, #48154, #48156, #48162, #48163, #48165, #48167, #48181, #48186, #48195, #48035
- Failed merges:
  • Loading branch information
bors committed Feb 14, 2018
2 parents 3ec5a99 + ce89c3d commit d3fb063
Show file tree
Hide file tree
Showing 49 changed files with 798 additions and 208 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ matrix:
NO_LLVM_ASSERTIONS=1
NO_DEBUG_ASSERTIONS=1
os: osx
osx_image: xcode8.3
osx_image: xcode9.2
if: branch = auto
- env: >
Expand All @@ -70,7 +70,7 @@ matrix:
NO_LLVM_ASSERTIONS=1
NO_DEBUG_ASSERTIONS=1
os: osx
osx_image: xcode8.3
osx_image: xcode9.2
if: branch = auto
# OSX builders producing releases. These do not run the full test suite and
Expand Down
2 changes: 2 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ Compatibility Notes
- [`column!()` macro is one-based instead of zero-based][46977]
- [`fmt::Arguments` can no longer be shared across threads][45198]
- [Access to `#[repr(packed)]` struct fields is now unsafe][44884]
- [Cargo sets a different working directory for the compiler][cargo/4788]

[44884]: https://github.com/rust-lang/rust/pull/44884
[45198]: https://github.com/rust-lang/rust/pull/45198
Expand Down Expand Up @@ -106,6 +107,7 @@ Compatibility Notes
[47080]: https://github.com/rust-lang/rust/pull/47080
[47084]: https://github.com/rust-lang/rust/pull/47084
[cargo/4743]: https://github.com/rust-lang/cargo/pull/4743
[cargo/4788]: https://github.com/rust-lang/cargo/pull/4788
[cargo/4817]: https://github.com/rust-lang/cargo/pull/4817
[`RefCell::replace`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.replace
[`RefCell::swap`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.swap
Expand Down
8 changes: 8 additions & 0 deletions src/bootstrap/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,14 @@ impl Step for Llvm {
.define("LLVM_TARGET_ARCH", target.split('-').next().unwrap())
.define("LLVM_DEFAULT_TARGET_TRIPLE", target);

// By default, LLVM will automatically find OCaml and, if it finds it,
// install the LLVM bindings in LLVM_OCAML_INSTALL_PATH, which defaults
// to /usr/bin/ocaml.
// This causes problem for non-root builds of Rust. Side-step the issue
// by setting LLVM_OCAML_INSTALL_PATH to a relative path, so it installs
// in the prefix.
cfg.define("LLVM_OCAML_INSTALL_PATH",
env::var_os("LLVM_OCAML_INSTALL_PATH").unwrap_or_else(|| "usr/lib/ocaml".into()));

// This setting makes the LLVM tools link to the dynamic LLVM library,
// which saves both memory during parallel links and overall disk space
Expand Down
17 changes: 1 addition & 16 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -805,22 +805,7 @@ impl<T> Vec<T> {
pub fn retain<F>(&mut self, mut f: F)
where F: FnMut(&T) -> bool
{
let len = self.len();
let mut del = 0;
{
let v = &mut **self;

for i in 0..len {
if !f(&v[i]) {
del += 1;
} else if del > 0 {
v.swap(i - del, i);
}
}
}
if del > 0 {
self.truncate(len - del);
}
self.drain_filter(|x| !f(x));
}

/// Removes all but the first of consecutive elements in the vector that resolve to the same
Expand Down
2 changes: 1 addition & 1 deletion src/libcompiler_builtins
2 changes: 2 additions & 0 deletions src/libcore/iter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,8 @@ pub use self::range::Step;

#[stable(feature = "rust1", since = "1.0.0")]
pub use self::sources::{Repeat, repeat};
#[unstable(feature = "iterator_repeat_with", issue = "48169")]
pub use self::sources::{RepeatWith, repeat_with};
#[stable(feature = "iter_empty", since = "1.2.0")]
pub use self::sources::{Empty, empty};
#[stable(feature = "iter_once", since = "1.2.0")]
Expand Down
115 changes: 115 additions & 0 deletions src/libcore/iter/sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ unsafe impl<A: Clone> TrustedLen for Repeat<A> {}
///
/// [`take`]: trait.Iterator.html#method.take
///
/// If the element type of the iterator you need does not implement `Clone`,
/// or if you do not want to keep the repeated element in memory, you can
/// instead use the [`repeat_with`] function.
///
/// [`repeat_with`]: fn.repeat_with.html
///
/// # Examples
///
/// Basic usage:
Expand Down Expand Up @@ -99,6 +105,115 @@ pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
Repeat{element: elt}
}

/// An iterator that repeats elements of type `A` endlessly by
/// applying the provided closure `F: FnMut() -> A`.
///
/// This `struct` is created by the [`repeat_with`] function.
/// See its documentation for more.
///
/// [`repeat_with`]: fn.repeat_with.html
#[derive(Copy, Clone, Debug)]
#[unstable(feature = "iterator_repeat_with", issue = "48169")]
pub struct RepeatWith<F> {
repeater: F
}

#[unstable(feature = "iterator_repeat_with", issue = "48169")]
impl<A, F: FnMut() -> A> Iterator for RepeatWith<F> {
type Item = A;

#[inline]
fn next(&mut self) -> Option<A> { Some((self.repeater)()) }

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) { (usize::MAX, None) }
}

#[unstable(feature = "iterator_repeat_with", issue = "48169")]
impl<A, F: FnMut() -> A> DoubleEndedIterator for RepeatWith<F> {
#[inline]
fn next_back(&mut self) -> Option<A> { self.next() }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A, F: FnMut() -> A> FusedIterator for RepeatWith<F> {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A, F: FnMut() -> A> TrustedLen for RepeatWith<F> {}

/// Creates a new iterator that repeats elements of type `A` endlessly by
/// applying the provided closure, the repeater, `F: FnMut() -> A`.
///
/// The `repeat_with()` function calls the repeater over and over and over and
/// over and over and 🔁.
///
/// Infinite iterators like `repeat_with()` are often used with adapters like
/// [`take`], in order to make them finite.
///
/// [`take`]: trait.Iterator.html#method.take
///
/// If the element type of the iterator you need implements `Clone`, and
/// it is OK to keep the source element in memory, you should instead use
/// the [`repeat`] function.
///
/// [`repeat`]: fn.repeat.html
///
/// An iterator produced by `repeat_with()` is a `DoubleEndedIterator`.
/// It is important to not that reversing `repeat_with(f)` will produce
/// the exact same sequence as the non-reversed iterator. In other words,
/// `repeat_with(f).rev().collect::<Vec<_>>()` is equivalent to
/// `repeat_with(f).collect::<Vec<_>>()`.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(iterator_repeat_with)]
///
/// use std::iter;
///
/// // let's assume we have some value of a type that is not `Clone`
/// // or which don't want to have in memory just yet because it is expensive:
/// #[derive(PartialEq, Debug)]
/// struct Expensive;
///
/// // a particular value forever:
/// let mut things = iter::repeat_with(|| Expensive);
///
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// ```
///
/// Using mutation and going finite:
///
/// ```rust
/// #![feature(iterator_repeat_with)]
///
/// use std::iter;
///
/// // From the zeroth to the third power of two:
/// let mut curr = 1;
/// let mut pow2 = iter::repeat_with(|| { let tmp = curr; curr *= 2; tmp })
/// .take(4);
///
/// assert_eq!(Some(1), pow2.next());
/// assert_eq!(Some(2), pow2.next());
/// assert_eq!(Some(4), pow2.next());
/// assert_eq!(Some(8), pow2.next());
///
/// // ... and now we're done
/// assert_eq!(None, pow2.next());
/// ```
#[inline]
#[unstable(feature = "iterator_repeat_with", issue = "48169")]
pub fn repeat_with<A, F: FnMut() -> A>(repeater: F) -> RepeatWith<F> {
RepeatWith { repeater }
}

/// An iterator that yields nothing.
///
/// This `struct` is created by the [`empty`] function. See its documentation for more.
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/iter/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ pub trait ExactSizeIterator: Iterator {
/// ```
/// #![feature(exact_size_is_empty)]
///
/// let mut one_element = 0..1;
/// let mut one_element = std::iter::once(0);
/// assert!(!one_element.is_empty());
///
/// assert_eq!(one_element.next(), Some(0));
Expand Down
1 change: 1 addition & 0 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
#![feature(unwind_attributes)]
#![feature(doc_spotlight)]
#![feature(rustc_const_unstable)]
#![feature(iterator_repeat_with)]

#[prelude_import]
#[allow(unused)]
Expand Down
6 changes: 3 additions & 3 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2881,7 +2881,7 @@ pub enum FpCategory {
issue = "32110")]
pub trait Float: Sized {
/// Type used by `to_bits` and `from_bits`.
#[stable(feature = "core_float_bits", since = "1.24.0")]
#[stable(feature = "core_float_bits", since = "1.25.0")]
type Bits;

/// Returns `true` if this value is NaN and false otherwise.
Expand Down Expand Up @@ -2947,10 +2947,10 @@ pub trait Float: Sized {
fn min(self, other: Self) -> Self;

/// Raw transmutation to integer.
#[stable(feature = "core_float_bits", since="1.24.0")]
#[stable(feature = "core_float_bits", since="1.25.0")]
fn to_bits(self) -> Self::Bits;
/// Raw transmutation from integer.
#[stable(feature = "core_float_bits", since="1.24.0")]
#[stable(feature = "core_float_bits", since="1.25.0")]
fn from_bits(v: Self::Bits) -> Self;
}

Expand Down
90 changes: 81 additions & 9 deletions src/libcore/ops/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,19 @@ impl fmt::Debug for RangeFull {
/// (`start..end`).
///
/// The `Range` `start..end` contains all values with `x >= start` and
/// `x < end`.
/// `x < end`. It is empty unless `start < end`.
///
/// # Examples
///
/// ```
/// assert_eq!((3..5), std::ops::Range { start: 3, end: 5 });
/// assert_eq!(3 + 4 + 5, (3..6).sum());
///
/// let arr = [0, 1, 2, 3];
/// assert_eq!(arr[ .. ], [0,1,2,3]);
/// assert_eq!(arr[ ..3], [0,1,2 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3]);
/// assert_eq!(arr[1..3], [ 1,2 ]); // Range
/// let arr = ['a', 'b', 'c', 'd'];
/// assert_eq!(arr[ .. ], ['a', 'b', 'c', 'd']);
/// assert_eq!(arr[ ..3], ['a', 'b', 'c', ]);
/// assert_eq!(arr[1.. ], [ 'b', 'c', 'd']);
/// assert_eq!(arr[1..3], [ 'b', 'c' ]); // Range
/// ```
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
#[stable(feature = "rust1", since = "1.0.0")]
Expand All @@ -92,7 +92,6 @@ impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> {
}
}

#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
impl<Idx: PartialOrd<Idx>> Range<Idx> {
/// Returns `true` if `item` is contained in the range.
///
Expand All @@ -109,9 +108,37 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
/// assert!(!(3..3).contains(3));
/// assert!(!(3..2).contains(3));
/// ```
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
pub fn contains(&self, item: Idx) -> bool {
(self.start <= item) && (item < self.end)
}

/// Returns `true` if the range contains no items.
///
/// # Examples
///
/// ```
/// #![feature(range_is_empty)]
///
/// assert!(!(3..5).is_empty());
/// assert!( (3..3).is_empty());
/// assert!( (3..2).is_empty());
/// ```
///
/// The range is empty if either side is incomparable:
///
/// ```
/// #![feature(range_is_empty,inclusive_range_syntax)]
///
/// use std::f32::NAN;
/// assert!(!(3.0..5.0).is_empty());
/// assert!( (3.0..NAN).is_empty());
/// assert!( (NAN..5.0).is_empty());
/// ```
#[unstable(feature = "range_is_empty", reason = "recently added", issue = "48111")]
pub fn is_empty(&self) -> bool {
!(self.start < self.end)
}
}

/// A range only bounded inclusively below (`start..`).
Expand Down Expand Up @@ -244,7 +271,14 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
/// An range bounded inclusively below and above (`start..=end`).
///
/// The `RangeInclusive` `start..=end` contains all values with `x >= start`
/// and `x <= end`.
/// and `x <= end`. It is empty unless `start <= end`.
///
/// This iterator is [fused], but the specific values of `start` and `end` after
/// iteration has finished are **unspecified** other than that [`.is_empty()`]
/// will return `true` once no more values will be produced.
///
/// [fused]: ../iter/trait.FusedIterator.html
/// [`.is_empty()`]: #method.is_empty
///
/// # Examples
///
Expand Down Expand Up @@ -280,7 +314,6 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
}
}

#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
/// Returns `true` if `item` is contained in the range.
///
Expand All @@ -298,9 +331,48 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
/// assert!( (3..=3).contains(3));
/// assert!(!(3..=2).contains(3));
/// ```
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
pub fn contains(&self, item: Idx) -> bool {
self.start <= item && item <= self.end
}

/// Returns `true` if the range contains no items.
///
/// # Examples
///
/// ```
/// #![feature(range_is_empty,inclusive_range_syntax)]
///
/// assert!(!(3..=5).is_empty());
/// assert!(!(3..=3).is_empty());
/// assert!( (3..=2).is_empty());
/// ```
///
/// The range is empty if either side is incomparable:
///
/// ```
/// #![feature(range_is_empty,inclusive_range_syntax)]
///
/// use std::f32::NAN;
/// assert!(!(3.0..=5.0).is_empty());
/// assert!( (3.0..=NAN).is_empty());
/// assert!( (NAN..=5.0).is_empty());
/// ```
///
/// This method returns `true` after iteration has finished:
///
/// ```
/// #![feature(range_is_empty,inclusive_range_syntax)]
///
/// let mut r = 3..=5;
/// for _ in r.by_ref() {}
/// // Precise field values are unspecified here
/// assert!(r.is_empty());
/// ```
#[unstable(feature = "range_is_empty", reason = "recently added", issue = "48111")]
pub fn is_empty(&self) -> bool {
!(self.start <= self.end)
}
}

/// A range only bounded inclusively above (`..=end`).
Expand Down
Loading

0 comments on commit d3fb063

Please sign in to comment.