Skip to content

Use slicing syntax instead of methods and add a feature gate #17620

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

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion src/compiletest/compiletest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// except according to those terms.

#![crate_type = "bin"]
#![feature(phase)]
#![feature(phase, slicing_syntax)]

#![deny(warnings)]

Expand Down
2 changes: 1 addition & 1 deletion src/compiletest/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,7 @@ fn check_error_patterns(props: &TestProps,
if done { return; }

let missing_patterns =
props.error_patterns.slice(next_err_idx, props.error_patterns.len());
props.error_patterns[next_err_idx..];
if missing_patterns.len() == 1u {
fatal_proc_rec(format!("error pattern '{}' not found!",
missing_patterns[0]).as_slice(),
Expand Down
2 changes: 1 addition & 1 deletion src/doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -3828,7 +3828,7 @@ type signature of `print`, and the cast expression in `main`.
Within the body of an item that has type parameter declarations, the names of
its type parameters are types:

```
```ignore
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you undo the deprecation, please remove the ignore here. (And in general, better to add a silent #[allow(deprecated)] but otherwise keep the test.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason I couldn't add attributes to this code snippet - I tried to allow slicing syntax but there was no way I could get it to work.

fn map<A: Clone, B: Clone>(f: |A| -> B, xs: &[A]) -> Vec<B> {
if xs.len() == 0 {
return vec![];
Expand Down
2 changes: 1 addition & 1 deletion src/libcollections/bitv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ impl Bitv {
if start > self.storage.len() {
start = self.storage.len();
}
let mut iter = self.storage.slice_from(start).iter();
let mut iter = self.storage[start..].iter();
MaskWords {
next_word: iter.next(),
iter: iter,
Expand Down
3 changes: 2 additions & 1 deletion src/libcollections/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]

#![allow(unknown_features)]
#![feature(macro_rules, managed_boxes, default_type_params, phase, globs)]
#![feature(unsafe_destructor, import_shadowing)]
#![feature(unsafe_destructor, import_shadowing, slicing_syntax)]
#![no_std]

#[phase(plugin, link)] extern crate core;
Expand Down
4 changes: 2 additions & 2 deletions src/libcollections/ringbuf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ impl<T> RingBuf<T> {
/// *num = *num - 2;
/// }
/// let b: &[_] = &[&mut 3, &mut 1, &mut 2];
/// assert_eq!(buf.iter_mut().collect::<Vec<&mut int>>().as_slice(), b);
/// assert_eq!(buf.iter_mut().collect::<Vec<&mut int>>()[], b);
/// ```
pub fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T> {
let start_index = raw_index(self.lo, self.elts.len(), 0);
Expand All @@ -291,7 +291,7 @@ impl<T> RingBuf<T> {
} else {
// Items to iterate goes from start_index to end_index:
let (empty, elts) = self.elts.split_at_mut(0);
let remaining1 = elts.slice_mut(start_index, end_index);
let remaining1 = elts[mut start_index..end_index];
MutItems { remaining1: remaining1,
remaining2: empty,
nelts: self.nelts }
Expand Down
63 changes: 37 additions & 26 deletions src/libcollections/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,20 @@
//!
//! A number of traits add methods that allow you to accomplish tasks with slices.
//! These traits include `ImmutableSlice`, which is defined for `&[T]` types,
//! and `MutableSlice`, defined for `&mut [T]` types.
//! `MutableSlice`, defined for `&mut [T]` types, and `Slice` and `SliceMut`
//! which are defined for `[T]`.
//!
//! An example is the method `.slice(a, b)` that returns an immutable "view" into
//! a `Vec` or another slice from the index interval `[a, b)`:
//! An example is the `slice` method which enables slicing syntax `[a..b]` that
//! returns an immutable "view" into a `Vec` or another slice from the index
//! interval `[a, b)`:
//!
//! ```rust
//! let numbers = [0i, 1i, 2i];
//! let last_numbers = numbers.slice(1, 3);
//! // last_numbers is now &[1i, 2i]
//! #![feature(slicing_syntax)]
//! fn main() {
//! let numbers = [0i, 1i, 2i];
//! let last_numbers = numbers[1..3];
//! // last_numbers is now &[1i, 2i]
//! }
//! ```
//!
//! ## Implementations of other traits
Expand Down Expand Up @@ -610,7 +615,7 @@ impl<'a,T> MutableSliceAllocating<'a, T> for &'a mut [T] {

#[inline]
fn move_from(self, mut src: Vec<T>, 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[mut start..end].iter_mut()) {
mem::swap(a, b);
}
cmp::min(self.len(), end-start)
Expand Down Expand Up @@ -702,7 +707,7 @@ impl<'a, T: Ord> MutableOrdSlice<T> for &'a mut [T] {
self.swap(j, i-1);

// Step 4: Reverse the (previously) weakly decreasing part
self.slice_from_mut(i).reverse();
self[mut i..].reverse();

true
}
Expand All @@ -723,7 +728,7 @@ impl<'a, T: Ord> MutableOrdSlice<T> for &'a mut [T] {
}

// Step 2: Reverse the weakly increasing part
self.slice_from_mut(i).reverse();
self[mut i..].reverse();

// Step 3: Find the rightmost element equal to or bigger than the pivot (i-1)
let mut j = self.len() - 1;
Expand Down Expand Up @@ -990,24 +995,24 @@ mod tests {
fn test_slice() {
// Test fixed length vector.
let vec_fixed = [1i, 2, 3, 4];
let v_a = vec_fixed.slice(1u, vec_fixed.len()).to_vec();
let v_a = vec_fixed[1u..vec_fixed.len()].to_vec();
assert_eq!(v_a.len(), 3u);
let v_a = v_a.as_slice();
assert_eq!(v_a[0], 2);
assert_eq!(v_a[1], 3);
assert_eq!(v_a[2], 4);

// Test on stack.
let vec_stack = &[1i, 2, 3];
let v_b = vec_stack.slice(1u, 3u).to_vec();
let vec_stack: &[_] = &[1i, 2, 3];
let v_b = vec_stack[1u..3u].to_vec();
assert_eq!(v_b.len(), 2u);
let v_b = v_b.as_slice();
assert_eq!(v_b[0], 2);
assert_eq!(v_b[1], 3);

// Test `Box<[T]>`
let vec_unique = vec![1i, 2, 3, 4, 5, 6];
let v_d = vec_unique.slice(1u, 6u).to_vec();
let v_d = vec_unique[1u..6u].to_vec();
assert_eq!(v_d.len(), 5u);
let v_d = v_d.as_slice();
assert_eq!(v_d[0], 2);
Expand All @@ -1020,21 +1025,21 @@ mod tests {
#[test]
fn test_slice_from() {
let vec: &[int] = &[1, 2, 3, 4];
assert_eq!(vec.slice_from(0), vec);
assert_eq!(vec[0..], vec);
let b: &[int] = &[3, 4];
assert_eq!(vec.slice_from(2), b);
assert_eq!(vec[2..], b);
let b: &[int] = &[];
assert_eq!(vec.slice_from(4), b);
assert_eq!(vec[4..], b);
}

#[test]
fn test_slice_to() {
let vec: &[int] = &[1, 2, 3, 4];
assert_eq!(vec.slice_to(4), vec);
assert_eq!(vec[..4], vec);
let b: &[int] = &[1, 2];
assert_eq!(vec.slice_to(2), b);
assert_eq!(vec[..2], b);
let b: &[int] = &[];
assert_eq!(vec.slice_to(0), b);
assert_eq!(vec[..0], b);
}


Expand Down Expand Up @@ -1975,7 +1980,7 @@ mod tests {
assert!(a == [7i,2,3,4]);
let mut a = [1i,2,3,4,5];
let b = vec![5i,6,7,8,9,0];
assert_eq!(a.slice_mut(2,4).move_from(b,1,6), 2);
assert_eq!(a[mut 2..4].move_from(b,1,6), 2);
assert!(a == [1i,2,6,7,5]);
}

Expand All @@ -1995,7 +2000,7 @@ mod tests {
#[test]
fn test_reverse_part() {
let mut values = [1i,2,3,4,5];
values.slice_mut(1, 4).reverse();
values[mut 1..4].reverse();
assert!(values == [1,4,3,2,5]);
}

Expand Down Expand Up @@ -2042,9 +2047,9 @@ mod tests {
fn test_bytes_set_memory() {
use slice::bytes::MutableByteVector;
let mut values = [1u8,2,3,4,5];
values.slice_mut(0,5).set_memory(0xAB);
values[mut 0..5].set_memory(0xAB);
assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
values.slice_mut(2,4).set_memory(0xFF);
values[mut 2..4].set_memory(0xFF);
assert!(values == [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
}

Expand All @@ -2070,12 +2075,18 @@ mod tests {
let mut values = [1u8,2,3,4,5];
{
let (left, right) = values.split_at_mut(2);
assert!(left.slice(0, left.len()) == [1, 2]);
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious why this new scope is needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its because we can't take a mutable slice (because we do a mutable iter later) and we can't take an immutable slice of a mutable variable (#17293), so we need to get an immutable version of right and then let that go out of scope so that we can later get access to the mutable version again.

let left: &[_] = left;
assert!(left[0..left.len()] == [1, 2]);
}
for p in left.iter_mut() {
*p += 1;
}

assert!(right.slice(0, right.len()) == [3, 4, 5]);
{
let right: &[_] = right;
assert!(right[0..right.len()] == [3, 4, 5]);
}
for p in right.iter_mut() {
*p += 2;
}
Expand All @@ -2099,7 +2110,7 @@ mod tests {
}
assert_eq!(cnt, 3);

for f in v.slice(1, 3).iter() {
for f in v[1..3].iter() {
assert!(*f == Foo);
cnt += 1;
}
Expand Down
4 changes: 2 additions & 2 deletions src/libcollections/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1680,7 +1680,7 @@ mod tests {
let mut bytes = [0u8, ..4];
for c in range(0u32, 0x110000).filter_map(|c| ::core::char::from_u32(c)) {
let len = c.encode_utf8(bytes).unwrap_or(0);
let s = ::core::str::from_utf8(bytes.slice_to(len)).unwrap();
let s = ::core::str::from_utf8(bytes[..len]).unwrap();
if Some(c) != s.chars().next() {
fail!("character {:x}={} does not decode correctly", c as u32, c);
}
Expand All @@ -1692,7 +1692,7 @@ mod tests {
let mut bytes = [0u8, ..4];
for c in range(0u32, 0x110000).filter_map(|c| ::core::char::from_u32(c)) {
let len = c.encode_utf8(bytes).unwrap_or(0);
let s = ::core::str::from_utf8(bytes.slice_to(len)).unwrap();
let s = ::core::str::from_utf8(bytes[..len]).unwrap();
if Some(c) != s.chars().rev().next() {
fail!("character {:x}={} does not decode correctly", c as u32, c);
}
Expand Down
35 changes: 32 additions & 3 deletions src/libcollections/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ impl String {

if i > 0 {
unsafe {
res.as_mut_vec().push_all(v.slice_to(i))
res.as_mut_vec().push_all(v[..i])
};
}

Expand All @@ -177,7 +177,7 @@ impl String {
macro_rules! error(() => ({
unsafe {
if subseqidx != i_ {
res.as_mut_vec().push_all(v.slice(subseqidx, i_));
res.as_mut_vec().push_all(v[subseqidx..i_]);
}
subseqidx = i;
res.as_mut_vec().push_all(REPLACEMENT);
Expand Down Expand Up @@ -246,7 +246,7 @@ impl String {
}
if subseqidx < total {
unsafe {
res.as_mut_vec().push_all(v.slice(subseqidx, total))
res.as_mut_vec().push_all(v[subseqidx..total])
};
}
Owned(res.into_string())
Expand Down Expand Up @@ -927,6 +927,7 @@ impl<S: Str> Add<S, String> for String {
}
}

#[cfg(stage0)]
impl ops::Slice<uint, str> for String {
#[inline]
fn as_slice_<'a>(&'a self) -> &'a str {
Expand All @@ -949,6 +950,34 @@ impl ops::Slice<uint, str> for String {
}
}

#[cfg(not(stage0))]
#[inline]
fn str_to_slice<'a, U: Str>(this: &'a U) -> &'a str {
this.as_slice()
}
#[cfg(not(stage0))]
impl ops::Slice<uint, str> for String {
#[inline]
fn as_slice<'a>(&'a self) -> &'a str {
str_to_slice(self)
}

#[inline]
fn slice_from<'a>(&'a self, from: &uint) -> &'a str {
self[][*from..]
}

#[inline]
fn slice_to<'a>(&'a self, to: &uint) -> &'a str {
self[][..*to]
}

#[inline]
fn slice<'a>(&'a self, from: &uint, to: &uint) -> &'a str {
self[][*from..*to]
}
}

/// Unsafe operations
#[unstable = "waiting on raw module conventions"]
pub mod raw {
Expand Down
21 changes: 20 additions & 1 deletion src/libcollections/trie.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use core::fmt;
use core::fmt::Show;
use core::mem::zeroed;
use core::mem;
use core::ops::{Slice,SliceMut};
use core::uint;
use core::iter;
use std::hash::{Writer, Hash};
Expand Down Expand Up @@ -378,7 +379,7 @@ macro_rules! bound {
}
};
// push to the stack.
it.stack[it.length] = children.$slice_from(slice_idx).$iter();
it.stack[it.length] = children.$slice_from(&slice_idx).$iter();
it.length += 1;
if ret { return it }
})
Expand All @@ -388,6 +389,15 @@ macro_rules! bound {

impl<T> TrieMap<T> {
// If `upper` is true then returns upper_bound else returns lower_bound.
#[cfg(stage0)]
#[inline]
fn bound<'a>(&'a self, key: uint, upper: bool) -> Entries<'a, T> {
bound!(Entries, self = self,
key = key, is_upper = upper,
slice_from = slice_from_, iter = iter,
mutability = )
}
#[cfg(not(stage0))]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this temporary?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

#[inline]
fn bound<'a>(&'a self, key: uint, upper: bool) -> Entries<'a, T> {
bound!(Entries, self = self,
Expand Down Expand Up @@ -430,6 +440,15 @@ impl<T> TrieMap<T> {
self.bound(key, true)
}
// If `upper` is true then returns upper_bound else returns lower_bound.
#[cfg(stage0)]
#[inline]
fn bound_mut<'a>(&'a mut self, key: uint, upper: bool) -> MutEntries<'a, T> {
bound!(MutEntries, self = self,
key = key, is_upper = upper,
slice_from = slice_from_mut_, iter = iter_mut,
mutability = mut)
}
#[cfg(not(stage0))]
#[inline]
fn bound_mut<'a>(&'a mut self, key: uint, upper: bool) -> MutEntries<'a, T> {
bound!(MutEntries, self = self,
Expand Down
Loading