Skip to content

Commit

Permalink
libcore: DST-ify AsSlice
Browse files Browse the repository at this point in the history
This commit changes `AsSlice` to work on unsized types, and changes the
`impl` for `&[T]` to `[T]`. Aside from making the trait more general,
this also helps some ongoing work with method resolution changes.

This is a breaking change: code that uses generics bounded by `AsSlice`
will have to change. In particular, such code previously often took
arguments of type `V` where `V: AsSlice<T>` by value. These should now
be taken by reference:

```rust
fn foo<Sized? V: AsSlice<T>>(v: &V) { .. }
```

A few std lib functions have been changed accordingly.

[breaking-change]
  • Loading branch information
aturon committed Nov 20, 2014
1 parent 7936242 commit 004db80
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/libcollections/slice.rs
Expand Up @@ -121,7 +121,7 @@ pub trait VectorVector<T> for Sized? {
fn connect_vec(&self, sep: &T) -> Vec<T>;
}

impl<T: Clone, V: AsSlice<T>> VectorVector<T> for [V] {
impl<'a, T: Clone, V: AsSlice<T>> VectorVector<T> for [V] {
fn concat_vec(&self) -> Vec<T> {
let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
let mut result = Vec::with_capacity(size);
Expand Down
5 changes: 3 additions & 2 deletions src/libcollections/vec.rs
Expand Up @@ -20,6 +20,7 @@ use core::cmp::max;
use core::default::Default;
use core::fmt;
use core::kinds::marker::{ContravariantLifetime, InvariantType};
use core::kinds::Sized;
use core::mem;
use core::num::{Int, UnsignedInt};
use core::ops;
Expand Down Expand Up @@ -516,7 +517,7 @@ impl<T: PartialOrd> PartialOrd for Vec<T> {
impl<T: Eq> Eq for Vec<T> {}

#[experimental]
impl<T: PartialEq, V: AsSlice<T>> Equiv<V> for Vec<T> {
impl<T: PartialEq, Sized? V: AsSlice<T>> Equiv<V> for Vec<T> {
#[inline]
fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
}
Expand Down Expand Up @@ -1181,7 +1182,7 @@ impl<T> AsSlice<T> for Vec<T> {
}
}

impl<T: Clone, V: AsSlice<T>> Add<V, Vec<T>> for Vec<T> {
impl<T: Clone, Sized? V: AsSlice<T>> Add<V, Vec<T>> for Vec<T> {
#[inline]
fn add(&self, rhs: &V) -> Vec<T> {
let mut res = Vec::with_capacity(self.len() + rhs.as_slice().len());
Expand Down
20 changes: 15 additions & 5 deletions src/libcore/slice.rs
Expand Up @@ -1008,15 +1008,25 @@ impl<T: Clone> CloneSlicePrelude<T> for [T] {

/// Data that is viewable as a slice.
#[unstable = "may merge with other traits"]
pub trait AsSlice<T> {
pub trait AsSlice<T> for Sized? {
/// Work with `self` as a slice.
fn as_slice<'a>(&'a self) -> &'a [T];
}

#[unstable = "trait is unstable"]
impl<'a,T> AsSlice<T> for &'a [T] {
impl<T> AsSlice<T> for [T] {
#[inline(always)]
fn as_slice<'a>(&'a self) -> &'a [T] { *self }
fn as_slice<'a>(&'a self) -> &'a [T] { self }
}

impl<'a, T, Sized? U: AsSlice<T>> AsSlice<T> for &'a U {
#[inline(always)]
fn as_slice<'a>(&'a self) -> &'a [T] { AsSlice::as_slice(*self) }
}

impl<'a, T, Sized? U: AsSlice<T>> AsSlice<T> for &'a mut U {
#[inline(always)]
fn as_slice<'a>(&'a self) -> &'a [T] { AsSlice::as_slice(*self) }
}

#[unstable = "waiting for DST"]
Expand Down Expand Up @@ -1681,13 +1691,13 @@ impl<T: PartialEq> PartialEq for [T] {
impl<T: Eq> Eq for [T] {}

#[unstable = "waiting for DST"]
impl<T: PartialEq, V: AsSlice<T>> Equiv<V> for [T] {
impl<T: PartialEq, Sized? V: AsSlice<T>> Equiv<V> for [T] {
#[inline]
fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
}

#[unstable = "waiting for DST"]
impl<'a,T:PartialEq, V: AsSlice<T>> Equiv<V> for &'a mut [T] {
impl<'a,T:PartialEq, Sized? V: AsSlice<T>> Equiv<V> for &'a mut [T] {
#[inline]
fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
}
Expand Down
2 changes: 1 addition & 1 deletion src/libgraphviz/maybe_owned_vec.rs
Expand Up @@ -89,7 +89,7 @@ impl<'a, T: Ord> Ord for MaybeOwnedVector<'a, T> {
}
}

impl<'a, T: PartialEq, V: AsSlice<T>> Equiv<V> for MaybeOwnedVector<'a, T> {
impl<'a, T: PartialEq, Sized? V: AsSlice<T>> Equiv<V> for MaybeOwnedVector<'a, T> {
fn equiv(&self, other: &V) -> bool {
self.as_slice() == other.as_slice()
}
Expand Down
3 changes: 2 additions & 1 deletion src/libstd/path/posix.rs
Expand Up @@ -16,6 +16,7 @@ use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
use hash;
use io::Writer;
use iter::{DoubleEndedIterator, AdditiveIterator, Extend, Iterator, Map};
use kinds::Sized;
use option::{Option, None, Some};
use str::{FromStr, Str};
use str;
Expand Down Expand Up @@ -342,7 +343,7 @@ impl Path {

/// Returns a normalized byte vector representation of a path, by removing all empty
/// components, and unnecessary . and .. components.
fn normalize<V: AsSlice<u8>>(v: V) -> Vec<u8> {
fn normalize<Sized? V: AsSlice<u8>>(v: &V) -> Vec<u8> {
// borrowck is being very picky
let val = {
let is_abs = !v.as_slice().is_empty() && v.as_slice()[0] == SEP_BYTE;
Expand Down

0 comments on commit 004db80

Please sign in to comment.