Skip to content

Revert "Stabilize RangeArgument" #42991

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 1, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/liballoc/btree/map.rs
Original file line number Diff line number Diff line change
@@ -13,11 +13,12 @@ use core::fmt::Debug;
use core::hash::{Hash, Hasher};
use core::iter::{FromIterator, Peekable, FusedIterator};
use core::marker::PhantomData;
use core::ops::{Index, RangeArgument};
use core::ops::Bound::{Excluded, Included, Unbounded};
use core::ops::Index;
use core::{fmt, intrinsics, mem, ptr};

use borrow::Borrow;
use Bound::{Excluded, Included, Unbounded};
use range::RangeArgument;

use super::node::{self, Handle, NodeRef, marker};
use super::search;
3 changes: 2 additions & 1 deletion src/liballoc/btree/set.rs
Original file line number Diff line number Diff line change
@@ -16,11 +16,12 @@ use core::cmp::{min, max};
use core::fmt::Debug;
use core::fmt;
use core::iter::{Peekable, FromIterator, FusedIterator};
use core::ops::{BitOr, BitAnd, BitXor, Sub, RangeArgument};
use core::ops::{BitOr, BitAnd, BitXor, Sub};

use borrow::Borrow;
use btree_map::{BTreeMap, Keys};
use super::Recover;
use range::RangeArgument;

// FIXME(conventions): implement bounded iterators

51 changes: 50 additions & 1 deletion src/liballoc/lib.rs
Original file line number Diff line number Diff line change
@@ -203,7 +203,56 @@ mod std {
pub use core::ops; // RangeFull
}

pub use core::ops::Bound;
/// An endpoint of a range of keys.
///
/// # Examples
///
/// `Bound`s are range endpoints:
///
/// ```
/// #![feature(collections_range)]
///
/// use std::collections::range::RangeArgument;
/// use std::collections::Bound::*;
///
/// assert_eq!((..100).start(), Unbounded);
/// assert_eq!((1..12).start(), Included(&1));
/// assert_eq!((1..12).end(), Excluded(&12));
/// ```
///
/// Using a tuple of `Bound`s as an argument to [`BTreeMap::range`].
/// Note that in most cases, it's better to use range syntax (`1..5`) instead.
///
/// ```
/// use std::collections::BTreeMap;
/// use std::collections::Bound::{Excluded, Included, Unbounded};
///
/// let mut map = BTreeMap::new();
/// map.insert(3, "a");
/// map.insert(5, "b");
/// map.insert(8, "c");
///
/// for (key, value) in map.range((Excluded(3), Included(8))) {
/// println!("{}: {}", key, value);
/// }
///
/// assert_eq!(Some((&3, &"a")), map.range((Unbounded, Included(5))).next());
/// ```
///
/// [`BTreeMap::range`]: btree_map/struct.BTreeMap.html#method.range
#[stable(feature = "collections_bound", since = "1.17.0")]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub enum Bound<T> {
/// An inclusive bound.
#[stable(feature = "collections_bound", since = "1.17.0")]
Included(T),
/// An exclusive bound.
#[stable(feature = "collections_bound", since = "1.17.0")]
Excluded(T),
/// An infinite endpoint. Indicates that there is no bound in this direction.
#[stable(feature = "collections_bound", since = "1.17.0")]
Unbounded,
}

/// An intermediate trait for specialization of `Extend`.
#[doc(hidden)]
138 changes: 136 additions & 2 deletions src/liballoc/range.rs
Original file line number Diff line number Diff line change
@@ -11,8 +11,142 @@
#![unstable(feature = "collections_range",
reason = "waiting for dust to settle on inclusive ranges",
issue = "30877")]
#![rustc_deprecated(reason = "moved to core::ops", since = "1.19.0")]

//! Range syntax.

pub use core::ops::RangeArgument;
use core::ops::{RangeFull, Range, RangeTo, RangeFrom, RangeInclusive, RangeToInclusive};
use Bound::{self, Excluded, Included, Unbounded};

/// `RangeArgument` is implemented by Rust's built-in range types, produced
/// by range syntax like `..`, `a..`, `..b` or `c..d`.
pub trait RangeArgument<T: ?Sized> {
/// Start index bound.
///
/// Returns the start value as a `Bound`.
///
/// # Examples
///
/// ```
/// #![feature(alloc)]
/// #![feature(collections_range)]
///
/// extern crate alloc;
///
/// # fn main() {
/// use alloc::range::RangeArgument;
/// use alloc::Bound::*;
///
/// assert_eq!((..10).start(), Unbounded);
/// assert_eq!((3..10).start(), Included(&3));
/// # }
/// ```
fn start(&self) -> Bound<&T>;

/// End index bound.
///
/// Returns the end value as a `Bound`.
///
/// # Examples
///
/// ```
/// #![feature(alloc)]
/// #![feature(collections_range)]
///
/// extern crate alloc;
///
/// # fn main() {
/// use alloc::range::RangeArgument;
/// use alloc::Bound::*;
///
/// assert_eq!((3..).end(), Unbounded);
/// assert_eq!((3..10).end(), Excluded(&10));
/// # }
/// ```
fn end(&self) -> Bound<&T>;
}

// FIXME add inclusive ranges to RangeArgument

impl<T: ?Sized> RangeArgument<T> for RangeFull {
fn start(&self) -> Bound<&T> {
Unbounded
}
fn end(&self) -> Bound<&T> {
Unbounded
}
}

impl<T> RangeArgument<T> for RangeFrom<T> {
fn start(&self) -> Bound<&T> {
Included(&self.start)
}
fn end(&self) -> Bound<&T> {
Unbounded
}
}

impl<T> RangeArgument<T> for RangeTo<T> {
fn start(&self) -> Bound<&T> {
Unbounded
}
fn end(&self) -> Bound<&T> {
Excluded(&self.end)
}
}

impl<T> RangeArgument<T> for Range<T> {
fn start(&self) -> Bound<&T> {
Included(&self.start)
}
fn end(&self) -> Bound<&T> {
Excluded(&self.end)
}
}

#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<T> RangeArgument<T> for RangeInclusive<T> {
fn start(&self) -> Bound<&T> {
Included(&self.start)
}
fn end(&self) -> Bound<&T> {
Included(&self.end)
}
}

#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<T> RangeArgument<T> for RangeToInclusive<T> {
fn start(&self) -> Bound<&T> {
Unbounded
}
fn end(&self) -> Bound<&T> {
Included(&self.end)
}
}

impl<T> RangeArgument<T> for (Bound<T>, Bound<T>) {
fn start(&self) -> Bound<&T> {
match *self {
(Included(ref start), _) => Included(start),
(Excluded(ref start), _) => Excluded(start),
(Unbounded, _) => Unbounded,
}
}

fn end(&self) -> Bound<&T> {
match *self {
(_, Included(ref end)) => Included(end),
(_, Excluded(ref end)) => Excluded(end),
(_, Unbounded) => Unbounded,
}
}
}

impl<'a, T: ?Sized + 'a> RangeArgument<T> for (Bound<&'a T>, Bound<&'a T>) {
fn start(&self) -> Bound<&T> {
self.0
}

fn end(&self) -> Bound<&T> {
self.1
}
}
5 changes: 3 additions & 2 deletions src/liballoc/string.rs
Original file line number Diff line number Diff line change
@@ -59,14 +59,15 @@
use core::fmt;
use core::hash;
use core::iter::{FromIterator, FusedIterator};
use core::ops::{self, Add, AddAssign, Index, IndexMut, RangeArgument};
use core::ops::Bound::{Excluded, Included, Unbounded};
use core::ops::{self, Add, AddAssign, Index, IndexMut};
use core::ptr;
use core::str::pattern::Pattern;
use std_unicode::lossy;
use std_unicode::char::{decode_utf16, REPLACEMENT_CHARACTER};

use borrow::{Cow, ToOwned};
use range::RangeArgument;
use Bound::{Excluded, Included, Unbounded};
use str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars};
use vec::Vec;
use boxed::Box;
5 changes: 3 additions & 2 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
@@ -74,8 +74,7 @@ use core::iter::{FromIterator, FusedIterator, TrustedLen};
use core::mem;
#[cfg(not(test))]
use core::num::Float;
use core::ops::{InPlace, Index, IndexMut, Place, Placer, RangeArgument};
use core::ops::Bound::{Excluded, Included, Unbounded};
use core::ops::{InPlace, Index, IndexMut, Place, Placer};
use core::ops;
use core::ptr;
use core::ptr::Shared;
@@ -85,6 +84,8 @@ use borrow::ToOwned;
use borrow::Cow;
use boxed::Box;
use raw_vec::RawVec;
use super::range::RangeArgument;
use Bound::{Excluded, Included, Unbounded};

/// A contiguous growable array type, written `Vec<T>` but pronounced 'vector'.
///
5 changes: 3 additions & 2 deletions src/liballoc/vec_deque.rs
Original file line number Diff line number Diff line change
@@ -21,8 +21,7 @@ use core::cmp::Ordering;
use core::fmt;
use core::iter::{repeat, FromIterator, FusedIterator};
use core::mem;
use core::ops::{Index, IndexMut, Place, Placer, InPlace, RangeArgument};
use core::ops::Bound::{Excluded, Included, Unbounded};
use core::ops::{Index, IndexMut, Place, Placer, InPlace};
use core::ptr;
use core::ptr::Shared;
use core::slice;
@@ -32,6 +31,8 @@ use core::cmp;

use raw_vec::RawVec;

use super::range::RangeArgument;
use Bound::{Excluded, Included, Unbounded};
use super::vec::Vec;

const INITIAL_CAPACITY: usize = 7; // 2^3 - 1
1 change: 0 additions & 1 deletion src/libcollections/lib.rs
Original file line number Diff line number Diff line change
@@ -46,7 +46,6 @@ pub use alloc::binary_heap;
pub use alloc::borrow;
pub use alloc::fmt;
pub use alloc::linked_list;
#[allow(deprecated)]
pub use alloc::range;
pub use alloc::slice;
pub use alloc::str;
3 changes: 0 additions & 3 deletions src/libcore/ops/mod.rs
Original file line number Diff line number Diff line change
@@ -183,9 +183,6 @@ pub use self::index::{Index, IndexMut};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};

#[stable(feature = "range_argument", since = "1.19.0")]
pub use self::range::{RangeArgument, Bound};

#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
pub use self::range::{RangeInclusive, RangeToInclusive};

174 changes: 9 additions & 165 deletions src/libcore/ops/range.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,6 @@
// except according to those terms.

use fmt;
use ops::Bound::{Included, Excluded, Unbounded};

/// An unbounded range. Use `..` (two dots) for its shorthand.
///
@@ -72,8 +71,7 @@ impl fmt::Debug for RangeFull {
/// assert_eq!(arr[1..3], [ 1,2 ]); // Range
/// }
/// ```
#[derive(Clone, PartialEq, Eq, Hash)]
// not Copy -- see #27186
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Range<Idx> {
/// The lower bound of the range (inclusive).
@@ -136,8 +134,7 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
/// assert_eq!(arr[1..3], [ 1,2 ]);
/// }
/// ```
#[derive(Clone, PartialEq, Eq, Hash)]
// not Copy -- see #27186
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
#[stable(feature = "rust1", since = "1.0.0")]
pub struct RangeFrom<Idx> {
/// The lower bound of the range (inclusive).
@@ -253,16 +250,17 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
/// assert_eq!(arr[1...2], [ 1,2 ]); // RangeInclusive
/// }
/// ```
#[derive(Clone, PartialEq, Eq, Hash)]
// not Copy -- see #27186
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
pub struct RangeInclusive<Idx> {
/// The lower bound of the range (inclusive).
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC",
#[unstable(feature = "inclusive_range",
reason = "recently added, follows RFC",
issue = "28237")]
pub start: Idx,
/// The upper bound of the range (inclusive).
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC",
#[unstable(feature = "inclusive_range",
reason = "recently added, follows RFC",
issue = "28237")]
pub end: Idx,
}
@@ -335,7 +333,8 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
pub struct RangeToInclusive<Idx> {
/// The upper bound of the range (inclusive)
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC",
#[unstable(feature = "inclusive_range",
reason = "recently added, follows RFC",
issue = "28237")]
pub end: Idx,
}
@@ -366,158 +365,3 @@ impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {

// RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>>
// because underflow would be possible with (..0).into()

/// `RangeArgument` is implemented by Rust's built-in range types, produced
/// by range syntax like `..`, `a..`, `..b` or `c..d`.
#[stable(feature = "range_argument", since = "1.19.0")]
pub trait RangeArgument<T: ?Sized> {
/// Start index bound.
///
/// Returns the start value as a `Bound`.
///
/// # Examples
///
/// ```
/// use std::ops::RangeArgument;
/// use std::ops::Bound::*;
///
/// assert_eq!((..10).start(), Unbounded);
/// assert_eq!((3..10).start(), Included(&3));
/// ```
#[stable(feature = "range_argument", since = "1.19.0")]
fn start(&self) -> Bound<&T>;

/// End index bound.
///
/// Returns the end value as a `Bound`.
///
/// # Examples
///
/// ```
/// use std::ops::RangeArgument;
/// use std::ops::Bound::*;
///
/// assert_eq!((3..).end(), Unbounded);
/// assert_eq!((3..10).end(), Excluded(&10));
/// ```
#[stable(feature = "range_argument", since = "1.19.0")]
fn end(&self) -> Bound<&T>;
}

#[stable(feature = "range_argument", since = "1.19.0")]
impl<T: ?Sized> RangeArgument<T> for RangeFull {
fn start(&self) -> Bound<&T> {
Unbounded
}
fn end(&self) -> Bound<&T> {
Unbounded
}
}

#[stable(feature = "range_argument", since = "1.19.0")]
impl<T> RangeArgument<T> for RangeFrom<T> {
fn start(&self) -> Bound<&T> {
Included(&self.start)
}
fn end(&self) -> Bound<&T> {
Unbounded
}
}

#[stable(feature = "range_argument", since = "1.19.0")]
impl<T> RangeArgument<T> for RangeTo<T> {
fn start(&self) -> Bound<&T> {
Unbounded
}
fn end(&self) -> Bound<&T> {
Excluded(&self.end)
}
}

#[stable(feature = "range_argument", since = "1.19.0")]
impl<T> RangeArgument<T> for Range<T> {
fn start(&self) -> Bound<&T> {
Included(&self.start)
}
fn end(&self) -> Bound<&T> {
Excluded(&self.end)
}
}

#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<T> RangeArgument<T> for RangeInclusive<T> {
fn start(&self) -> Bound<&T> {
Included(&self.start)
}
fn end(&self) -> Bound<&T> {
Included(&self.end)
}
}

#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<T> RangeArgument<T> for RangeToInclusive<T> {
fn start(&self) -> Bound<&T> {
Unbounded
}
fn end(&self) -> Bound<&T> {
Included(&self.end)
}
}

#[stable(feature = "range_argument", since = "1.19.0")]
impl<T> RangeArgument<T> for (Bound<T>, Bound<T>) {
fn start(&self) -> Bound<&T> {
match *self {
(Included(ref start), _) => Included(start),
(Excluded(ref start), _) => Excluded(start),
(Unbounded, _) => Unbounded,
}
}

fn end(&self) -> Bound<&T> {
match *self {
(_, Included(ref end)) => Included(end),
(_, Excluded(ref end)) => Excluded(end),
(_, Unbounded) => Unbounded,
}
}
}

#[stable(feature = "range_argument", since = "1.19.0")]
impl<'a, T: ?Sized + 'a> RangeArgument<T> for (Bound<&'a T>, Bound<&'a T>) {
fn start(&self) -> Bound<&T> {
self.0
}

fn end(&self) -> Bound<&T> {
self.1
}
}

/// An endpoint of a range of keys.
///
/// # Examples
///
/// `Bound`s are range endpoints:
///
/// ```
/// use std::ops::RangeArgument;
/// use std::ops::Bound::*;
///
/// assert_eq!((..100).start(), Unbounded);
/// assert_eq!((1..12).start(), Included(&1));
/// assert_eq!((1..12).end(), Excluded(&12));
/// ```
#[stable(feature = "collections_bound", since = "1.17.0")]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub enum Bound<T> {
/// An inclusive bound.
#[stable(feature = "collections_bound", since = "1.17.0")]
Included(T),
/// An exclusive bound.
#[stable(feature = "collections_bound", since = "1.17.0")]
Excluded(T),
/// An infinite endpoint. Indicates that there is no bound in this direction.
#[stable(feature = "collections_bound", since = "1.17.0")]
Unbounded,
}
3 changes: 2 additions & 1 deletion src/librustc_data_structures/accumulate_vec.rs
Original file line number Diff line number Diff line change
@@ -15,10 +15,11 @@
//!
//! The N above is determined by Array's implementor, by way of an associatated constant.
use std::ops::{Deref, DerefMut, RangeArgument};
use std::ops::{Deref, DerefMut};
use std::iter::{self, IntoIterator, FromIterator};
use std::slice;
use std::vec;
use std::collections::range::RangeArgument;

use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};

5 changes: 3 additions & 2 deletions src/librustc_data_structures/array_vec.rs
Original file line number Diff line number Diff line change
@@ -13,12 +13,13 @@
use std::marker::Unsize;
use std::iter::Extend;
use std::ptr::{self, drop_in_place, Shared};
use std::ops::{Deref, DerefMut, Range, RangeArgument};
use std::ops::Bound::{Excluded, Included, Unbounded};
use std::ops::{Deref, DerefMut, Range};
use std::hash::{Hash, Hasher};
use std::slice;
use std::fmt;
use std::mem;
use std::collections::range::RangeArgument;
use std::collections::Bound::{Excluded, Included, Unbounded};
use std::mem::ManuallyDrop;

pub unsafe trait Array {
3 changes: 2 additions & 1 deletion src/librustc_data_structures/indexed_vec.rs
Original file line number Diff line number Diff line change
@@ -8,11 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::collections::range::RangeArgument;
use std::fmt::Debug;
use std::iter::{self, FromIterator};
use std::slice;
use std::marker::PhantomData;
use std::ops::{Index, IndexMut, Range, RangeArgument};
use std::ops::{Index, IndexMut, Range};
use std::fmt;
use std::vec;
use std::u32;
1 change: 1 addition & 0 deletions src/librustc_data_structures/lib.rs
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@
#![deny(warnings)]

#![feature(shared)]
#![feature(collections_range)]
#![feature(nonzero)]
#![feature(unboxed_closures)]
#![feature(fn_traits)]
2 changes: 0 additions & 2 deletions src/libstd/collections/mod.rs
Original file line number Diff line number Diff line change
@@ -436,8 +436,6 @@ pub use self::hash_map::HashMap;
pub use self::hash_set::HashSet;

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_deprecated(reason = "moved to std::ops", since = "1.19.0")]
#[allow(deprecated)]
pub use alloc::range;

mod hash;