From 143206d54d7558c2326212df99efc98110904fdb Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 18 Jun 2017 22:01:29 -0700 Subject: [PATCH] Stabilize RangeArgument Move it and Bound to core::ops while we're at it. Closes #30877 --- src/liballoc/btree/map.rs | 5 +- src/liballoc/btree/set.rs | 3 +- src/liballoc/lib.rs | 51 +---- src/liballoc/range.rs | 138 +------------- src/liballoc/string.rs | 5 +- src/liballoc/vec.rs | 5 +- src/liballoc/vec_deque.rs | 5 +- src/libcollections/lib.rs | 1 + src/libcore/ops/mod.rs | 3 + src/libcore/ops/range.rs | 174 +++++++++++++++++- .../accumulate_vec.rs | 3 +- src/librustc_data_structures/array_vec.rs | 5 +- src/librustc_data_structures/indexed_vec.rs | 3 +- src/librustc_data_structures/lib.rs | 1 - src/libstd/collections/mod.rs | 2 + 15 files changed, 187 insertions(+), 217 deletions(-) diff --git a/src/liballoc/btree/map.rs b/src/liballoc/btree/map.rs index a51c70159db4d..5243fb6ae0e06 100644 --- a/src/liballoc/btree/map.rs +++ b/src/liballoc/btree/map.rs @@ -13,12 +13,11 @@ use core::fmt::Debug; use core::hash::{Hash, Hasher}; use core::iter::{FromIterator, Peekable, FusedIterator}; use core::marker::PhantomData; -use core::ops::Index; +use core::ops::{Index, RangeArgument}; +use core::ops::Bound::{Excluded, Included, Unbounded}; 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; diff --git a/src/liballoc/btree/set.rs b/src/liballoc/btree/set.rs index d32460da93923..c755d2d8b8538 100644 --- a/src/liballoc/btree/set.rs +++ b/src/liballoc/btree/set.rs @@ -16,12 +16,11 @@ 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}; +use core::ops::{BitOr, BitAnd, BitXor, Sub, RangeArgument}; use borrow::Borrow; use btree_map::{BTreeMap, Keys}; use super::Recover; -use range::RangeArgument; // FIXME(conventions): implement bounded iterators diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index ca52943ea97e3..6f4e300fd3cc9 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -203,56 +203,7 @@ mod std { pub use core::ops; // RangeFull } -/// 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 { - /// 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, -} +pub use core::ops::Bound; /// An intermediate trait for specialization of `Extend`. #[doc(hidden)] diff --git a/src/liballoc/range.rs b/src/liballoc/range.rs index f862da0d61e01..0a058c47a50b2 100644 --- a/src/liballoc/range.rs +++ b/src/liballoc/range.rs @@ -11,142 +11,8 @@ #![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. -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 { - /// 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 RangeArgument for RangeFull { - fn start(&self) -> Bound<&T> { - Unbounded - } - fn end(&self) -> Bound<&T> { - Unbounded - } -} - -impl RangeArgument for RangeFrom { - fn start(&self) -> Bound<&T> { - Included(&self.start) - } - fn end(&self) -> Bound<&T> { - Unbounded - } -} - -impl RangeArgument for RangeTo { - fn start(&self) -> Bound<&T> { - Unbounded - } - fn end(&self) -> Bound<&T> { - Excluded(&self.end) - } -} - -impl RangeArgument for Range { - 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 RangeArgument for RangeInclusive { - 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 RangeArgument for RangeToInclusive { - fn start(&self) -> Bound<&T> { - Unbounded - } - fn end(&self) -> Bound<&T> { - Included(&self.end) - } -} - -impl RangeArgument for (Bound, Bound) { - 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 for (Bound<&'a T>, Bound<&'a T>) { - fn start(&self) -> Bound<&T> { - self.0 - } - - fn end(&self) -> Bound<&T> { - self.1 - } -} +pub use core::ops::RangeArgument; diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 79d1ccf637d37..1f0894d39d4d2 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -59,15 +59,14 @@ use core::fmt; use core::hash; use core::iter::{FromIterator, FusedIterator}; -use core::ops::{self, Add, AddAssign, Index, IndexMut}; +use core::ops::{self, Add, AddAssign, Index, IndexMut, RangeArgument}; +use core::ops::Bound::{Excluded, Included, Unbounded}; 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; diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 5d1999a42629a..e118d406ecf09 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -74,7 +74,8 @@ use core::iter::{FromIterator, FusedIterator, TrustedLen}; use core::mem; #[cfg(not(test))] use core::num::Float; -use core::ops::{InPlace, Index, IndexMut, Place, Placer}; +use core::ops::{InPlace, Index, IndexMut, Place, Placer, RangeArgument}; +use core::ops::Bound::{Excluded, Included, Unbounded}; use core::ops; use core::ptr; use core::ptr::Shared; @@ -84,8 +85,6 @@ 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` but pronounced 'vector'. /// diff --git a/src/liballoc/vec_deque.rs b/src/liballoc/vec_deque.rs index 18175a5d01bd2..d1d334267bccf 100644 --- a/src/liballoc/vec_deque.rs +++ b/src/liballoc/vec_deque.rs @@ -21,7 +21,8 @@ use core::cmp::Ordering; use core::fmt; use core::iter::{repeat, FromIterator, FusedIterator}; use core::mem; -use core::ops::{Index, IndexMut, Place, Placer, InPlace}; +use core::ops::{Index, IndexMut, Place, Placer, InPlace, RangeArgument}; +use core::ops::Bound::{Excluded, Included, Unbounded}; use core::ptr; use core::ptr::Shared; use core::slice; @@ -31,8 +32,6 @@ 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 diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index de5d6df328cbd..0a939831622f5 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -46,6 +46,7 @@ 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; diff --git a/src/libcore/ops/mod.rs b/src/libcore/ops/mod.rs index a78f4fe28a6b4..34f00850579e8 100644 --- a/src/libcore/ops/mod.rs +++ b/src/libcore/ops/mod.rs @@ -183,6 +183,9 @@ 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}; diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 33258b7a875c5..65e09da4fff05 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -9,6 +9,7 @@ // except according to those terms. use fmt; +use ops::Bound::{Included, Excluded, Unbounded}; /// An unbounded range. Use `..` (two dots) for its shorthand. /// @@ -71,7 +72,8 @@ 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 { /// The lower bound of the range (inclusive). @@ -134,7 +136,8 @@ impl> Range { /// 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 { /// The lower bound of the range (inclusive). @@ -250,17 +253,16 @@ impl> RangeTo { /// 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 { /// 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, } @@ -333,8 +335,7 @@ impl> RangeInclusive { #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] pub struct RangeToInclusive { /// 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, } @@ -365,3 +366,158 @@ impl> RangeToInclusive { // RangeToInclusive cannot impl From> // 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 { + /// 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 RangeArgument for RangeFull { + fn start(&self) -> Bound<&T> { + Unbounded + } + fn end(&self) -> Bound<&T> { + Unbounded + } +} + +#[stable(feature = "range_argument", since = "1.19.0")] +impl RangeArgument for RangeFrom { + fn start(&self) -> Bound<&T> { + Included(&self.start) + } + fn end(&self) -> Bound<&T> { + Unbounded + } +} + +#[stable(feature = "range_argument", since = "1.19.0")] +impl RangeArgument for RangeTo { + fn start(&self) -> Bound<&T> { + Unbounded + } + fn end(&self) -> Bound<&T> { + Excluded(&self.end) + } +} + +#[stable(feature = "range_argument", since = "1.19.0")] +impl RangeArgument for Range { + 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 RangeArgument for RangeInclusive { + 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 RangeArgument for RangeToInclusive { + fn start(&self) -> Bound<&T> { + Unbounded + } + fn end(&self) -> Bound<&T> { + Included(&self.end) + } +} + +#[stable(feature = "range_argument", since = "1.19.0")] +impl RangeArgument for (Bound, Bound) { + 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 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 { + /// 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, +} diff --git a/src/librustc_data_structures/accumulate_vec.rs b/src/librustc_data_structures/accumulate_vec.rs index c03c2890ba34c..eacd394ad5ea1 100644 --- a/src/librustc_data_structures/accumulate_vec.rs +++ b/src/librustc_data_structures/accumulate_vec.rs @@ -15,11 +15,10 @@ //! //! The N above is determined by Array's implementor, by way of an associatated constant. -use std::ops::{Deref, DerefMut}; +use std::ops::{Deref, DerefMut, RangeArgument}; use std::iter::{self, IntoIterator, FromIterator}; use std::slice; use std::vec; -use std::collections::range::RangeArgument; use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; diff --git a/src/librustc_data_structures/array_vec.rs b/src/librustc_data_structures/array_vec.rs index 078bb801751d0..a9abdf1377e9d 100644 --- a/src/librustc_data_structures/array_vec.rs +++ b/src/librustc_data_structures/array_vec.rs @@ -13,13 +13,12 @@ use std::marker::Unsize; use std::iter::Extend; use std::ptr::{self, drop_in_place, Shared}; -use std::ops::{Deref, DerefMut, Range}; +use std::ops::{Deref, DerefMut, Range, RangeArgument}; +use std::ops::Bound::{Excluded, Included, Unbounded}; 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 { diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs index 29ac650aa7053..3bf926fa8bf38 100644 --- a/src/librustc_data_structures/indexed_vec.rs +++ b/src/librustc_data_structures/indexed_vec.rs @@ -8,12 +8,11 @@ // 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}; +use std::ops::{Index, IndexMut, Range, RangeArgument}; use std::fmt; use std::vec; use std::u32; diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index d63b4c9c31b5b..0bbda547761cc 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -25,7 +25,6 @@ #![deny(warnings)] #![feature(shared)] -#![feature(collections_range)] #![feature(nonzero)] #![feature(unboxed_closures)] #![feature(fn_traits)] diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index b8a6a66eaa65d..2ed6724b07da4 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -436,6 +436,8 @@ 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;