From fba0bf63a90379e8825012a817167774e14a627f Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Thu, 15 Jan 2015 20:00:09 -0800 Subject: [PATCH 1/5] Stabilize Index traits and most range notation This commit marks as `#[stable]`: * The `Index` and `IndexMut` traits. These are stabilized as taking the index itself *by reference*; after extensive discussion it was determined that this is a better match with our choices elsewhere (e.g. making comparison operators auto-reference), and that the use cases for by-value indices are better handled through `IndexSet`. * The `Range`, `RangeFrom` and `RangeTo` structs, introduced for range notation. * Various impls of `Index` and `IndexMut`. The `FullRange` struct is left unstable as we may wish to rename it to `RangeFull` in the future. This commit also *removes* the `Step` trait in favor of direct implementation of iterator traits on ranges for integers. The `Step` trait was not a terribly useful factoring internally, and it is likely that external integer types are best off implementing range iterators directly. It was removed to simplify the API surface. We can always reintroduce `Step` later if it turns out to be useful. Due to this removal, this is a: [breaking-change] --- src/libcollections/vec.rs | 12 ++++- src/libcore/iter.rs | 102 ++++++++++++++++++++++++-------------- src/libcore/ops.rs | 75 +++++----------------------- 3 files changed, 88 insertions(+), 101 deletions(-) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 4ddab8c533aa..7596973ea23b 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1229,7 +1229,7 @@ impl> Hash for Vec { } } -#[unstable = "waiting on Index stability"] +#[stable] impl Index for Vec { type Output = T; @@ -1239,6 +1239,7 @@ impl Index for Vec { } } +#[stable] impl IndexMut for Vec { type Output = T; @@ -1249,6 +1250,7 @@ impl IndexMut for Vec { } +#[stable] impl ops::Index> for Vec { type Output = [T]; #[inline] @@ -1256,6 +1258,7 @@ impl ops::Index> for Vec { self.as_slice().index(index) } } +#[stable] impl ops::Index> for Vec { type Output = [T]; #[inline] @@ -1263,6 +1266,7 @@ impl ops::Index> for Vec { self.as_slice().index(index) } } +#[stable] impl ops::Index> for Vec { type Output = [T]; #[inline] @@ -1270,6 +1274,7 @@ impl ops::Index> for Vec { self.as_slice().index(index) } } +#[stable] impl ops::Index for Vec { type Output = [T]; #[inline] @@ -1278,6 +1283,7 @@ impl ops::Index for Vec { } } +#[stable] impl ops::IndexMut> for Vec { type Output = [T]; #[inline] @@ -1285,6 +1291,7 @@ impl ops::IndexMut> for Vec { self.as_mut_slice().index_mut(index) } } +#[stable] impl ops::IndexMut> for Vec { type Output = [T]; #[inline] @@ -1292,6 +1299,7 @@ impl ops::IndexMut> for Vec { self.as_mut_slice().index_mut(index) } } +#[stable] impl ops::IndexMut> for Vec { type Output = [T]; #[inline] @@ -1299,6 +1307,7 @@ impl ops::IndexMut> for Vec { self.as_mut_slice().index_mut(index) } } +#[stable] impl ops::IndexMut for Vec { type Output = [T]; #[inline] @@ -1307,7 +1316,6 @@ impl ops::IndexMut for Vec { } } - #[stable] impl ops::Deref for Vec { type Target = [T]; diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 0005db36c278..faf8ccbc90eb 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -2701,63 +2701,93 @@ impl Iterator for RangeStepInclusive { } } +macro_rules! range_impl { + ($($t:ty)*) => ($( + #[stable] + impl Iterator for ::ops::Range<$t> { + type Item = $t; -/// The `Step` trait identifies objects which can be stepped over in both -/// directions. The `steps_between` function provides a way to -/// compare two Step objects (it could be provided using `step()` and `Ord`, -/// but the implementation would be so inefficient as to be useless). -#[unstable = "design of range notation/iteration is in flux"] -pub trait Step: Ord { - /// Change self to the next object. - fn step(&mut self); - /// Change self to the previous object. - fn step_back(&mut self); - /// The steps_between two step objects. - /// start should always be less than end, so the result should never be negative. - /// Return None if it is not possible to calculate steps_between without - /// overflow. - fn steps_between(start: &Self, end: &Self) -> Option; + #[inline] + fn next(&mut self) -> Option<$t> { + if self.start < self.end { + let result = self.start; + self.start += 1; + return Some(result); + } + + return None; + } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + debug_assert!(self.end >= self.start); + let hint = (self.end - self.start) as uint; + (hint, Some(hint)) + } + } + + #[stable] + impl ExactSizeIterator for ::ops::Range<$t> {} + )*) } -macro_rules! step_impl { +macro_rules! range_impl_no_hint { ($($t:ty)*) => ($( - #[unstable = "Trait is unstable."] - impl Step for $t { + #[stable] + impl Iterator for ::ops::Range<$t> { + type Item = $t; + #[inline] - fn step(&mut self) { *self += 1; } - #[inline] - fn step_back(&mut self) { *self -= 1; } - #[inline] - fn steps_between(start: &$t, end: &$t) -> Option { - debug_assert!(end >= start); - Some((*end - *start) as uint) + fn next(&mut self) -> Option<$t> { + if self.start < self.end { + let result = self.start; + self.start += 1; + return Some(result); + } + + return None; } } )*) } -macro_rules! step_impl_no_between { +macro_rules! range_other_impls { ($($t:ty)*) => ($( - #[unstable = "Trait is unstable."] - impl Step for $t { + #[stable] + impl DoubleEndedIterator for ::ops::Range<$t> { #[inline] - fn step(&mut self) { *self += 1; } + fn next_back(&mut self) -> Option<$t> { + if self.start < self.end { + self.end -= 1; + return Some(self.end); + } + + return None; + } + } + + #[stable] + impl Iterator for ::ops::RangeFrom<$t> { + type Item = $t; + #[inline] - fn step_back(&mut self) { *self -= 1; } - #[inline] - fn steps_between(_start: &$t, _end: &$t) -> Option { - None + fn next(&mut self) -> Option<$t> { + let result = self.start; + self.start += 1; + debug_assert!(result < self.start); + return Some(result); } } )*) } -step_impl!(uint u8 u16 u32 int i8 i16 i32); +range_impl!(uint u8 u16 u32 int i8 i16 i32); #[cfg(target_pointer_width = "64")] -step_impl!(u64 i64); +range_impl!(u64 i64); #[cfg(target_pointer_width = "32")] -step_impl_no_between!(u64 i64); +range_impl_no_hint!(u64 i64); +range_other_impls!(uint u8 u16 u32 u64 int i8 i16 i32 i64); /// An iterator that repeats an element endlessly #[derive(Clone)] diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 905de9ef615d..e5186f9335aa 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -69,10 +69,7 @@ #![stable] -use clone::Clone; -use iter::{Step, Iterator,DoubleEndedIterator,ExactSizeIterator}; use marker::Sized; -use option::Option::{self, Some, None}; use fmt; /// The `Drop` trait is used to run some code when a value goes out of scope. This @@ -924,10 +921,12 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } /// } /// ``` #[lang="index"] +#[stable] pub trait Index { type Output: ?Sized; /// The method for the indexing (`Foo[Bar]`) operation + #[stable] fn index<'a>(&'a self, index: &Index) -> &'a Self::Output; } @@ -960,20 +959,22 @@ pub trait Index { /// } /// ``` #[lang="index_mut"] +#[stable] pub trait IndexMut { type Output: ?Sized; /// The method for the indexing (`Foo[Bar]`) operation + #[stable] fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Self::Output; } /// An unbounded range. #[derive(Copy, Clone, PartialEq, Eq)] #[lang="full_range"] -#[unstable = "API still in development"] +#[unstable = "may be renamed to RangeFull"] pub struct FullRange; -#[unstable = "API still in development"] +#[stable] impl fmt::Show for FullRange { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt::Show::fmt("..", fmt) @@ -983,7 +984,7 @@ impl fmt::Show for FullRange { /// A (half-open) range which is bounded at both ends. #[derive(Copy, Clone, PartialEq, Eq)] #[lang="range"] -#[unstable = "API still in development"] +#[stable] pub struct Range { /// The lower bound of the range (inclusive). pub start: Idx, @@ -991,48 +992,7 @@ pub struct Range { pub end: Idx, } -#[unstable = "API still in development"] -impl Iterator for Range { - type Item = Idx; - - #[inline] - fn next(&mut self) -> Option { - if self.start < self.end { - let result = self.start.clone(); - self.start.step(); - return Some(result); - } - - return None; - } - - #[inline] - fn size_hint(&self) -> (uint, Option) { - if let Some(hint) = Step::steps_between(&self.start, &self.end) { - (hint, Some(hint)) - } else { - (0, None) - } - } -} - -#[unstable = "API still in development"] -impl DoubleEndedIterator for Range { - #[inline] - fn next_back(&mut self) -> Option { - if self.start < self.end { - self.end.step_back(); - return Some(self.end.clone()); - } - - return None; - } -} - -#[unstable = "API still in development"] -impl ExactSizeIterator for Range {} - -#[unstable = "API still in development"] +#[stable] impl fmt::Show for Range { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{:?}..{:?}", self.start, self.end) @@ -1042,26 +1002,15 @@ impl fmt::Show for Range { /// A range which is only bounded below. #[derive(Copy, Clone, PartialEq, Eq)] #[lang="range_from"] -#[unstable = "API still in development"] +#[stable] pub struct RangeFrom { /// The lower bound of the range (inclusive). pub start: Idx, } -#[unstable = "API still in development"] -impl Iterator for RangeFrom { - type Item = Idx; - #[inline] - fn next(&mut self) -> Option { - // Deliberately overflow so we loop forever. - let result = self.start.clone(); - self.start.step(); - return Some(result); - } -} -#[unstable = "API still in development"] +#[stable] impl fmt::Show for RangeFrom { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{:?}..", self.start) @@ -1071,13 +1020,13 @@ impl fmt::Show for RangeFrom { /// A range which is only bounded above. #[derive(Copy, Clone, PartialEq, Eq)] #[lang="range_to"] -#[unstable = "API still in development"] +#[stable] pub struct RangeTo { /// The upper bound of the range (exclusive). pub end: Idx, } -#[unstable = "API still in development"] +#[stable] impl fmt::Show for RangeTo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "..{:?}", self.end) From 092ba6a8563b5c95f5aa53a705eaba6cc94e2da7 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Sat, 17 Jan 2015 16:15:47 -0800 Subject: [PATCH 2/5] Deprecate slicing methods in favor of notation This commit deprecates `slice`, `slice_from`, `slice_to` and their mutable variants in favor of slice notation. The `as_slice` methods are left intact, for now. [breaking-change] --- src/libcollections/slice.rs | 62 ++++++-------------- src/libcollections/str.rs | 56 ++---------------- src/libcollections/string.rs | 4 ++ src/libcore/slice.rs | 68 ++++++---------------- src/libcore/str/mod.rs | 110 ++++++++++++++++++++++------------- 5 files changed, 115 insertions(+), 185 deletions(-) diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 988ec4c661fa..a640e4ee0e34 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -169,29 +169,16 @@ pub trait SliceExt { #[unstable = "uncertain about this API approach"] fn move_from(&mut self, src: Vec, start: uint, end: uint) -> uint; - /// Returns a subslice spanning the interval [`start`, `end`). - /// - /// Panics when the end of the new slice lies beyond the end of the - /// original slice (i.e. when `end > self.len()`) or when `start > end`. - /// - /// Slicing with `start` equal to `end` yields an empty slice. - #[unstable = "will be replaced by slice syntax"] + /// Deprecated: use `&s[start .. end]` notation instead. + #[deprecated = "use &s[start .. end] instead"] fn slice(&self, start: uint, end: uint) -> &[Self::Item]; - /// Returns a subslice from `start` to the end of the slice. - /// - /// Panics when `start` is strictly greater than the length of the original slice. - /// - /// Slicing from `self.len()` yields an empty slice. - #[unstable = "will be replaced by slice syntax"] + /// Deprecated: use `&s[start..]` notation instead. + #[deprecated = "use &s[start..] isntead"] fn slice_from(&self, start: uint) -> &[Self::Item]; - /// Returns a subslice from the start of the slice to `end`. - /// - /// Panics when `end` is strictly greater than the length of the original slice. - /// - /// Slicing to `0` yields an empty slice. - #[unstable = "will be replaced by slice syntax"] + /// Deprecated: use `&s[..end]` notation instead. + #[deprecated = "use &s[..end] instead"] fn slice_to(&self, end: uint) -> &[Self::Item]; /// Divides one slice into two at an index. @@ -378,29 +365,16 @@ pub trait SliceExt { #[stable] fn as_mut_slice(&mut self) -> &mut [Self::Item]; - /// Returns a mutable subslice spanning the interval [`start`, `end`). - /// - /// Panics when the end of the new slice lies beyond the end of the - /// original slice (i.e. when `end > self.len()`) or when `start > end`. - /// - /// Slicing with `start` equal to `end` yields an empty slice. - #[unstable = "will be replaced by slice syntax"] + /// Deprecated: use `&mut s[start .. end]` instead. + #[deprecated = "use &mut s[start .. end] instead"] fn slice_mut(&mut self, start: uint, end: uint) -> &mut [Self::Item]; - /// Returns a mutable subslice from `start` to the end of the slice. - /// - /// Panics when `start` is strictly greater than the length of the original slice. - /// - /// Slicing from `self.len()` yields an empty slice. - #[unstable = "will be replaced by slice syntax"] + /// Deprecated: use `&mut s[start ..]` instead. + #[deprecated = "use &mut s[start ..] instead"] fn slice_from_mut(&mut self, start: uint) -> &mut [Self::Item]; - /// Returns a mutable subslice from the start of the slice to `end`. - /// - /// Panics when `end` is strictly greater than the length of the original slice. - /// - /// Slicing to `0` yields an empty slice. - #[unstable = "will be replaced by slice syntax"] + /// Deprecated: use `&mut s[.. end]` instead. + #[deprecated = "use &mut s[.. end] instead"] fn slice_to_mut(&mut self, end: uint) -> &mut [Self::Item]; /// Returns an iterator that allows modifying each value @@ -720,17 +694,17 @@ impl SliceExt for [T] { #[inline] fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T] { - core_slice::SliceExt::slice(self, start, end) + &self[start .. end] } #[inline] fn slice_from<'a>(&'a self, start: uint) -> &'a [T] { - core_slice::SliceExt::slice_from(self, start) + &self[start ..] } #[inline] fn slice_to<'a>(&'a self, end: uint) -> &'a [T] { - core_slice::SliceExt::slice_to(self, end) + &self[.. end] } #[inline] @@ -834,17 +808,17 @@ impl SliceExt for [T] { #[inline] fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [T] { - core_slice::SliceExt::slice_mut(self, start, end) + &mut self[start .. end] } #[inline] fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T] { - core_slice::SliceExt::slice_from_mut(self, start) + &mut self[start ..] } #[inline] fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T] { - core_slice::SliceExt::slice_to_mut(self, end) + &mut self[.. end] } #[inline] diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index f7668930660b..94554fd1e81d 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -750,64 +750,20 @@ pub trait StrExt: Index { core_str::StrExt::lines_any(&self[]) } - /// Returns a slice of the given string from the byte range - /// [`begin`..`end`). - /// - /// This operation is `O(1)`. - /// - /// Panics when `begin` and `end` do not point to valid characters - /// or point beyond the last character of the string. - /// - /// See also `slice_to` and `slice_from` for slicing prefixes and - /// suffixes of strings, and `slice_chars` for slicing based on - /// code point counts. - /// - /// # Example - /// - /// ```rust - /// let s = "Löwe 老虎 Léopard"; - /// assert_eq!(s.slice(0, 1), "L"); - /// - /// assert_eq!(s.slice(1, 9), "öwe 老"); - /// - /// // these will panic: - /// // byte 2 lies within `ö`: - /// // s.slice(2, 3); - /// - /// // byte 8 lies within `老` - /// // s.slice(1, 8); - /// - /// // byte 100 is outside the string - /// // s.slice(3, 100); - /// ``` - #[unstable = "use slice notation [a..b] instead"] + /// Deprecated: use `s[a .. b]` instead. + #[deprecated = "use slice notation [a..b] instead"] fn slice(&self, begin: uint, end: uint) -> &str { core_str::StrExt::slice(&self[], begin, end) } - /// Returns a slice of the string from `begin` to its end. - /// - /// Equivalent to `self.slice(begin, self.len())`. - /// - /// Panics when `begin` does not point to a valid character, or is - /// out of bounds. - /// - /// See also `slice`, `slice_to` and `slice_chars`. - #[unstable = "use slice notation [a..] instead"] + /// Deprecated: use `s[a..]` instead. + #[deprecated = "use slice notation [a..] instead"] fn slice_from(&self, begin: uint) -> &str { core_str::StrExt::slice_from(&self[], begin) } - /// Returns a slice of the string from the beginning to byte - /// `end`. - /// - /// Equivalent to `self.slice(0, end)`. - /// - /// Panics when `end` does not point to a valid character, or is - /// out of bounds. - /// - /// See also `slice`, `slice_from` and `slice_chars`. - #[unstable = "use slice notation [..a] instead"] + /// Deprecated: use `s[..a]` instead. + #[deprecated = "use slice notation [..a] instead"] fn slice_to(&self, end: uint) -> &str { core_str::StrExt::slice_to(&self[], end) } diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 5d35d8a86795..4a73757baf97 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -848,6 +848,7 @@ impl<'a> Add<&'a str> for String { } } +#[stable] impl ops::Index> for String { type Output = str; #[inline] @@ -855,6 +856,7 @@ impl ops::Index> for String { &self[][*index] } } +#[stable] impl ops::Index> for String { type Output = str; #[inline] @@ -862,6 +864,7 @@ impl ops::Index> for String { &self[][*index] } } +#[stable] impl ops::Index> for String { type Output = str; #[inline] @@ -869,6 +872,7 @@ impl ops::Index> for String { &self[][*index] } } +#[stable] impl ops::Index for String { type Output = str; #[inline] diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 50cbb7a61dce..f02804ad9d19 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -67,9 +67,6 @@ use raw::Slice as RawSlice; pub trait SliceExt { type Item; - fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [Self::Item]; - fn slice_from<'a>(&'a self, start: uint) -> &'a [Self::Item]; - fn slice_to<'a>(&'a self, end: uint) -> &'a [Self::Item]; fn split_at<'a>(&'a self, mid: uint) -> (&'a [Self::Item], &'a [Self::Item]); fn iter<'a>(&'a self) -> Iter<'a, Self::Item>; fn split<'a, P>(&'a self, pred: P) -> Split<'a, Self::Item, P> @@ -93,9 +90,6 @@ pub trait SliceExt { fn is_empty(&self) -> bool { self.len() == 0 } fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut Self::Item>; fn as_mut_slice<'a>(&'a mut self) -> &'a mut [Self::Item]; - fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [Self::Item]; - fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [Self::Item]; - fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [Self::Item]; fn iter_mut<'a>(&'a mut self) -> IterMut<'a, Self::Item>; fn first_mut<'a>(&'a mut self) -> Option<&'a mut Self::Item>; fn tail_mut<'a>(&'a mut self) -> &'a mut [Self::Item]; @@ -135,28 +129,6 @@ pub trait SliceExt { impl SliceExt for [T] { type Item = T; - #[inline] - fn slice(&self, start: uint, end: uint) -> &[T] { - assert!(start <= end); - assert!(end <= self.len()); - unsafe { - transmute(RawSlice { - data: self.as_ptr().offset(start as int), - len: (end - start) - }) - } - } - - #[inline] - fn slice_from(&self, start: uint) -> &[T] { - self.slice(start, self.len()) - } - - #[inline] - fn slice_to(&self, end: uint) -> &[T] { - self.slice(0, end) - } - #[inline] fn split_at(&self, mid: uint) -> (&[T], &[T]) { (&self[..mid], &self[mid..]) @@ -291,20 +263,6 @@ impl SliceExt for [T] { #[inline] fn as_mut_slice(&mut self) -> &mut [T] { self } - fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T] { - ops::IndexMut::index_mut(self, &ops::Range { start: start, end: end } ) - } - - #[inline] - fn slice_from_mut(&mut self, start: uint) -> &mut [T] { - ops::IndexMut::index_mut(self, &ops::RangeFrom { start: start } ) - } - - #[inline] - fn slice_to_mut(&mut self, end: uint) -> &mut [T] { - ops::IndexMut::index_mut(self, &ops::RangeTo { end: end } ) - } - #[inline] fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]) { unsafe { @@ -345,13 +303,13 @@ impl SliceExt for [T] { #[inline] fn tail_mut(&mut self) -> &mut [T] { - self.slice_from_mut(1) + &mut self[1 ..] } #[inline] fn init_mut(&mut self) -> &mut [T] { let len = self.len(); - self.slice_to_mut(len-1) + &mut self[.. (len - 1)] } #[inline] @@ -483,7 +441,7 @@ impl SliceExt for [T] { self.swap(j, i-1); // Step 4: Reverse the (previously) weakly decreasing part - self.slice_from_mut(i).reverse(); + self[i..].reverse(); true } @@ -505,7 +463,7 @@ impl SliceExt for [T] { } // Step 2: Reverse the weakly increasing part - self.slice_from_mut(i).reverse(); + self[i..].reverse(); // Step 3: Find the rightmost element equal to or bigger than the pivot (i-1) let mut j = self.len() - 1; @@ -522,8 +480,8 @@ impl SliceExt for [T] { #[inline] fn clone_from_slice(&mut self, src: &[T]) -> uint where T: Clone { let min = cmp::min(self.len(), src.len()); - let dst = self.slice_to_mut(min); - let src = src.slice_to(min); + let dst = &mut self[.. min]; + let src = &src[.. min]; for i in range(0, min) { dst[i].clone_from(&src[i]); } @@ -531,6 +489,7 @@ impl SliceExt for [T] { } } +#[stable] impl ops::Index for [T] { type Output = T; @@ -541,6 +500,7 @@ impl ops::Index for [T] { } } +#[stable] impl ops::IndexMut for [T] { type Output = T; @@ -551,6 +511,7 @@ impl ops::IndexMut for [T] { } } +#[stable] impl ops::Index> for [T] { type Output = [T]; #[inline] @@ -565,6 +526,7 @@ impl ops::Index> for [T] { } } } +#[stable] impl ops::Index> for [T] { type Output = [T]; #[inline] @@ -572,6 +534,7 @@ impl ops::Index> for [T] { self.index(&ops::Range{ start: 0, end: index.end }) } } +#[stable] impl ops::Index> for [T] { type Output = [T]; #[inline] @@ -579,6 +542,7 @@ impl ops::Index> for [T] { self.index(&ops::Range{ start: index.start, end: self.len() }) } } +#[stable] impl ops::Index for [T] { type Output = [T]; #[inline] @@ -587,6 +551,7 @@ impl ops::Index for [T] { } } +#[stable] impl ops::IndexMut> for [T] { type Output = [T]; #[inline] @@ -601,6 +566,7 @@ impl ops::IndexMut> for [T] { } } } +#[stable] impl ops::IndexMut> for [T] { type Output = [T]; #[inline] @@ -608,6 +574,7 @@ impl ops::IndexMut> for [T] { self.index_mut(&ops::Range{ start: 0, end: index.end }) } } +#[stable] impl ops::IndexMut> for [T] { type Output = [T]; #[inline] @@ -616,6 +583,7 @@ impl ops::IndexMut> for [T] { self.index_mut(&ops::Range{ start: index.start, end: len }) } } +#[stable] impl ops::IndexMut for [T] { type Output = [T]; #[inline] @@ -1051,7 +1019,7 @@ impl<'a, T, P> Iterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { Some(idx) => { let tmp = mem::replace(&mut self.v, &mut []); let (head, tail) = tmp.split_at_mut(idx); - self.v = tail.slice_from_mut(1); + self.v = &mut tail[1..]; Some(head) } } @@ -1087,7 +1055,7 @@ impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P> where let tmp = mem::replace(&mut self.v, &mut []); let (head, tail) = tmp.split_at_mut(idx); self.v = head; - Some(tail.slice_from_mut(1)) + Some(&mut tail[1..]) } } } diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 6a542b2c4588..42034a8bd701 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -902,13 +902,13 @@ impl<'a> Iterator for SplitStr<'a> { match self.it.next() { Some((from, to)) => { - let ret = Some(self.it.haystack.slice(self.last_end, from)); + let ret = Some(&self.it.haystack[self.last_end .. from]); self.last_end = to; ret } None => { self.finished = true; - Some(self.it.haystack.slice(self.last_end, self.it.haystack.len())) + Some(&self.it.haystack[self.last_end .. self.it.haystack.len()]) } } } @@ -1115,27 +1115,90 @@ mod traits { } } + /// Returns a slice of the given string from the byte range + /// [`begin`..`end`). + /// + /// This operation is `O(1)`. + /// + /// Panics when `begin` and `end` do not point to valid characters + /// or point beyond the last character of the string. + /// + /// # Example + /// + /// ```rust + /// let s = "Löwe 老虎 Léopard"; + /// assert_eq!(&s[0 .. 1], "L"); + /// + /// assert_eq!(&s[1 .. 9], "öwe 老"); + /// + /// // these will panic: + /// // byte 2 lies within `ö`: + /// // &s[2 ..3]; + /// + /// // byte 8 lies within `老` + /// // &s[1 .. 8]; + /// + /// // byte 100 is outside the string + /// // &s[3 .. 100]; + /// ``` + #[stable] impl ops::Index> for str { type Output = str; #[inline] fn index(&self, index: &ops::Range) -> &str { - self.slice(index.start, index.end) + // is_char_boundary checks that the index is in [0, .len()] + if index.start <= index.end && + self.is_char_boundary(index.start) && + self.is_char_boundary(index.end) { + unsafe { self.slice_unchecked(index.start, index.end) } + } else { + super::slice_error_fail(self, index.start, index.end) + } } } + + /// Returns a slice of the string from the beginning to byte + /// `end`. + /// + /// Equivalent to `self[0 .. end]`. + /// + /// Panics when `end` does not point to a valid character, or is + /// out of bounds. + #[stable] impl ops::Index> for str { type Output = str; #[inline] fn index(&self, index: &ops::RangeTo) -> &str { - self.slice_to(index.end) + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(index.end) { + unsafe { self.slice_unchecked(0, index.end) } + } else { + super::slice_error_fail(self, 0, index.end) + } } } + + /// Returns a slice of the string from `begin` to its end. + /// + /// Equivalent to `self[begin .. self.len()]`. + /// + /// Panics when `begin` does not point to a valid character, or is + /// out of bounds. + #[stable] impl ops::Index> for str { type Output = str; #[inline] fn index(&self, index: &ops::RangeFrom) -> &str { - self.slice_from(index.start) + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(index.start) { + unsafe { self.slice_unchecked(index.start, self.len()) } + } else { + super::slice_error_fail(self, index.start, self.len()) + } } } + + #[stable] impl ops::Index for str { type Output = str; #[inline] @@ -1208,9 +1271,6 @@ pub trait StrExt { fn lines<'a>(&'a self) -> Lines<'a>; fn lines_any<'a>(&'a self) -> LinesAny<'a>; fn char_len(&self) -> uint; - fn slice<'a>(&'a self, begin: uint, end: uint) -> &'a str; - fn slice_from<'a>(&'a self, begin: uint) -> &'a str; - fn slice_to<'a>(&'a self, end: uint) -> &'a str; fn slice_chars<'a>(&'a self, begin: uint, end: uint) -> &'a str; unsafe fn slice_unchecked<'a>(&'a self, begin: uint, end: uint) -> &'a str; fn starts_with(&self, pat: &str) -> bool; @@ -1332,7 +1392,7 @@ impl StrExt for str { fn lines_any(&self) -> LinesAny { fn f(line: &str) -> &str { let l = line.len(); - if l > 0 && line.as_bytes()[l - 1] == b'\r' { line.slice(0, l - 1) } + if l > 0 && line.as_bytes()[l - 1] == b'\r' { &line[0 .. l - 1] } else { line } } @@ -1343,38 +1403,6 @@ impl StrExt for str { #[inline] fn char_len(&self) -> uint { self.chars().count() } - #[inline] - fn slice(&self, begin: uint, end: uint) -> &str { - // is_char_boundary checks that the index is in [0, .len()] - if begin <= end && - self.is_char_boundary(begin) && - self.is_char_boundary(end) { - unsafe { self.slice_unchecked(begin, end) } - } else { - slice_error_fail(self, begin, end) - } - } - - #[inline] - fn slice_from(&self, begin: uint) -> &str { - // is_char_boundary checks that the index is in [0, .len()] - if self.is_char_boundary(begin) { - unsafe { self.slice_unchecked(begin, self.len()) } - } else { - slice_error_fail(self, begin, self.len()) - } - } - - #[inline] - fn slice_to(&self, end: uint) -> &str { - // is_char_boundary checks that the index is in [0, .len()] - if self.is_char_boundary(end) { - unsafe { self.slice_unchecked(0, end) } - } else { - slice_error_fail(self, 0, end) - } - } - fn slice_chars(&self, begin: uint, end: uint) -> &str { assert!(begin <= end); let mut count = 0; From a506d4cbfe8f20a2725c7efd9d43359a0bbd0e9e Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Sat, 17 Jan 2015 16:15:52 -0800 Subject: [PATCH 3/5] Fallout from stabilization. --- src/compiletest/header.rs | 3 +- src/compiletest/runtest.rs | 4 +-- src/doc/intro.md | 4 +-- src/libcollections/btree/node.rs | 21 +++++++------ src/libcollections/ring_buf.rs | 2 +- src/libcollections/slice.rs | 2 +- src/libcollections/str.rs | 26 +++++++++------- src/libcore/fmt/float.rs | 4 +-- src/librand/chacha.rs | 3 +- src/librbml/io.rs | 2 +- src/libregex/re.rs | 2 +- src/librustc/metadata/cstore.rs | 2 +- src/librustc/metadata/loader.rs | 4 +-- src/librustc/middle/cfg/construct.rs | 2 +- src/librustc/middle/dataflow.rs | 30 +++++++++---------- .../middle/infer/region_inference/mod.rs | 5 ++-- src/librustc/middle/subst.rs | 4 +-- src/librustc/session/search_paths.rs | 8 ++--- src/librustc_borrowck/borrowck/check_loans.rs | 2 +- src/librustc_trans/back/link.rs | 2 +- src/librustc_trans/save/mod.rs | 4 +-- src/librustc_trans/trans/debuginfo.rs | 5 ++-- src/librustc_trans/trans/meth.rs | 4 +-- src/librustc_typeck/astconv.rs | 8 ++--- src/librustc_typeck/check/regionck.rs | 2 +- src/librustc_typeck/coherence/overlap.rs | 2 +- src/librustdoc/html/escape.rs | 4 +-- src/librustdoc/html/markdown.rs | 2 +- src/librustdoc/html/render.rs | 4 +-- src/librustdoc/markdown.rs | 4 +-- src/librustdoc/passes.rs | 2 +- src/libstd/ffi/c_str.rs | 2 +- src/libstd/io/buffered.rs | 2 +- src/libstd/io/comm_adapters.rs | 4 +-- src/libstd/io/mem.rs | 10 +++---- src/libstd/io/mod.rs | 4 +-- src/libstd/io/net/ip.rs | 2 +- src/libstd/io/util.rs | 2 +- src/libstd/num/strconv.rs | 4 +-- src/libstd/rand/os.rs | 2 +- src/libstd/rt/util.rs | 2 +- src/libstd/sys/common/backtrace.rs | 16 +++++----- src/libstd/sys/unix/process.rs | 4 +-- src/libstd/sys/windows/fs.rs | 2 +- src/libstd/sys/windows/os.rs | 2 +- src/libsyntax/parse/lexer/mod.rs | 6 ++-- src/libsyntax/parse/parser.rs | 2 +- src/libsyntax/print/pprust.rs | 4 +-- src/libunicode/u_str.rs | 8 ++--- 49 files changed, 126 insertions(+), 125 deletions(-) diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index 2413a001ee80..d7af767688e8 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -332,8 +332,7 @@ pub fn parse_name_value_directive(line: &str, directive: &str) let keycolon = format!("{}:", directive); match line.find_str(keycolon.as_slice()) { Some(colon) => { - let value = line.slice(colon + keycolon.len(), - line.len()).to_string(); + let value = line[(colon + keycolon.len()) .. line.len()].to_string(); debug!("{}: {}", directive, value); Some(value) } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 5579479c5e5a..8936c20cefdf 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -862,7 +862,7 @@ fn check_debugger_output(debugger_run_result: &ProcRes, check_lines: &[String]) break; } Some(i) => { - rest = rest.slice_from(i + frag.len()); + rest = &rest[(i + frag.len())..]; } } first = false; @@ -1045,7 +1045,7 @@ fn scan_until_char(haystack: &str, needle: char, idx: &mut uint) -> bool { if *idx >= haystack.len() { return false; } - let opt = haystack.slice_from(*idx).find(needle); + let opt = haystack[(*idx)..].find(needle); if opt.is_none() { return false; } diff --git a/src/doc/intro.md b/src/doc/intro.md index 3487738467fb..a7c37ba8e07e 100644 --- a/src/doc/intro.md +++ b/src/doc/intro.md @@ -485,9 +485,9 @@ fn main() { Thread::spawn(move || { let mut array = number.lock().unwrap(); - (*array)[i] += 1; + array[i as usize] += 1; - println!("numbers[{}] is {}", i, (*array)[i]); + println!("numbers[{}] is {}", i, array[i as usize]); }); } } diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index fa8906430894..50857c78469c 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -21,7 +21,7 @@ use core::prelude::*; use core::borrow::BorrowFrom; use core::cmp::Ordering::{Greater, Less, Equal}; use core::iter::Zip; -use core::ops::{Deref, DerefMut}; +use core::ops::{Deref, DerefMut, Index, IndexMut}; use core::ptr::Unique; use core::{slice, mem, ptr, cmp, num, raw}; use alloc::heap; @@ -1487,7 +1487,7 @@ impl AbsTraversal macro_rules! node_slice_impl { ($NodeSlice:ident, $Traversal:ident, - $as_slices_internal:ident, $slice_from:ident, $slice_to:ident, $iter:ident) => { + $as_slices_internal:ident, $index:ident, $iter:ident) => { impl<'a, K: Ord + 'a, V: 'a> $NodeSlice<'a, K, V> { /// Performs linear search in a slice. Returns a tuple of (index, is_exact_match). fn search_linear(&self, key: &Q) -> (uint, bool) @@ -1521,10 +1521,10 @@ macro_rules! node_slice_impl { edges: if !self.has_edges { self.edges } else { - self.edges.$slice_from(pos) + self.edges.$index(&(pos ..)) }, - keys: self.keys.slice_from(pos), - vals: self.vals.$slice_from(pos), + keys: &self.keys[pos ..], + vals: self.vals.$index(&(pos ..)), head_is_edge: !pos_is_kv, tail_is_edge: self.tail_is_edge, } @@ -1550,10 +1550,10 @@ macro_rules! node_slice_impl { edges: if !self.has_edges { self.edges } else { - self.edges.$slice_to(pos + 1) + self.edges.$index(&(.. (pos + 1))) }, - keys: self.keys.slice_to(pos), - vals: self.vals.$slice_to(pos), + keys: &self.keys[..pos], + vals: self.vals.$index(&(.. pos)), head_is_edge: self.head_is_edge, tail_is_edge: !pos_is_kv, } @@ -1583,6 +1583,5 @@ macro_rules! node_slice_impl { } } -node_slice_impl!(NodeSlice, Traversal, as_slices_internal, slice_from, slice_to, iter); -node_slice_impl!(MutNodeSlice, MutTraversal, as_slices_internal_mut, slice_from_mut, - slice_to_mut, iter_mut); +node_slice_impl!(NodeSlice, Traversal, as_slices_internal, index, iter); +node_slice_impl!(MutNodeSlice, MutTraversal, as_slices_internal_mut, index_mut, iter_mut); diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs index b9cb4be7c189..69d64bcdf6d5 100644 --- a/src/libcollections/ring_buf.rs +++ b/src/libcollections/ring_buf.rs @@ -578,7 +578,7 @@ impl RingBuf { if contiguous { let (empty, buf) = buf.split_at_mut(0); - (buf.slice_mut(tail, head), empty) + (&mut buf[tail .. head], empty) } else { let (mid, right) = buf.split_at_mut(tail); let (left, _) = mid.split_at_mut(head); diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index a640e4ee0e34..16e5a89f343b 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -686,7 +686,7 @@ impl SliceExt for [T] { #[inline] fn move_from(&mut self, mut src: Vec, start: uint, end: uint) -> uint { - for (a, b) in self.iter_mut().zip(src.slice_mut(start, end).iter_mut()) { + for (a, b) in self.iter_mut().zip(src[start .. end].iter_mut()) { mem::swap(a, b); } cmp::min(self.len(), end-start) diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 94554fd1e81d..6608d0ee9a7e 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -752,21 +752,15 @@ pub trait StrExt: Index { /// Deprecated: use `s[a .. b]` instead. #[deprecated = "use slice notation [a..b] instead"] - fn slice(&self, begin: uint, end: uint) -> &str { - core_str::StrExt::slice(&self[], begin, end) - } + fn slice(&self, begin: uint, end: uint) -> &str; /// Deprecated: use `s[a..]` instead. #[deprecated = "use slice notation [a..] instead"] - fn slice_from(&self, begin: uint) -> &str { - core_str::StrExt::slice_from(&self[], begin) - } + fn slice_from(&self, begin: uint) -> &str; /// Deprecated: use `s[..a]` instead. #[deprecated = "use slice notation [..a] instead"] - fn slice_to(&self, end: uint) -> &str { - core_str::StrExt::slice_to(&self[], end) - } + fn slice_to(&self, end: uint) -> &str; /// Returns a slice of the string from the character range /// [`begin`..`end`). @@ -1304,7 +1298,19 @@ pub trait StrExt: Index { } #[stable] -impl StrExt for str {} +impl StrExt for str { + fn slice(&self, begin: uint, end: uint) -> &str { + &self[begin..end] + } + + fn slice_from(&self, begin: uint) -> &str { + &self[begin..] + } + + fn slice_to(&self, end: uint) -> &str { + &self[..end] + } +} #[cfg(test)] mod tests { diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index f1b9ebe6d905..245dc00d8382 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -179,7 +179,7 @@ pub fn float_to_str_bytes_common( _ => () } - buf.slice_to_mut(end).reverse(); + buf[..end].reverse(); // Remember start of the fractional digits. // Points one beyond end of buf if none get generated, @@ -316,7 +316,7 @@ pub fn float_to_str_bytes_common( impl<'a> fmt::Writer for Filler<'a> { fn write_str(&mut self, s: &str) -> fmt::Result { - slice::bytes::copy_memory(self.buf.slice_from_mut(*self.end), + slice::bytes::copy_memory(&mut self.buf[(*self.end)..], s.as_bytes()); *self.end += s.len(); Ok(()) diff --git a/src/librand/chacha.rs b/src/librand/chacha.rs index 815fc0e7ec7a..3332e06e19e7 100644 --- a/src/librand/chacha.rs +++ b/src/librand/chacha.rs @@ -174,7 +174,7 @@ impl<'a> SeedableRng<&'a [u32]> for ChaChaRng { // reset state self.init(&[0u32; KEY_WORDS]); // set key in place - let key = self.state.slice_mut(4, 4+KEY_WORDS); + let key = &mut self.state[4 .. 4+KEY_WORDS]; for (k, s) in key.iter_mut().zip(seed.iter()) { *k = *s; } @@ -292,4 +292,3 @@ mod test { } } } - diff --git a/src/librbml/io.rs b/src/librbml/io.rs index f39860c8695c..9c746c69baaf 100644 --- a/src/librbml/io.rs +++ b/src/librbml/io.rs @@ -103,7 +103,7 @@ impl Writer for SeekableMemWriter { // Do the necessary writes if left.len() > 0 { - slice::bytes::copy_memory(self.buf.slice_from_mut(self.pos), left); + slice::bytes::copy_memory(&mut self.buf[self.pos..], left); } if right.len() > 0 { self.buf.push_all(right); diff --git a/src/libregex/re.rs b/src/libregex/re.rs index abc51d624040..3cdc0be45a60 100644 --- a/src/libregex/re.rs +++ b/src/libregex/re.rs @@ -459,7 +459,7 @@ impl<'t> Captures<'t> { pub fn at(&self, i: uint) -> Option<&'t str> { match self.pos(i) { None => None, - Some((s, e)) => Some(self.text.slice(s, e)) + Some((s, e)) => Some(&self.text[s.. e]) } } diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index a928d1c90228..7b7159da4385 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -242,7 +242,7 @@ impl MetadataBlob { ((slice[2] as u32) << 8) | ((slice[3] as u32) << 0)) as uint; if len + 4 <= slice.len() { - slice.slice(4, len + 4) + &slice[4.. len + 4] } else { &[] // corrupt or old metadata } diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 70b6ddf23fd8..b1043a4152cf 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -392,11 +392,11 @@ impl<'a> Context<'a> { }; let (hash, rlib) = if file.starts_with(&rlib_prefix[]) && file.ends_with(".rlib") { - (file.slice(rlib_prefix.len(), file.len() - ".rlib".len()), + (&file[(rlib_prefix.len()) .. (file.len() - ".rlib".len())], true) } else if file.starts_with(dylib_prefix.as_slice()) && file.ends_with(dypair.1.as_slice()) { - (file.slice(dylib_prefix.len(), file.len() - dypair.1.len()), + (&file[(dylib_prefix.len()) .. (file.len() - dypair.1.len())], false) } else { return FileDoesntMatch diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index a1ac25a5650e..1a2162b3076e 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -424,7 +424,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { } ast::ExprMethodCall(_, _, ref args) => { - self.call(expr, pred, &*args[0], args.slice_from(1).iter().map(|e| &**e)) + self.call(expr, pred, &*args[0], args[1..].iter().map(|e| &**e)) } ast::ExprIndex(ref l, ref r) | diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 2b9bd1cd09fd..a17278698103 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -118,17 +118,17 @@ impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O assert!(self.bits_per_id > 0); let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index); let (start, end) = self.compute_id_range(cfgidx); - let on_entry = self.on_entry.slice(start, end); + let on_entry = &self.on_entry[start.. end]; let entry_str = bits_to_string(on_entry); - let gens = self.gens.slice(start, end); + let gens = &self.gens[start.. end]; let gens_str = if gens.iter().any(|&u| u != 0) { format!(" gen: {}", bits_to_string(gens)) } else { "".to_string() }; - let kills = self.kills.slice(start, end); + let kills = &self.kills[start .. end]; let kills_str = if kills.iter().any(|&u| u != 0) { format!(" kill: {}", bits_to_string(kills)) } else { @@ -232,7 +232,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index); let (start, end) = self.compute_id_range(cfgidx); - let gens = self.gens.slice_mut(start, end); + let gens = &mut self.gens[start.. end]; set_bit(gens, bit); } @@ -245,7 +245,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index); let (start, end) = self.compute_id_range(cfgidx); - let kills = self.kills.slice_mut(start, end); + let kills = &mut self.kills[start.. end]; set_bit(kills, bit); } @@ -256,9 +256,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { assert!(self.bits_per_id > 0); let (start, end) = self.compute_id_range(cfgidx); - let gens = self.gens.slice(start, end); + let gens = &self.gens[start.. end]; bitwise(bits, gens, &Union); - let kills = self.kills.slice(start, end); + let kills = &self.kills[start.. end]; bitwise(bits, kills, &Subtract); debug!("{} apply_gen_kill(cfgidx={:?}, bits={}) [after]", @@ -304,7 +304,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { } let (start, end) = self.compute_id_range(cfgidx); - let on_entry = self.on_entry.slice(start, end); + let on_entry = &self.on_entry[start.. end]; let temp_bits; let slice = match e { Entry => on_entry, @@ -336,7 +336,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index); let (start, end) = self.compute_id_range(cfgidx); - let gens = self.gens.slice(start, end); + let gens = &self.gens[start.. end]; debug!("{} each_gen_bit(id={}, gens={})", self.analysis_name, id, bits_to_string(gens)); self.each_bit(gens, f) @@ -396,7 +396,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { cfg.graph.each_edge(|_edge_index, edge| { let flow_exit = edge.source(); let (start, end) = self.compute_id_range(flow_exit); - let mut orig_kills = self.kills.slice(start, end).to_vec(); + let mut orig_kills = self.kills[start.. end].to_vec(); let mut changed = false; for &node_id in edge.data.exiting_scopes.iter() { @@ -404,7 +404,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { match opt_cfg_idx { Some(cfg_idx) => { let (start, end) = self.compute_id_range(cfg_idx); - let kills = self.kills.slice(start, end); + let kills = &self.kills[start.. end]; if bitwise(orig_kills.as_mut_slice(), kills, &Union) { changed = true; } @@ -418,7 +418,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { } if changed { - let bits = self.kills.slice_mut(start, end); + let bits = &mut self.kills[start.. end]; debug!("{} add_kills_from_flow_exits flow_exit={:?} bits={} [before]", self.analysis_name, flow_exit, mut_bits_to_string(bits)); bits.clone_from_slice(&orig_kills[]); @@ -487,7 +487,7 @@ impl<'a, 'b, 'tcx, O:DataFlowOperator> PropagationContext<'a, 'b, 'tcx, O> { let (start, end) = self.dfcx.compute_id_range(node_index); // Initialize local bitvector with state on-entry. - in_out.clone_from_slice(self.dfcx.on_entry.slice(start, end)); + in_out.clone_from_slice(&self.dfcx.on_entry[start.. end]); // Compute state on-exit by applying transfer function to // state on-entry. @@ -528,13 +528,13 @@ impl<'a, 'b, 'tcx, O:DataFlowOperator> PropagationContext<'a, 'b, 'tcx, O> { let (start, end) = self.dfcx.compute_id_range(cfgidx); let changed = { // (scoping mutable borrow of self.dfcx.on_entry) - let on_entry = self.dfcx.on_entry.slice_mut(start, end); + let on_entry = &mut self.dfcx.on_entry[start.. end]; bitwise(on_entry, pred_bits, &self.dfcx.oper) }; if changed { debug!("{} changed entry set for {:?} to {}", self.dfcx.analysis_name, cfgidx, - bits_to_string(self.dfcx.on_entry.slice(start, end))); + bits_to_string(&self.dfcx.on_entry[start.. end])); self.changed = true; } } diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs index 0f487fffe5cb..9339f435d8fa 100644 --- a/src/librustc/middle/infer/region_inference/mod.rs +++ b/src/librustc/middle/infer/region_inference/mod.rs @@ -609,8 +609,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { pub fn vars_created_since_snapshot(&self, mark: &RegionSnapshot) -> Vec { - self.undo_log.borrow() - .slice_from(mark.length) + self.undo_log.borrow()[mark.length..] .iter() .filter_map(|&elt| match elt { AddVar(vid) => Some(vid), @@ -637,7 +636,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { debug!("result_index={}, r={:?}", result_index, r); for undo_entry in - self.undo_log.borrow().slice_from(mark.length).iter() + self.undo_log.borrow()[mark.length..].iter() { match undo_entry { &AddConstraint(ConstrainVarSubVar(a, b)) => { diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs index 9ad2dd499cc9..031eb26300f2 100644 --- a/src/librustc/middle/subst.rs +++ b/src/librustc/middle/subst.rs @@ -373,12 +373,12 @@ impl VecPerParamSpace { pub fn get_slice<'a>(&'a self, space: ParamSpace) -> &'a [T] { let (start, limit) = self.limits(space); - self.content.slice(start, limit) + &self.content[start.. limit] } pub fn get_mut_slice<'a>(&'a mut self, space: ParamSpace) -> &'a mut [T] { let (start, limit) = self.limits(space); - self.content.slice_mut(start, limit) + &mut self.content[start.. limit] } pub fn opt_get<'a>(&'a self, diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs index 0cf04fe0a006..dfc27d3ae684 100644 --- a/src/librustc/session/search_paths.rs +++ b/src/librustc/session/search_paths.rs @@ -36,13 +36,13 @@ impl SearchPaths { pub fn add_path(&mut self, path: &str) { let (kind, path) = if path.starts_with("native=") { - (PathKind::Native, path.slice_from("native=".len())) + (PathKind::Native, &path["native=".len()..]) } else if path.starts_with("crate=") { - (PathKind::Crate, path.slice_from("crate=".len())) + (PathKind::Crate, &path["crate=".len()..]) } else if path.starts_with("dependency=") { - (PathKind::Dependency, path.slice_from("dependency=".len())) + (PathKind::Dependency, &path["dependency=".len()..]) } else if path.starts_with("all=") { - (PathKind::All, path.slice_from("all=".len())) + (PathKind::All, &path["all=".len()..]) } else { (PathKind::All, path) }; diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index d5ad201eabfa..0ade916f6390 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -370,7 +370,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { for (i, &x) in new_loan_indices.iter().enumerate() { let old_loan = &self.all_loans[x]; - for &y in new_loan_indices.slice_from(i+1).iter() { + for &y in new_loan_indices[(i+1) ..].iter() { let new_loan = &self.all_loans[y]; self.report_error_if_loans_conflict(old_loan, new_loan); } diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index dacf620cbd1d..efa948f09426 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -178,7 +178,7 @@ pub fn build_link_meta(sess: &Session, krate: &ast::Crate, fn truncated_hash_result(symbol_hasher: &mut Sha256) -> String { let output = symbol_hasher.result_bytes(); // 64 bits should be enough to avoid collisions. - output.slice_to(8).to_hex().to_string() + output[.. 8].to_hex().to_string() } diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index b12903c814cb..c765698fc0cd 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -157,7 +157,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { return; } - let sub_paths = sub_paths.slice(0, len-1); + let sub_paths = &sub_paths[.. (len-1)]; for &(ref span, ref qualname) in sub_paths.iter() { self.fmt.sub_mod_ref_str(path.span, *span, @@ -174,7 +174,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { if len <= 1 { return; } - let sub_paths = sub_paths.slice_to(len-1); + let sub_paths = &sub_paths[.. (len-1)]; // write the trait part of the sub-path let (ref span, ref qualname) = sub_paths[len-2]; diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 2f01f0328e28..7d0ff5f2adc2 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -1615,8 +1615,8 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor { let prefix: &[u8] = &[dotdot[0], ::std::path::SEP_BYTE]; let mut path_bytes = p.as_vec().to_vec(); - if path_bytes.slice_to(2) != prefix && - path_bytes.slice_to(2) != dotdot { + if &path_bytes[..2] != prefix && + &path_bytes[..2] != dotdot { path_bytes.insert(0, prefix[0]); path_bytes.insert(1, prefix[1]); } @@ -4122,4 +4122,3 @@ fn needs_gdb_debug_scripts_section(ccx: &CrateContext) -> bool { !ccx.sess().target.target.options.is_like_windows && ccx.sess().opts.debuginfo != NoDebugInfo } - diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index 0fb0dffe930f..2a893a6cfdfe 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -494,7 +494,7 @@ pub fn trans_trait_callee_from_llval<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ty::ty_bare_fn(_, ref f) if f.abi == Rust || f.abi == RustCall => { let fake_sig = ty::Binder(ty::FnSig { - inputs: f.sig.0.inputs.slice_from(1).to_vec(), + inputs: f.sig.0.inputs[1..].to_vec(), output: f.sig.0.output, variadic: f.sig.0.variadic, }); @@ -634,7 +634,7 @@ pub fn trans_object_shim<'a, 'tcx>( } _ => { // skip the self parameter: - sig.inputs.slice_from(1) + &sig.inputs[1..] } }; diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 42b12c158664..428c5680a48f 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1321,7 +1321,7 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>, // HACK(eddyb) replace the fake self type in the AST with the actual type. let input_params = if self_ty.is_some() { - decl.inputs.slice_from(1) + &decl.inputs[1..] } else { &decl.inputs[] }; @@ -1339,9 +1339,9 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>, let lifetimes_for_params = if implied_output_region.is_none() { let input_tys = if self_ty.is_some() { // Skip the first argument if `self` is present. - self_and_input_tys.slice_from(1) + &self_and_input_tys[1..] } else { - self_and_input_tys.slice_from(0) + &self_and_input_tys[] }; let (ior, lfp) = find_implied_output_region(input_tys, input_pats); @@ -1665,7 +1665,7 @@ fn compute_opt_region_bound<'tcx>(tcx: &ty::ctxt<'tcx>, // of derived region bounds. If so, use that. Otherwise, report an // error. let r = derived_region_bounds[0]; - if derived_region_bounds.slice_from(1).iter().any(|r1| r != *r1) { + if derived_region_bounds[1..].iter().any(|r1| r != *r1) { tcx.sess.span_err( span, &format!("ambiguous lifetime bound, \ diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 3b5027dbb9e6..e4b28bf5648c 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -531,7 +531,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { ast::ExprMethodCall(_, _, ref args) => { constrain_call(rcx, expr, Some(&*args[0]), - args.slice_from(1).iter().map(|e| &**e), false); + args[1..].iter().map(|e| &**e), false); visit::walk_expr(rcx, expr); } diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index ce7ba9ac11e6..a7bad3dc789a 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -65,7 +65,7 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> { continue; } - for &impl2_def_id in trait_impls.slice_from(i+1).iter() { + for &impl2_def_id in trait_impls[(i+1)..].iter() { self.check_if_impls_overlap(trait_def_id, impl1_def_id, impl2_def_id); diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs index 6fb78d9a8334..db7253c9ef3d 100644 --- a/src/librustdoc/html/escape.rs +++ b/src/librustdoc/html/escape.rs @@ -29,7 +29,7 @@ impl<'a> fmt::String for Escape<'a> { for (i, ch) in s.bytes().enumerate() { match ch as char { '<' | '>' | '&' | '\'' | '"' => { - try!(fmt.write_str(pile_o_bits.slice(last, i))); + try!(fmt.write_str(&pile_o_bits[last.. i])); let s = match ch as char { '>' => ">", '<' => "<", @@ -46,7 +46,7 @@ impl<'a> fmt::String for Escape<'a> { } if last < s.len() { - try!(fmt.write_str(pile_o_bits.slice_from(last))); + try!(fmt.write_str(&pile_o_bits[last..])); } Ok(()) } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 0dbd13b4616b..1c800771c70b 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -146,7 +146,7 @@ extern { fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> { let trimmed = s.trim(); if trimmed.starts_with("# ") { - Some(trimmed.slice_from(2)) + Some(&trimmed[2..]) } else { None } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index ab9700d966aa..ea535a1490b0 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -749,7 +749,7 @@ impl<'a> SourceCollector<'a> { // Remove the utf-8 BOM if any let contents = if contents.starts_with("\u{feff}") { - contents.slice_from(3) + &contents[3..] } else { contents }; @@ -1469,7 +1469,7 @@ fn full_path(cx: &Context, item: &clean::Item) -> String { fn shorter<'a>(s: Option<&'a str>) -> &'a str { match s { Some(s) => match s.find_str("\n\n") { - Some(pos) => s.slice_to(pos), + Some(pos) => &s[..pos], None => s, }, None => "" diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index dc98a56eb1a4..594cf3dcd439 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -28,10 +28,10 @@ fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) { for line in s.lines() { if line.starts_with("%") { // remove % - metadata.push(line.slice_from(1).trim_left()) + metadata.push(line[1..].trim_left()) } else { let line_start_byte = s.subslice_offset(line); - return (metadata, s.slice_from(line_start_byte)); + return (metadata, &s[line_start_byte..]); } } // if we're here, then all lines were metadata % lines. diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs index 9a67b479106e..34a23774e5b1 100644 --- a/src/librustdoc/passes.rs +++ b/src/librustdoc/passes.rs @@ -357,7 +357,7 @@ pub fn unindent(s: &str) -> String { line.to_string() } else { assert!(line.len() >= min_indent); - line.slice_from(min_indent).to_string() + line[min_indent..].to_string() } }).collect::>().as_slice()); unindented.connect("\n") diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index d7f8eb2e4158..6d6aaac22a24 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -115,7 +115,7 @@ impl Deref for CString { type Target = [libc::c_char]; fn deref(&self) -> &[libc::c_char] { - self.inner.slice_to(self.inner.len() - 1) + &self.inner[..(self.inner.len() - 1)] } } diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 8c38bc009cc6..2b293d6eef28 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -219,7 +219,7 @@ impl Writer for BufferedWriter { if buf.len() > self.buf.len() { self.inner.as_mut().unwrap().write(buf) } else { - let dst = self.buf.slice_from_mut(self.pos); + let dst = &mut self.buf[self.pos..]; slice::bytes::copy_memory(dst, buf); self.pos += buf.len(); Ok(()) diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs index 4b0014c68f7a..4649012d454b 100644 --- a/src/libstd/io/comm_adapters.rs +++ b/src/libstd/io/comm_adapters.rs @@ -72,7 +72,7 @@ impl Buffer for ChanReader { if self.closed { Err(io::standard_error(io::EndOfFile)) } else { - Ok(self.buf.slice_from(self.pos)) + Ok(&self.buf[self.pos..]) } } @@ -88,7 +88,7 @@ impl Reader for ChanReader { loop { let count = match self.fill_buf().ok() { Some(src) => { - let dst = buf.slice_from_mut(num_read); + let dst = &mut buf[num_read..]; let count = cmp::min(src.len(), dst.len()); bytes::copy_memory(dst, &src[..count]); count diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs index ee05a9e55964..884582cbaa8e 100644 --- a/src/libstd/io/mem.rs +++ b/src/libstd/io/mem.rs @@ -160,7 +160,7 @@ impl Reader for MemReader { let write_len = min(buf.len(), self.buf.len() - self.pos); { let input = &self.buf[self.pos.. (self.pos + write_len)]; - let output = buf.slice_to_mut(write_len); + let output = &mut buf[.. write_len]; assert_eq!(input.len(), output.len()); slice::bytes::copy_memory(output, input); } @@ -205,11 +205,11 @@ impl<'a> Reader for &'a [u8] { let write_len = min(buf.len(), self.len()); { let input = &self[..write_len]; - let output = buf.slice_to_mut(write_len); + let output = &mut buf[.. write_len]; slice::bytes::copy_memory(output, input); } - *self = self.slice_from(write_len); + *self = &self[write_len..]; Ok(write_len) } @@ -270,7 +270,7 @@ impl<'a> BufWriter<'a> { impl<'a> Writer for BufWriter<'a> { #[inline] fn write(&mut self, src: &[u8]) -> IoResult<()> { - let dst = self.buf.slice_from_mut(self.pos); + let dst = &mut self.buf[self.pos..]; let dst_len = dst.len(); if dst_len == 0 { @@ -350,7 +350,7 @@ impl<'a> Reader for BufReader<'a> { let write_len = min(buf.len(), self.buf.len() - self.pos); { let input = &self.buf[self.pos.. (self.pos + write_len)]; - let output = buf.slice_to_mut(write_len); + let output = &mut buf[.. write_len]; assert_eq!(input.len(), output.len()); slice::bytes::copy_memory(output, input); } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index dc21416df7b4..ba7c81bf3fbf 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -516,7 +516,7 @@ pub trait Reader { while read < min { let mut zeroes = 0; loop { - match self.read(buf.slice_from_mut(read)) { + match self.read(&mut buf[read..]) { Ok(0) => { zeroes += 1; if zeroes >= NO_PROGRESS_LIMIT { @@ -1481,7 +1481,7 @@ pub trait Buffer: Reader { { let mut start = 1; while start < width { - match try!(self.read(buf.slice_mut(start, width))) { + match try!(self.read(&mut buf[start .. width])) { n if n == width - start => break, n if n < width - start => { start += n; } _ => return Err(standard_error(InvalidInput)), diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs index adc122ff4474..2c79d7a373de 100644 --- a/src/libstd/io/net/ip.rs +++ b/src/libstd/io/net/ip.rs @@ -251,7 +251,7 @@ impl<'a> Parser<'a> { assert!(head.len() + tail.len() <= 8); let mut gs = [0u16; 8]; gs.clone_from_slice(head); - gs.slice_mut(8 - tail.len(), 8).clone_from_slice(tail); + gs[(8 - tail.len()) .. 8].clone_from_slice(tail); Ipv6Addr(gs[0], gs[1], gs[2], gs[3], gs[4], gs[5], gs[6], gs[7]) } diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs index adfd88644cce..e4bf38a9ef5d 100644 --- a/src/libstd/io/util.rs +++ b/src/libstd/io/util.rs @@ -48,7 +48,7 @@ impl Reader for LimitReader { } let len = cmp::min(self.limit, buf.len()); - let res = self.inner.read(buf.slice_to_mut(len)); + let res = self.inner.read(&mut buf[..len]); match res { Ok(len) => self.limit -= len, _ => {} diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index 67fe599ecd6b..1d3bf484edb9 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -379,14 +379,14 @@ pub fn float_to_str_bytes_common( // only resize buf if we actually remove digits if i < buf_max_i { - buf = buf.slice(0, i + 1).to_vec(); + buf = buf[.. (i + 1)].to_vec(); } } } // If exact and trailing '.', just cut that else { let max_i = buf.len() - 1; if buf[max_i] == b'.' { - buf = buf.slice(0, max_i).to_vec(); + buf = buf[.. max_i].to_vec(); } } diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs index 68ba7e1dd29e..bafbde2511de 100644 --- a/src/libstd/rand/os.rs +++ b/src/libstd/rand/os.rs @@ -65,7 +65,7 @@ mod imp { let mut read = 0; let len = v.len(); while read < len { - let result = getrandom(v.slice_from_mut(read)); + let result = getrandom(&mut v[read..]); if result == -1 { let err = errno() as libc::c_int; if err == libc::EINTR { diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs index 235cedcda524..4023a0a4c100 100644 --- a/src/libstd/rt/util.rs +++ b/src/libstd/rt/util.rs @@ -130,7 +130,7 @@ pub fn abort(args: fmt::Arguments) -> ! { } impl<'a> fmt::Writer for BufWriter<'a> { fn write_str(&mut self, bytes: &str) -> fmt::Result { - let left = self.buf.slice_from_mut(self.pos); + let left = &mut self.buf[self.pos..]; let to_write = &bytes.as_bytes()[..cmp::min(bytes.len(), left.len())]; slice::bytes::copy_memory(left, to_write); self.pos += to_write.len(); diff --git a/src/libstd/sys/common/backtrace.rs b/src/libstd/sys/common/backtrace.rs index d8b859872360..d069d9ee3b8b 100644 --- a/src/libstd/sys/common/backtrace.rs +++ b/src/libstd/sys/common/backtrace.rs @@ -42,10 +42,10 @@ pub fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> { let mut valid = true; let mut inner = s; if s.len() > 4 && s.starts_with("_ZN") && s.ends_with("E") { - inner = s.slice(3, s.len() - 1); + inner = &s[3 .. s.len() - 1]; // On Windows, dbghelp strips leading underscores, so we accept "ZN...E" form too. } else if s.len() > 3 && s.starts_with("ZN") && s.ends_with("E") { - inner = s.slice(2, s.len() - 1); + inner = &s[2 .. s.len() - 1]; } else { valid = false; } @@ -83,11 +83,11 @@ pub fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> { } let mut rest = inner; while rest.char_at(0).is_numeric() { - rest = rest.slice_from(1); + rest = &rest[1..]; } - let i: uint = inner.slice_to(inner.len() - rest.len()).parse().unwrap(); - inner = rest.slice_from(i); - rest = rest.slice_to(i); + let i: uint = inner[.. (inner.len() - rest.len())].parse().unwrap(); + inner = &rest[i..]; + rest = &rest[..i]; while rest.len() > 0 { if rest.starts_with("$") { macro_rules! demangle { @@ -128,8 +128,8 @@ pub fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> { None => rest.len(), Some(i) => i, }; - try!(writer.write_str(rest.slice_to(idx))); - rest = rest.slice_from(idx); + try!(writer.write_str(&rest[..idx])); + rest = &rest[idx..]; } } } diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs index 36bf696dba55..46639d7d8f0c 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -125,9 +125,9 @@ impl Process { let mut bytes = [0; 8]; return match input.read(&mut bytes) { Ok(8) => { - assert!(combine(CLOEXEC_MSG_FOOTER) == combine(bytes.slice(4, 8)), + assert!(combine(CLOEXEC_MSG_FOOTER) == combine(&bytes[4.. 8]), "Validation on the CLOEXEC pipe failed: {:?}", bytes); - let errno = combine(bytes.slice(0, 4)); + let errno = combine(&bytes[0.. 4]); assert!(p.wait(0).is_ok(), "wait(0) should either return Ok or panic"); Err(super::decode_error(errno)) } diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index a7330f7c67c9..cb8ef7eb66bc 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -376,7 +376,7 @@ pub fn readlink(p: &Path) -> IoResult { }); let ret = match ret { Some(ref s) if s.starts_with(r"\\?\") => { // " - Ok(Path::new(s.slice_from(4))) + Ok(Path::new(&s[4..])) } Some(s) => Ok(Path::new(s)), None => Err(super::last_error()), diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index e9490dc95c94..36dc9b2afe49 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -146,7 +146,7 @@ pub fn fill_utf16_buf_and_decode(mut f: F) -> Option where done = true; } if k != 0 && done { - let sub = buf.slice(0, k as uint); + let sub = &buf[.. (k as uint)]; // We want to explicitly catch the case when the // closure returned invalid UTF-16, rather than // set `res` to None and continue. diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 4cdafb36eecc..7852b077b536 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -271,9 +271,9 @@ impl<'a> StringReader<'a> { fn with_str_from_to(&self, start: BytePos, end: BytePos, f: F) -> T where F: FnOnce(&str) -> T, { - f(self.filemap.src.slice( - self.byte_offset(start).to_uint(), - self.byte_offset(end).to_uint())) + f(&self.filemap.src[ + self.byte_offset(start).to_uint().. + self.byte_offset(end).to_uint()]) } /// Converts CRLF to LF in the given string, raising an error on bare CR. diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 83a7504bc498..932c5ce23ea5 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5223,7 +5223,7 @@ impl<'a> Parser<'a> { Some(i) => { let mut err = String::from_str("circular modules: "); let len = included_mod_stack.len(); - for p in included_mod_stack.slice(i, len).iter() { + for p in included_mod_stack[i.. len].iter() { err.push_str(&p.display().as_cow()[]); err.push_str(" -> "); } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index b59e770c6ba5..cf5066ae4745 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1590,7 +1590,7 @@ impl<'a> State<'a> { ident: ast::SpannedIdent, tys: &[P], args: &[P]) -> IoResult<()> { - let base_args = args.slice_from(1); + let base_args = &args[1..]; try!(self.print_expr(&*args[0])); try!(word(&mut self.s, ".")); try!(self.print_ident(ident.node)); @@ -2312,7 +2312,7 @@ impl<'a> State<'a> { let args = if first { &decl.inputs[] } else { - decl.inputs.slice_from(1) + &decl.inputs[1..] }; for arg in args.iter() { diff --git a/src/libunicode/u_str.rs b/src/libunicode/u_str.rs index 13672a7b480a..66cdf03a51ea 100644 --- a/src/libunicode/u_str.rs +++ b/src/libunicode/u_str.rs @@ -249,8 +249,8 @@ impl<'a> Iterator for Graphemes<'a> { Some(cat) }; - let retstr = self.string.slice_to(idx); - self.string = self.string.slice_from(idx); + let retstr = &self.string[..idx]; + self.string = &self.string[idx..]; Some(retstr) } } @@ -350,8 +350,8 @@ impl<'a> DoubleEndedIterator for Graphemes<'a> { Some(cat) }; - let retstr = self.string.slice_from(idx); - self.string = self.string.slice_to(idx); + let retstr = &self.string[idx..]; + self.string = &self.string[..idx]; Some(retstr) } } From da8023d653618431f8e1c651e0c3b83fa0d4269a Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Tue, 20 Jan 2015 16:37:00 -0800 Subject: [PATCH 4/5] Change init-large-type to use child thread --- src/test/run-pass/init-large-type.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test/run-pass/init-large-type.rs b/src/test/run-pass/init-large-type.rs index 0534d0c054f4..8ee6054f8ba5 100644 --- a/src/test/run-pass/init-large-type.rs +++ b/src/test/run-pass/init-large-type.rs @@ -14,6 +14,8 @@ #![feature(intrinsics)] +use std::thread::Thread; + extern "rust-intrinsic" { pub fn init() -> T; } @@ -21,5 +23,8 @@ extern "rust-intrinsic" { const SIZE: usize = 1024 * 1024; fn main() { - let _memory: [u8; SIZE] = unsafe { init() }; + // do the test in a new thread to avoid (spurious?) stack overflows + let _ = Thread::scoped(|| { + let _memory: [u8; SIZE] = unsafe { init() }; + }).join(); } From 537889aa78c984ee6484d16fec4a67f35778aec6 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Wed, 21 Jan 2015 11:16:00 -0800 Subject: [PATCH 5/5] Fix type inference problems in tests and docs --- src/doc/intro.md | 8 +++---- src/doc/trpl/looping.md | 2 +- src/doc/trpl/threads.md | 4 ++-- src/test/bench/shootout-binarytrees.rs | 32 ++++++++++++++------------ 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/doc/intro.md b/src/doc/intro.md index a7c37ba8e07e..b92d38215c29 100644 --- a/src/doc/intro.md +++ b/src/doc/intro.md @@ -480,14 +480,12 @@ use std::sync::{Arc,Mutex}; fn main() { let numbers = Arc::new(Mutex::new(vec![1is, 2, 3])); - for i in 0..3 { + for i in 0us..3 { let number = numbers.clone(); Thread::spawn(move || { let mut array = number.lock().unwrap(); - - array[i as usize] += 1; - - println!("numbers[{}] is {}", i, array[i as usize]); + array[i] += 1; + println!("numbers[{}] is {}", i, array[i]); }); } } diff --git a/src/doc/trpl/looping.md b/src/doc/trpl/looping.md index 28f02b1ffe15..4301149d1f8b 100644 --- a/src/doc/trpl/looping.md +++ b/src/doc/trpl/looping.md @@ -123,7 +123,7 @@ We now loop forever with `loop` and use `break` to break out early. iteration. This will only print the odd numbers: ```{rust} -for x in 0..10 { +for x in 0u32..10 { if x % 2 == 0 { continue; } println!("{}", x); diff --git a/src/doc/trpl/threads.md b/src/doc/trpl/threads.md index 1bad09b4b6e5..a801a1ab0e92 100644 --- a/src/doc/trpl/threads.md +++ b/src/doc/trpl/threads.md @@ -179,7 +179,7 @@ for init_val in 0 .. 3 { } let result = rx.recv().unwrap() + rx.recv().unwrap() + rx.recv().unwrap(); -# fn some_expensive_computation(_i: u32) -> u32 { 42 } +# fn some_expensive_computation(_i: i32) -> i32 { 42 } ``` Cloning a `Sender` produces a new handle to the same channel, allowing multiple @@ -207,7 +207,7 @@ let rxs = (0 .. 3).map(|&:init_val| { // Wait on each port, accumulating the results let result = rxs.iter().fold(0, |&:accum, rx| accum + rx.recv().unwrap() ); -# fn some_expensive_computation(_i: u32) -> u32 { 42 } +# fn some_expensive_computation(_i: i32) -> i32 { 42 } ``` ## Backgrounding computations: Futures diff --git a/src/test/bench/shootout-binarytrees.rs b/src/test/bench/shootout-binarytrees.rs index 58e2430b0ffa..4182f8b651b2 100644 --- a/src/test/bench/shootout-binarytrees.rs +++ b/src/test/bench/shootout-binarytrees.rs @@ -41,7 +41,7 @@ extern crate arena; use std::iter::range_step; -use std::thread::Thread; +use std::thread::{Thread, JoinGuard}; use arena::TypedArena; struct Tree<'a> { @@ -71,6 +71,18 @@ fn bottom_up_tree<'r>(arena: &'r TypedArena>, item: i32, depth: i32) } } +fn inner(depth: i32, iterations: i32) -> String { + let mut chk = 0; + for i in 1 .. iterations + 1 { + let arena = TypedArena::new(); + let a = bottom_up_tree(&arena, i, depth); + let b = bottom_up_tree(&arena, -i, depth); + chk += item_check(&a) + item_check(&b); + } + format!("{}\t trees of depth {}\t check: {}", + iterations * 2, depth, chk) +} + fn main() { let args = std::os::args(); let args = args.as_slice(); @@ -97,20 +109,10 @@ fn main() { let long_lived_tree = bottom_up_tree(&long_lived_arena, 0, max_depth); let messages = range_step(min_depth, max_depth + 1, 2).map(|depth| { - use std::num::Int; - let iterations = 2.pow((max_depth - depth + min_depth) as usize); - Thread::scoped(move|| { - let mut chk = 0; - for i in 1 .. iterations + 1 { - let arena = TypedArena::new(); - let a = bottom_up_tree(&arena, i, depth); - let b = bottom_up_tree(&arena, -i, depth); - chk += item_check(&a) + item_check(&b); - } - format!("{}\t trees of depth {}\t check: {}", - iterations * 2, depth, chk) - }) - }).collect::>(); + use std::num::Int; + let iterations = 2.pow((max_depth - depth + min_depth) as usize); + Thread::scoped(move || inner(depth, iterations)) + }).collect::>(); for message in messages.into_iter() { println!("{}", message.join().ok().unwrap());