diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 820a3838978c0..d38b77eb6fd78 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -247,7 +247,9 @@ impl BorrowFrom> for T { } #[experimental = "Deref is experimental."] -impl Deref for Arc { +impl Deref for Arc { + type Target = T; + #[inline] fn deref(&self) -> &T { &self.inner().data diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 74f0599e486e1..0d6ada4b2293c 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -153,11 +153,13 @@ impl fmt::Show for Box { } } -impl Deref for Box { +impl Deref for Box { + type Target = T; + fn deref(&self) -> &T { &**self } } -impl DerefMut for Box { +impl DerefMut for Box { fn deref_mut(&mut self) -> &mut T { &mut **self } } @@ -210,7 +212,7 @@ mod test { #[test] fn deref() { - fn homura>(_: T) { } + fn homura>(_: T) { } homura(box 765i32); } } diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 61b5d43d1cb50..c4858aea022a5 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -65,6 +65,7 @@ #![no_std] #![feature(lang_items, phase, unsafe_destructor, default_type_params)] +#![feature(associated_types)] #[phase(plugin, link)] extern crate core; diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index bd25093883649..c57231fc434cd 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -355,7 +355,9 @@ impl BorrowFrom> for T { } #[experimental = "Deref is experimental."] -impl Deref for Rc { +impl Deref for Rc { + type Target = T; + #[inline(always)] fn deref(&self) -> &T { &self.inner().value diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 87b40aa1ceeaf..4b85d2da4ac5d 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -515,13 +515,15 @@ mod stack { marker: marker::InvariantLifetime<'id> } - impl<'id, T> Deref for IdRef<'id, T> { + impl<'id, T> Deref for IdRef<'id, T> { + type Target = T; + fn deref(&self) -> &T { &*self.inner } } - impl<'id, T> DerefMut for IdRef<'id, T> { + impl<'id, T> DerefMut for IdRef<'id, T> { fn deref_mut(&mut self) -> &mut T { &mut *self.inner } diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index 3907f28092a37..d1a2916a14097 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -455,7 +455,9 @@ impl Clone for Node { /// flag: &'a Cell, /// } /// -/// impl<'a> Deref> for Nasty<'a> { +/// impl<'a> Deref for Nasty<'a> { +/// type Target = Node; +/// /// fn deref(&self) -> &Node { /// if self.flag.get() { /// &*self.second @@ -511,7 +513,7 @@ impl Node { /// Searches for the given key in the node. If it finds an exact match, /// `Found` will be yielded with the matching index. If it doesn't find an exact match, /// `GoDown` will be yielded with the index of the subtree the key must lie in. - pub fn search>>(node: NodeRef, key: &Q) + pub fn search>>(node: NodeRef, key: &Q) -> SearchResult where Q: BorrowFrom + Ord { // FIXME(Gankro): Tune when to search linear or binary based on B (and maybe K/V). // For the B configured as of this writing (B = 6), binary search was *significantly* @@ -588,7 +590,7 @@ impl Node { } } -impl>, Type, NodeType> Handle { +impl>, Type, NodeType> Handle { /// Returns a reference to the node that contains the pointed-to edge or key/value pair. This /// is very different from `edge` and `edge_mut` because those return children of the node /// returned by `node`. @@ -597,7 +599,9 @@ impl>, Type, NodeType> Handle>, Type, NodeType> Handle { +impl Handle where + NodeRef: Deref> + DerefMut, +{ /// Converts a handle into one that stores the same information using a raw pointer. This can /// be useful in conjunction with `from_raw` when the type system is insufficient for /// determining the lifetimes of the nodes. @@ -653,7 +657,7 @@ impl<'a, K: 'a, V: 'a> Handle<&'a mut Node, handle::Edge, handle::Internal } } -impl>> Handle { +impl>> Handle { // This doesn't exist because there are no uses for it, // but is fine to add, analagous to edge_mut. // @@ -667,7 +671,7 @@ pub enum ForceResult { Internal(Handle) } -impl>, Type> Handle { +impl>, Type> Handle { /// Figure out whether this handle is pointing to something in a leaf node or to something in /// an internal node, clarifying the type according to the result. pub fn force(self) -> ForceResult { @@ -684,8 +688,9 @@ impl>, Type> Handle>> Handle { +impl Handle where + NodeRef: Deref> + DerefMut, +{ /// Tries to insert this key-value pair at the given index in this leaf node /// If the node is full, we have to split it. /// @@ -717,7 +722,9 @@ impl>> Handle>> Handle { +impl Handle where + NodeRef: Deref> + DerefMut, +{ /// Returns a mutable reference to the edge pointed-to by this handle. This should not be /// confused with `node`, which references the parent node of what is returned here. pub fn edge_mut(&mut self) -> &mut Node { @@ -800,7 +807,9 @@ impl>> Handle>, NodeType> Handle { +impl Handle where + NodeRef: Deref> + DerefMut, +{ /// Gets the handle pointing to the key/value pair just to the left of the pointed-to edge. /// This is unsafe because the handle might point to the first edge in the node, which has no /// pair to its left. @@ -862,7 +871,7 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a mut Node, handle::KV, NodeType } } -impl<'a, K: 'a, V: 'a, NodeRef: Deref> + 'a, NodeType> Handle> + 'a, NodeType> Handle { // These are fine to include, but are currently unneeded. // @@ -881,8 +890,9 @@ impl<'a, K: 'a, V: 'a, NodeRef: Deref> + 'a, NodeType> Handle> + 'a, NodeType> Handle { +impl<'a, K: 'a, V: 'a, NodeRef, NodeType> Handle where + NodeRef: 'a + Deref> + DerefMut, +{ /// Returns a mutable reference to the key pointed-to by this handle. This doesn't return a /// reference with a lifetime as large as `into_kv_mut`, but it also does not consume the /// handle. @@ -898,7 +908,9 @@ impl<'a, K: 'a, V: 'a, NodeRef: DerefMut> + 'a, NodeType> Handle>, NodeType> Handle { +impl Handle where + NodeRef: Deref> + DerefMut, +{ /// Gets the handle pointing to the edge immediately to the left of the key/value pair pointed /// to by this handle. pub fn left_edge<'a>(&'a mut self) -> Handle<&'a mut Node, handle::Edge, NodeType> { @@ -918,7 +930,9 @@ impl>, NodeType> Handle>> Handle { +impl Handle where + NodeRef: Deref> + DerefMut, +{ /// Removes the key/value pair at the handle's location. /// /// # Panics (in debug build) @@ -929,7 +943,9 @@ impl>> Handle>> Handle { +impl Handle where + NodeRef: Deref> + DerefMut +{ /// Steal! Stealing is roughly analogous to a binary tree rotation. /// In this case, we're "rotating" right. unsafe fn steal_rightward(&mut self) { diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index cbd8d4955b217..09cff4bc5ad51 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -25,6 +25,7 @@ #![feature(macro_rules, default_type_params, phase, globs)] #![feature(unsafe_destructor, slicing_syntax)] #![feature(unboxed_closures)] +#![feature(associated_types)] #![no_std] #[phase(plugin, link)] extern crate core; @@ -120,7 +121,6 @@ mod prelude { pub use core::result::Result::{Ok, Err}; // in core and collections (may differ). - pub use slice::{PartialEqSliceExt, OrdSliceExt}; pub use slice::{AsSlice, SliceExt}; pub use str::{from_str, Str, StrExt}; @@ -129,7 +129,7 @@ mod prelude { pub use unicode::char::UnicodeChar; // from collections. - pub use slice::{CloneSliceExt, SliceConcatExt}; + pub use slice::SliceConcatExt; pub use str::IntoMaybeOwned; pub use string::{String, ToString}; pub use vec::Vec; diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 61111d96bd064..ac271e75ea114 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -96,7 +96,7 @@ use core::mem::size_of; use core::mem; use core::ops::{FnMut,SliceMut}; use core::prelude::{Clone, Greater, Iterator, IteratorExt, Less, None, Option}; -use core::prelude::{Ord, Ordering, PtrExt, Some, range, IteratorCloneExt, Result}; +use core::prelude::{Ord, Ordering, PartialEq, PtrExt, Some, range, IteratorCloneExt, Result}; use core::ptr; use core::slice as core_slice; use self::Direction::*; @@ -104,7 +104,7 @@ use self::Direction::*; use vec::Vec; pub use core::slice::{Chunks, AsSlice, Windows}; -pub use core::slice::{Iter, IterMut, PartialEqSliceExt}; +pub use core::slice::{Iter, IterMut}; pub use core::slice::{IntSliceExt, SplitMut, ChunksMut, Split}; pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut}; pub use core::slice::{bytes, mut_ref_slice, ref_slice}; @@ -122,7 +122,9 @@ pub type MutItems<'a, T:'a> = IterMut<'a, T>; /// Allocating extension methods for slices. #[unstable = "needs associated types, may merge with other traits"] -pub trait SliceExt for Sized? { +pub trait SliceExt for Sized? { + type Item; + /// Sorts the slice, in place, using `compare` to compare /// elements. /// @@ -141,7 +143,7 @@ pub trait SliceExt for Sized? { /// assert!(v == [5, 4, 3, 2, 1]); /// ``` #[stable] - fn sort_by(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering; + fn sort_by(&mut self, compare: F) where F: FnMut(&Self::Item, &Self::Item) -> Ordering; /// Consumes `src` and moves as many elements as it can into `self` /// from the range [start,end). @@ -165,7 +167,7 @@ pub trait SliceExt for Sized? { /// assert!(a == [6i, 7, 8, 4, 5]); /// ``` #[experimental = "uncertain about this API approach"] - fn move_from(&mut self, src: Vec, start: uint, end: uint) -> uint; + fn move_from(&mut self, src: Vec, start: uint, end: uint) -> uint; /// Returns a subslice spanning the interval [`start`, `end`). /// @@ -174,7 +176,7 @@ pub trait SliceExt for Sized? { /// /// Slicing with `start` equal to `end` yields an empty slice. #[experimental = "will be replaced by slice syntax"] - fn slice(&self, start: uint, end: uint) -> &[T]; + fn slice(&self, start: uint, end: uint) -> &[Self::Item]; /// Returns a subslice from `start` to the end of the slice. /// @@ -182,7 +184,7 @@ pub trait SliceExt for Sized? { /// /// Slicing from `self.len()` yields an empty slice. #[experimental = "will be replaced by slice syntax"] - fn slice_from(&self, start: uint) -> &[T]; + fn slice_from(&self, start: uint) -> &[Self::Item]; /// Returns a subslice from the start of the slice to `end`. /// @@ -190,7 +192,7 @@ pub trait SliceExt for Sized? { /// /// Slicing to `0` yields an empty slice. #[experimental = "will be replaced by slice syntax"] - fn slice_to(&self, end: uint) -> &[T]; + fn slice_to(&self, end: uint) -> &[Self::Item]; /// Divides one slice into two at an index. /// @@ -200,32 +202,32 @@ pub trait SliceExt for Sized? { /// /// Panics if `mid > len`. #[stable] - fn split_at(&self, mid: uint) -> (&[T], &[T]); + fn split_at(&self, mid: uint) -> (&[Self::Item], &[Self::Item]); /// Returns an iterator over the slice #[stable] - fn iter(&self) -> Iter; + fn iter(&self) -> Iter; /// Returns an iterator over subslices separated by elements that match /// `pred`. The matched element is not contained in the subslices. #[stable] - fn split(&self, pred: F) -> Split - where F: FnMut(&T) -> bool; + fn split(&self, pred: F) -> Split + where F: FnMut(&Self::Item) -> bool; /// Returns an iterator over subslices separated by elements that match /// `pred`, limited to splitting at most `n` times. The matched element is /// not contained in the subslices. #[stable] - fn splitn(&self, n: uint, pred: F) -> SplitN - where F: FnMut(&T) -> bool; + fn splitn(&self, n: uint, pred: F) -> SplitN + where F: FnMut(&Self::Item) -> bool; /// Returns an iterator over subslices separated by elements that match /// `pred` limited to splitting at most `n` times. This starts at the end of /// the slice and works backwards. The matched element is not contained in /// the subslices. #[stable] - fn rsplitn(&self, n: uint, pred: F) -> RSplitN - where F: FnMut(&T) -> bool; + fn rsplitn(&self, n: uint, pred: F) -> RSplitN + where F: FnMut(&Self::Item) -> bool; /// Returns an iterator over all contiguous windows of length /// `size`. The windows overlap. If the slice is shorter than @@ -247,7 +249,7 @@ pub trait SliceExt for Sized? { /// } /// ``` #[stable] - fn windows(&self, size: uint) -> Windows; + fn windows(&self, size: uint) -> Windows; /// Returns an iterator over `size` elements of the slice at a /// time. The chunks do not overlap. If `size` does not divide the @@ -270,41 +272,41 @@ pub trait SliceExt for Sized? { /// } /// ``` #[stable] - fn chunks(&self, size: uint) -> Chunks; + fn chunks(&self, size: uint) -> Chunks; /// Returns the element of a slice at the given index, or `None` if the /// index is out of bounds. #[stable] - fn get(&self, index: uint) -> Option<&T>; + fn get(&self, index: uint) -> Option<&Self::Item>; /// Returns the first element of a slice, or `None` if it is empty. #[stable] - fn first(&self) -> Option<&T>; + fn first(&self) -> Option<&Self::Item>; /// Deprecated: renamed to `first`. #[deprecated = "renamed to `first`"] - fn head(&self) -> Option<&T> { self.first() } + fn head(&self) -> Option<&Self::Item> { self.first() } /// Returns all but the first element of a slice. #[experimental = "likely to be renamed"] - fn tail(&self) -> &[T]; + fn tail(&self) -> &[Self::Item]; /// Returns all but the last element of a slice. #[experimental = "likely to be renamed"] - fn init(&self) -> &[T]; + fn init(&self) -> &[Self::Item]; /// Returns the last element of a slice, or `None` if it is empty. #[stable] - fn last(&self) -> Option<&T>; + fn last(&self) -> Option<&Self::Item>; /// Returns a pointer to the element at the given index, without doing /// bounds checking. #[stable] - unsafe fn get_unchecked(&self, index: uint) -> &T; + unsafe fn get_unchecked(&self, index: uint) -> &Self::Item; /// Deprecated: renamed to `get_unchecked`. #[deprecated = "renamed to get_unchecked"] - unsafe fn unsafe_get(&self, index: uint) -> &T { + unsafe fn unsafe_get(&self, index: uint) -> &Self::Item { self.get_unchecked(index) } @@ -316,7 +318,7 @@ pub trait SliceExt for Sized? { /// Modifying the slice may cause its buffer to be reallocated, which /// would also make any pointers to it invalid. #[stable] - fn as_ptr(&self) -> *const T; + fn as_ptr(&self) -> *const Self::Item; /// Binary search a sorted slice with a comparator function. /// @@ -352,7 +354,7 @@ pub trait SliceExt for Sized? { /// ``` #[stable] fn binary_search_by(&self, f: F) -> Result where - F: FnMut(&T) -> Ordering; + F: FnMut(&Self::Item) -> Ordering; /// Return the number of elements in the slice /// @@ -379,12 +381,12 @@ pub trait SliceExt for Sized? { /// Returns a mutable reference to the element at the given index, /// or `None` if the index is out of bounds #[stable] - fn get_mut(&mut self, index: uint) -> Option<&mut T>; + fn get_mut(&mut self, index: uint) -> Option<&mut Self::Item>; /// Work with `self` as a mut slice. /// Primarily intended for getting a &mut [T] from a [T; N]. #[stable] - fn as_mut_slice(&mut self) -> &mut [T]; + fn as_mut_slice(&mut self) -> &mut [Self::Item]; /// Returns a mutable subslice spanning the interval [`start`, `end`). /// @@ -393,7 +395,7 @@ pub trait SliceExt for Sized? { /// /// Slicing with `start` equal to `end` yields an empty slice. #[experimental = "will be replaced by slice syntax"] - fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T]; + fn slice_mut(&mut self, start: uint, end: uint) -> &mut [Self::Item]; /// Returns a mutable subslice from `start` to the end of the slice. /// @@ -401,7 +403,7 @@ pub trait SliceExt for Sized? { /// /// Slicing from `self.len()` yields an empty slice. #[experimental = "will be replaced by slice syntax"] - fn slice_from_mut(&mut self, start: uint) -> &mut [T]; + fn slice_from_mut(&mut self, start: uint) -> &mut [Self::Item]; /// Returns a mutable subslice from the start of the slice to `end`. /// @@ -409,54 +411,54 @@ pub trait SliceExt for Sized? { /// /// Slicing to `0` yields an empty slice. #[experimental = "will be replaced by slice syntax"] - fn slice_to_mut(&mut self, end: uint) -> &mut [T]; + fn slice_to_mut(&mut self, end: uint) -> &mut [Self::Item]; /// Returns an iterator that allows modifying each value #[stable] - fn iter_mut(&mut self) -> IterMut; + fn iter_mut(&mut self) -> IterMut; /// Returns a mutable pointer to the first element of a slice, or `None` if it is empty #[stable] - fn first_mut(&mut self) -> Option<&mut T>; + fn first_mut(&mut self) -> Option<&mut Self::Item>; /// Depreated: renamed to `first_mut`. #[deprecated = "renamed to first_mut"] - fn head_mut(&mut self) -> Option<&mut T> { + fn head_mut(&mut self) -> Option<&mut Self::Item> { self.first_mut() } /// Returns all but the first element of a mutable slice #[experimental = "likely to be renamed or removed"] - fn tail_mut(&mut self) -> &mut [T]; + fn tail_mut(&mut self) -> &mut [Self::Item]; /// Returns all but the last element of a mutable slice #[experimental = "likely to be renamed or removed"] - fn init_mut(&mut self) -> &mut [T]; + fn init_mut(&mut self) -> &mut [Self::Item]; /// Returns a mutable pointer to the last item in the slice. #[stable] - fn last_mut(&mut self) -> Option<&mut T>; + fn last_mut(&mut self) -> Option<&mut Self::Item>; /// Returns an iterator over mutable subslices separated by elements that /// match `pred`. The matched element is not contained in the subslices. #[stable] - fn split_mut(&mut self, pred: F) -> SplitMut - where F: FnMut(&T) -> bool; + fn split_mut(&mut self, pred: F) -> SplitMut + where F: FnMut(&Self::Item) -> bool; /// Returns an iterator over subslices separated by elements that match /// `pred`, limited to splitting at most `n` times. The matched element is /// not contained in the subslices. #[stable] - fn splitn_mut(&mut self, n: uint, pred: F) -> SplitNMut - where F: FnMut(&T) -> bool; + fn splitn_mut(&mut self, n: uint, pred: F) -> SplitNMut + where F: FnMut(&Self::Item) -> bool; /// Returns an iterator over subslices separated by elements that match /// `pred` limited to splitting at most `n` times. This starts at the end of /// the slice and works backwards. The matched element is not contained in /// the subslices. #[stable] - fn rsplitn_mut(&mut self, n: uint, pred: F) -> RSplitNMut - where F: FnMut(&T) -> bool; + fn rsplitn_mut(&mut self, n: uint, pred: F) -> RSplitNMut + where F: FnMut(&Self::Item) -> bool; /// Returns an iterator over `chunk_size` elements of the slice at a time. /// The chunks are mutable and do not overlap. If `chunk_size` does @@ -467,7 +469,7 @@ pub trait SliceExt for Sized? { /// /// Panics if `chunk_size` is 0. #[stable] - fn chunks_mut(&mut self, chunk_size: uint) -> ChunksMut; + fn chunks_mut(&mut self, chunk_size: uint) -> ChunksMut; /// Swaps two elements in a slice. /// @@ -525,7 +527,7 @@ pub trait SliceExt for Sized? { /// } /// ``` #[stable] - fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]); + fn split_at_mut(&mut self, mid: uint) -> (&mut [Self::Item], &mut [Self::Item]); /// Reverse the order of elements in a slice, in place. /// @@ -541,11 +543,11 @@ pub trait SliceExt for Sized? { /// Returns an unsafe mutable pointer to the element in index #[stable] - unsafe fn get_unchecked_mut(&mut self, index: uint) -> &mut T; + unsafe fn get_unchecked_mut(&mut self, index: uint) -> &mut Self::Item; /// Deprecated: renamed to `get_unchecked_mut`. #[deprecated = "renamed to get_unchecked_mut"] - unsafe fn unchecked_mut(&mut self, index: uint) -> &mut T { + unsafe fn unchecked_mut(&mut self, index: uint) -> &mut Self::Item { self.get_unchecked_mut(index) } @@ -558,11 +560,179 @@ pub trait SliceExt for Sized? { /// would also make any pointers to it invalid. #[inline] #[stable] - fn as_mut_ptr(&mut self) -> *mut T; + fn as_mut_ptr(&mut self) -> *mut Self::Item; + + /// Copies `self` into a new `Vec`. + #[stable] + fn to_vec(&self) -> Vec where Self::Item: Clone; + + /// Deprecated: use `iter().cloned().partition(f)` instead. + #[deprecated = "use iter().cloned().partition(f) instead"] + fn partitioned(&self, f: F) -> (Vec, Vec) where + Self::Item: Clone, + F: FnMut(&Self::Item) -> bool; + + /// Creates an iterator that yields every possible permutation of the + /// vector in succession. + /// + /// # Examples + /// + /// ```rust + /// let v = [1i, 2, 3]; + /// let mut perms = v.permutations(); + /// + /// for p in perms { + /// println!("{}", p); + /// } + /// ``` + /// + /// Iterating through permutations one by one. + /// + /// ```rust + /// let v = [1i, 2, 3]; + /// let mut perms = v.permutations(); + /// + /// assert_eq!(Some(vec![1i, 2, 3]), perms.next()); + /// assert_eq!(Some(vec![1i, 3, 2]), perms.next()); + /// assert_eq!(Some(vec![3i, 1, 2]), perms.next()); + /// ``` + #[unstable] + fn permutations(&self) -> Permutations where Self::Item: Clone; + + /// Copies as many elements from `src` as it can into `self` (the + /// shorter of `self.len()` and `src.len()`). Returns the number + /// of elements copied. + /// + /// # Example + /// + /// ```rust + /// let mut dst = [0i, 0, 0]; + /// let src = [1i, 2]; + /// + /// assert!(dst.clone_from_slice(&src) == 2); + /// assert!(dst == [1, 2, 0]); + /// + /// let src2 = [3i, 4, 5, 6]; + /// assert!(dst.clone_from_slice(&src2) == 3); + /// assert!(dst == [3i, 4, 5]); + /// ``` + #[experimental] + fn clone_from_slice(&mut self, &[Self::Item]) -> uint where Self::Item: Clone; + + /// Sorts the slice, in place. + /// + /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`. + /// + /// # Examples + /// + /// ```rust + /// let mut v = [-5i, 4, 1, -3, 2]; + /// + /// v.sort(); + /// assert!(v == [-5i, -3, 1, 2, 4]); + /// ``` + #[stable] + fn sort(&mut self) where Self::Item: Ord; + + /// Binary search a sorted slice for a given element. + /// + /// If the value is found then `Ok` is returned, containing the + /// index of the matching element; if the value is not found then + /// `Err` is returned, containing the index where a matching + /// element could be inserted while maintaining sorted order. + /// + /// # Example + /// + /// Looks up a series of four elements. The first is found, with a + /// uniquely determined position; the second and third are not + /// found; the fourth could match any position in `[1,4]`. + /// + /// ```rust + /// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; + /// let s = s.as_slice(); + /// + /// assert_eq!(s.binary_search(&13), Ok(9)); + /// assert_eq!(s.binary_search(&4), Err(7)); + /// assert_eq!(s.binary_search(&100), Err(13)); + /// let r = s.binary_search(&1); + /// assert!(match r { Ok(1...4) => true, _ => false, }); + /// ``` + #[stable] + fn binary_search(&self, x: &Self::Item) -> Result where Self::Item: Ord; + + /// Deprecated: use `binary_search` instead. + #[deprecated = "use binary_search instead"] + fn binary_search_elem(&self, x: &Self::Item) -> Result where Self::Item: Ord { + self.binary_search(x) + } + + /// Mutates the slice to the next lexicographic permutation. + /// + /// Returns `true` if successful and `false` if the slice is at the + /// last-ordered permutation. + /// + /// # Example + /// + /// ```rust + /// let v: &mut [_] = &mut [0i, 1, 2]; + /// v.next_permutation(); + /// let b: &mut [_] = &mut [0i, 2, 1]; + /// assert!(v == b); + /// v.next_permutation(); + /// let b: &mut [_] = &mut [1i, 0, 2]; + /// assert!(v == b); + /// ``` + #[unstable = "uncertain if this merits inclusion in std"] + fn next_permutation(&mut self) -> bool where Self::Item: Ord; + + /// Mutates the slice to the previous lexicographic permutation. + /// + /// Returns `true` if successful and `false` if the slice is at the + /// first-ordered permutation. + /// + /// # Example + /// + /// ```rust + /// let v: &mut [_] = &mut [1i, 0, 2]; + /// v.prev_permutation(); + /// let b: &mut [_] = &mut [0i, 2, 1]; + /// assert!(v == b); + /// v.prev_permutation(); + /// let b: &mut [_] = &mut [0i, 1, 2]; + /// assert!(v == b); + /// ``` + #[unstable = "uncertain if this merits inclusion in std"] + fn prev_permutation(&mut self) -> bool where Self::Item: Ord; + + /// Find the first index containing a matching value. + #[experimental] + fn position_elem(&self, t: &Self::Item) -> Option where Self::Item: PartialEq; + + /// Find the last index containing a matching value. + #[experimental] + fn rposition_elem(&self, t: &Self::Item) -> Option where Self::Item: PartialEq; + + /// Return true if the slice contains an element with the given value. + #[stable] + fn contains(&self, x: &Self::Item) -> bool where Self::Item: PartialEq; + + /// Returns true if `needle` is a prefix of the slice. + #[stable] + fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq; + + /// Returns true if `needle` is a suffix of the slice. + #[stable] + fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq; + + /// Convert `self` into a vector without clones or allocation. + #[experimental] + fn into_vec(self: Box) -> Vec; } #[unstable = "trait is unstable"] -impl SliceExt for [T] { +impl SliceExt for [T] { + type Item = T; + #[inline] fn sort_by(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering { merge_sort(self, compare) @@ -777,96 +947,10 @@ impl SliceExt for [T] { fn as_mut_ptr(&mut self) -> *mut T { core_slice::SliceExt::as_mut_ptr(self) } -} - -//////////////////////////////////////////////////////////////////////////////// -// Extension traits for slices over specifc kinds of data -//////////////////////////////////////////////////////////////////////////////// - -/// Extension methods for boxed slices. -#[experimental = "likely to merge into SliceExt if it survives"] -pub trait BoxedSliceExt { - /// Convert `self` into a vector without clones or allocation. - #[experimental] - fn into_vec(self) -> Vec; -} - -#[experimental = "trait is experimental"] -impl BoxedSliceExt for Box<[T]> { - fn into_vec(mut self) -> Vec { - unsafe { - let xs = Vec::from_raw_parts(self.as_mut_ptr(), self.len(), self.len()); - mem::forget(self); - xs - } - } -} - -/// Allocating extension methods for slices containing `Clone` elements. -#[unstable = "likely to be merged into SliceExt"] -pub trait CloneSliceExt for Sized? { - /// Copies `self` into a new `Vec`. - #[stable] - fn to_vec(&self) -> Vec; - - /// Deprecated: use `iter().cloned().partition(f)` instead. - #[deprecated = "use iter().cloned().partition(f) instead"] - fn partitioned(&self, f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool; - - /// Creates an iterator that yields every possible permutation of the - /// vector in succession. - /// - /// # Examples - /// - /// ```rust - /// let v = [1i, 2, 3]; - /// let mut perms = v.permutations(); - /// - /// for p in perms { - /// println!("{}", p); - /// } - /// ``` - /// - /// Iterating through permutations one by one. - /// - /// ```rust - /// let v = [1i, 2, 3]; - /// let mut perms = v.permutations(); - /// - /// assert_eq!(Some(vec![1i, 2, 3]), perms.next()); - /// assert_eq!(Some(vec![1i, 3, 2]), perms.next()); - /// assert_eq!(Some(vec![3i, 1, 2]), perms.next()); - /// ``` - #[unstable] - fn permutations(&self) -> Permutations; - - /// Copies as many elements from `src` as it can into `self` (the - /// shorter of `self.len()` and `src.len()`). Returns the number - /// of elements copied. - /// - /// # Example - /// - /// ```rust - /// let mut dst = [0i, 0, 0]; - /// let src = [1i, 2]; - /// - /// assert!(dst.clone_from_slice(&src) == 2); - /// assert!(dst == [1, 2, 0]); - /// - /// let src2 = [3i, 4, 5, 6]; - /// assert!(dst.clone_from_slice(&src2) == 3); - /// assert!(dst == [3i, 4, 5]); - /// ``` - #[experimental] - fn clone_from_slice(&mut self, &[T]) -> uint; -} - -#[unstable = "trait is unstable"] -impl CloneSliceExt for [T] { /// Returns a copy of `v`. #[inline] - fn to_vec(&self) -> Vec { + fn to_vec(&self) -> Vec where T: Clone { let mut vector = Vec::with_capacity(self.len()); vector.push_all(self); vector @@ -874,132 +958,71 @@ impl CloneSliceExt for [T] { #[inline] - fn partitioned(&self, f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool { + fn partitioned(&self, f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool, T: Clone { self.iter().cloned().partition(f) } /// Returns an iterator over all permutations of a vector. - fn permutations(&self) -> Permutations { + fn permutations(&self) -> Permutations where T: Clone { Permutations{ swaps: ElementSwaps::new(self.len()), v: self.to_vec(), } } - fn clone_from_slice(&mut self, src: &[T]) -> uint { - core_slice::CloneSliceExt::clone_from_slice(self, src) + fn clone_from_slice(&mut self, src: &[T]) -> uint where T: Clone { + core_slice::SliceExt::clone_from_slice(self, src) } -} -/// Allocating extension methods for slices on Ord values. -#[unstable = "likely to merge with SliceExt"] -pub trait OrdSliceExt for Sized? { - /// Sorts the slice, in place. - /// - /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`. - /// - /// # Examples - /// - /// ```rust - /// let mut v = [-5i, 4, 1, -3, 2]; - /// - /// v.sort(); - /// assert!(v == [-5i, -3, 1, 2, 4]); - /// ``` - #[stable] - fn sort(&mut self); + #[inline] + fn sort(&mut self) where T: Ord { + self.sort_by(|a, b| a.cmp(b)) + } - /// Binary search a sorted slice for a given element. - /// - /// If the value is found then `Ok` is returned, containing the - /// index of the matching element; if the value is not found then - /// `Err` is returned, containing the index where a matching - /// element could be inserted while maintaining sorted order. - /// - /// # Example - /// - /// Looks up a series of four elements. The first is found, with a - /// uniquely determined position; the second and third are not - /// found; the fourth could match any position in `[1,4]`. - /// - /// ```rust - /// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; - /// let s = s.as_slice(); - /// - /// assert_eq!(s.binary_search(&13), Ok(9)); - /// assert_eq!(s.binary_search(&4), Err(7)); - /// assert_eq!(s.binary_search(&100), Err(13)); - /// let r = s.binary_search(&1); - /// assert!(match r { Ok(1...4) => true, _ => false, }); - /// ``` - #[stable] - fn binary_search(&self, x: &T) -> Result; + fn binary_search(&self, x: &T) -> Result where T: Ord { + core_slice::SliceExt::binary_search(self, x) + } - /// Deprecated: use `binary_search` instead. - #[deprecated = "use binary_search instead"] - fn binary_search_elem(&self, x: &T) -> Result { - self.binary_search(x) + fn next_permutation(&mut self) -> bool where T: Ord { + core_slice::SliceExt::next_permutation(self) } - /// Mutates the slice to the next lexicographic permutation. - /// - /// Returns `true` if successful and `false` if the slice is at the - /// last-ordered permutation. - /// - /// # Example - /// - /// ```rust - /// let v: &mut [_] = &mut [0i, 1, 2]; - /// v.next_permutation(); - /// let b: &mut [_] = &mut [0i, 2, 1]; - /// assert!(v == b); - /// v.next_permutation(); - /// let b: &mut [_] = &mut [1i, 0, 2]; - /// assert!(v == b); - /// ``` - #[unstable = "uncertain if this merits inclusion in std"] - fn next_permutation(&mut self) -> bool; + fn prev_permutation(&mut self) -> bool where T: Ord { + core_slice::SliceExt::prev_permutation(self) + } - /// Mutates the slice to the previous lexicographic permutation. - /// - /// Returns `true` if successful and `false` if the slice is at the - /// first-ordered permutation. - /// - /// # Example - /// - /// ```rust - /// let v: &mut [_] = &mut [1i, 0, 2]; - /// v.prev_permutation(); - /// let b: &mut [_] = &mut [0i, 2, 1]; - /// assert!(v == b); - /// v.prev_permutation(); - /// let b: &mut [_] = &mut [0i, 1, 2]; - /// assert!(v == b); - /// ``` - #[unstable = "uncertain if this merits inclusion in std"] - fn prev_permutation(&mut self) -> bool; -} + fn position_elem(&self, t: &T) -> Option where T: PartialEq { + core_slice::SliceExt::position_elem(self, t) + } -#[unstable = "trait is unstable"] -impl OrdSliceExt for [T] { - #[inline] - fn sort(&mut self) { - self.sort_by(|a, b| a.cmp(b)) + fn rposition_elem(&self, t: &T) -> Option where T: PartialEq { + core_slice::SliceExt::rposition_elem(self, t) } - fn binary_search(&self, x: &T) -> Result { - core_slice::OrdSliceExt::binary_search(self, x) + fn contains(&self, x: &T) -> bool where T: PartialEq { + core_slice::SliceExt::contains(self, x) } - fn next_permutation(&mut self) -> bool { - core_slice::OrdSliceExt::next_permutation(self) + fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq { + core_slice::SliceExt::starts_with(self, needle) } - fn prev_permutation(&mut self) -> bool { - core_slice::OrdSliceExt::prev_permutation(self) + fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq { + core_slice::SliceExt::ends_with(self, needle) + } + + fn into_vec(mut self: Box) -> Vec { + unsafe { + let xs = Vec::from_raw_parts(self.as_mut_ptr(), self.len(), self.len()); + mem::forget(self); + xs + } } } +//////////////////////////////////////////////////////////////////////////////// +// Extension traits for slices over specifc kinds of data +//////////////////////////////////////////////////////////////////////////////// #[unstable = "U should be an associated type"] /// An extension trait for concatenating slices pub trait SliceConcatExt for Sized? { @@ -1419,7 +1442,7 @@ mod tests { use std::boxed::Box; use prelude::{Some, None, range, Vec, ToString, Clone, Greater, Less, Equal}; use prelude::{SliceExt, Iterator, IteratorExt, DoubleEndedIteratorExt}; - use prelude::{OrdSliceExt, CloneSliceExt, PartialEqSliceExt, AsSlice}; + use prelude::AsSlice; use prelude::{RandomAccessIterator, Ord, SliceConcatExt}; use core::cell::Cell; use core::default::Default; diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 37a6e690f5d30..c52993ff353f8 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -27,7 +27,6 @@ use core::raw::Slice as RawSlice; use unicode::str as unicode_str; use unicode::str::Utf16Item; -use slice::CloneSliceExt; use str::{mod, CharRange, FromStr, Utf8Error}; use vec::{DerefVec, Vec, as_vec}; @@ -94,7 +93,7 @@ impl String { #[inline] #[experimental = "needs investigation to see if to_string() can match perf"] pub fn from_str(string: &str) -> String { - String { vec: string.as_bytes().to_vec() } + String { vec: ::slice::SliceExt::to_vec(string.as_bytes()) } } /// Returns the vector as a string buffer, if possible, taking care not to @@ -936,7 +935,9 @@ impl ops::Slice for String { } #[experimental = "waiting on Deref stabilization"] -impl ops::Deref for String { +impl ops::Deref for String { + type Target = str; + fn deref<'a>(&'a self) -> &'a str { unsafe { mem::transmute(self.vec[]) } } @@ -948,7 +949,9 @@ pub struct DerefString<'a> { x: DerefVec<'a, u8> } -impl<'a> Deref for DerefString<'a> { +impl<'a> Deref for DerefString<'a> { + type Target = String; + fn deref<'b>(&'b self) -> &'b String { unsafe { mem::transmute(&*self.x) } } diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index a1952352badfa..140c15b2f7f3a 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -63,8 +63,6 @@ use core::ptr; use core::raw::Slice as RawSlice; use core::uint; -use slice::CloneSliceExt; - /// A growable list type, written `Vec` but pronounced 'vector.' /// /// # Examples @@ -1218,7 +1216,7 @@ unsafe fn dealloc(ptr: *mut T, len: uint) { #[unstable] impl Clone for Vec { - fn clone(&self) -> Vec { self.as_slice().to_vec() } + fn clone(&self) -> Vec { ::slice::SliceExt::to_vec(self.as_slice()) } fn clone_from(&mut self, other: &Vec) { // drop anything in self that will not be overwritten @@ -1303,12 +1301,14 @@ impl ops::SliceMut for Vec { } #[experimental = "waiting on Deref stability"] -impl ops::Deref<[T]> for Vec { +impl ops::Deref for Vec { + type Target = [T]; + fn deref<'a>(&'a self) -> &'a [T] { self.as_slice() } } #[experimental = "waiting on DerefMut stability"] -impl ops::DerefMut<[T]> for Vec { +impl ops::DerefMut for Vec { fn deref_mut<'a>(&'a mut self) -> &'a mut [T] { self.as_mut_slice() } } @@ -1718,7 +1718,9 @@ pub struct DerefVec<'a, T> { } #[experimental] -impl<'a, T> Deref> for DerefVec<'a, T> { +impl<'a, T> Deref for DerefVec<'a, T> { + type Target = Vec; + fn deref<'b>(&'b self) -> &'b Vec { &self.x } diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 28563a60b6164..ba7714ad9bc8c 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -54,7 +54,7 @@ macro_rules! array_impls { #[stable] impl<'a, A, B, Rhs> PartialEq for [A; $N] where A: PartialEq, - Rhs: Deref<[B]>, + Rhs: Deref, { #[inline(always)] fn eq(&self, other: &Rhs) -> bool { PartialEq::eq(self[], &**other) } @@ -65,7 +65,7 @@ macro_rules! array_impls { #[stable] impl<'a, A, B, Lhs> PartialEq<[B; $N]> for Lhs where A: PartialEq, - Lhs: Deref<[A]> + Lhs: Deref { #[inline(always)] fn eq(&self, other: &[B; $N]) -> bool { PartialEq::eq(&**self, other[]) } diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index 3a2cb8ea7d984..7e4d73d598d8d 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -191,7 +191,9 @@ impl<'a, T, Sized? B> Cow<'a, T, B> where B: ToOwned { } } -impl<'a, T, Sized? B> Deref for Cow<'a, T, B> where B: ToOwned { +impl<'a, T, Sized? B> Deref for Cow<'a, T, B> where B: ToOwned { + type Target = B; + fn deref(&self) -> &B { match *self { Borrowed(borrowed) => borrowed, diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 4b246860006ab..4939fc49958ce 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -422,7 +422,9 @@ pub struct Ref<'b, T:'b> { } #[unstable = "waiting for `Deref` to become stable"] -impl<'b, T> Deref for Ref<'b, T> { +impl<'b, T> Deref for Ref<'b, T> { + type Target = T; + #[inline] fn deref<'a>(&'a self) -> &'a T { self._value @@ -478,7 +480,9 @@ pub struct RefMut<'b, T:'b> { } #[unstable = "waiting for `Deref` to become stable"] -impl<'b, T> Deref for RefMut<'b, T> { +impl<'b, T> Deref for RefMut<'b, T> { + type Target = T; + #[inline] fn deref<'a>(&'a self) -> &'a T { self._value @@ -486,7 +490,7 @@ impl<'b, T> Deref for RefMut<'b, T> { } #[unstable = "waiting for `DerefMut` to become stable"] -impl<'b, T> DerefMut for RefMut<'b, T> { +impl<'b, T> DerefMut for RefMut<'b, T> { #[inline] fn deref_mut<'a>(&'a mut self) -> &'a mut T { self._value diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 7c53503b1ceb7..64bbc248ee1bc 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -1174,7 +1174,7 @@ pub trait IteratorCloneExt { } #[unstable = "trait is unstable"] -impl, I: Iterator> IteratorCloneExt for I { +impl, I: Iterator> IteratorCloneExt for I { fn cloned(self) -> Cloned { Cloned { it: self } } @@ -1185,7 +1185,7 @@ pub struct Cloned { it: I, } -impl, I: Iterator> Iterator for Cloned { +impl, I: Iterator> Iterator for Cloned { fn next(&mut self) -> Option { self.it.next().cloned() } @@ -1195,7 +1195,7 @@ impl, I: Iterator> Iterator for Cloned { } } -impl, I: DoubleEndedIterator> +impl, I: DoubleEndedIterator> DoubleEndedIterator for Cloned { fn next_back(&mut self) -> Option { self.it.next_back().cloned() @@ -1203,7 +1203,7 @@ impl, I: DoubleEndedIterator> } #[unstable = "trait is unstable"] -impl, I: ExactSizeIterator> ExactSizeIterator for Cloned {} +impl, I: ExactSizeIterator> ExactSizeIterator for Cloned {} #[unstable = "recently renamed for extension trait conventions"] /// An extension trait for cloneable iterators. diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index c429e4b8212bc..ba9103520d875 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -44,7 +44,9 @@ impl NonZero { } } -impl Deref for NonZero { +impl Deref for NonZero { + type Target = T; + #[inline] fn deref<'a>(&'a self) -> &'a T { let NonZero(ref inner) = *self; diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index af07869e95feb..17a3c93d98074 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -827,11 +827,14 @@ pub struct RangeTo { /// struct. /// /// ``` +/// #![feature(associated_types)] /// struct DerefExample { /// value: T /// } /// -/// impl Deref for DerefExample { +/// impl Deref for DerefExample { +/// type Target = T; +/// /// fn deref<'a>(&'a self) -> &'a T { /// &self.value /// } @@ -843,16 +846,22 @@ pub struct RangeTo { /// } /// ``` #[lang="deref"] -pub trait Deref for Sized? { +pub trait Deref for Sized? { + type Sized? Target; + /// The method called to dereference a value - fn deref<'a>(&'a self) -> &'a Result; + fn deref<'a>(&'a self) -> &'a Self::Target; } -impl<'a, Sized? T> Deref for &'a T { +impl<'a, Sized? T> Deref for &'a T { + type Target = T; + fn deref(&self) -> &T { *self } } -impl<'a, Sized? T> Deref for &'a mut T { +impl<'a, Sized? T> Deref for &'a mut T { + type Target = T; + fn deref(&self) -> &T { *self } } @@ -865,17 +874,20 @@ impl<'a, Sized? T> Deref for &'a mut T { /// struct. /// /// ``` +/// #![feature(associated_types)] /// struct DerefMutExample { /// value: T /// } /// -/// impl Deref for DerefMutExample { +/// impl Deref for DerefMutExample { +/// type Target = T; +/// /// fn deref<'a>(&'a self) -> &'a T { /// &self.value /// } /// } /// -/// impl DerefMut for DerefMutExample { +/// impl DerefMut for DerefMutExample { /// fn deref_mut<'a>(&'a mut self) -> &'a mut T { /// &mut self.value /// } @@ -888,12 +900,12 @@ impl<'a, Sized? T> Deref for &'a mut T { /// } /// ``` #[lang="deref_mut"] -pub trait DerefMut for Sized? : Deref { +pub trait DerefMut for Sized? : Deref { /// The method called to mutably dereference a value - fn deref_mut<'a>(&'a mut self) -> &'a mut Result; + fn deref_mut<'a>(&'a mut self) -> &'a mut ::Target; } -impl<'a, Sized? T> DerefMut for &'a mut T { +impl<'a, Sized? T> DerefMut for &'a mut T { fn deref_mut(&mut self) -> &mut T { *self } } diff --git a/src/libcore/option.rs b/src/libcore/option.rs index d831a57893bd7..b9749f57d5832 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -699,7 +699,7 @@ impl Option { } } -impl<'a, T: Clone, D: Deref> Option { +impl<'a, T: Clone, D: Deref> Option { /// Maps an Option to an Option by dereffing and cloning the contents of the Option. /// Useful for converting an Option<&T> to an Option. #[unstable = "recently added as part of collections reform"] diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index cecb493815380..19301cc2d9e32 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -64,5 +64,4 @@ pub use str::{Str, StrExt}; pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4}; pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8}; pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12}; -pub use slice::{PartialEqSliceExt, OrdSliceExt}; pub use slice::{AsSlice, SliceExt}; diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index faf1d781465c7..09c78d4bc2a46 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -243,7 +243,9 @@ pub unsafe fn write(dst: *mut T, src: T) { /// Methods on raw pointers #[stable] -pub trait PtrExt { +pub trait PtrExt { + type Target; + /// Returns the null pointer. #[deprecated = "call ptr::null instead"] fn null() -> Self; @@ -271,7 +273,7 @@ pub trait PtrExt { /// memory. #[unstable = "Option is not clearly the right return type, and we may want \ to tie the return lifetime to a borrow of the raw pointer"] - unsafe fn as_ref<'a>(&self) -> Option<&'a T>; + unsafe fn as_ref<'a>(&self) -> Option<&'a Self::Target>; /// Calculates the offset from a pointer. `count` is in units of T; e.g. a /// `count` of 3 represents a pointer offset of `3 * sizeof::()` bytes. @@ -287,7 +289,9 @@ pub trait PtrExt { /// Methods on mutable raw pointers #[stable] -pub trait MutPtrExt{ +pub trait MutPtrExt { + type Target; + /// Returns `None` if the pointer is null, or else returns a mutable /// reference to the value wrapped in `Some`. /// @@ -297,11 +301,13 @@ pub trait MutPtrExt{ /// of the returned pointer. #[unstable = "Option is not clearly the right return type, and we may want \ to tie the return lifetime to a borrow of the raw pointer"] - unsafe fn as_mut<'a>(&self) -> Option<&'a mut T>; + unsafe fn as_mut<'a>(&self) -> Option<&'a mut Self::Target>; } #[stable] -impl PtrExt for *const T { +impl PtrExt for *const T { + type Target = T; + #[inline] #[deprecated = "call ptr::null instead"] fn null() -> *const T { null() } @@ -333,7 +339,9 @@ impl PtrExt for *const T { } #[stable] -impl PtrExt for *mut T { +impl PtrExt for *mut T { + type Target = T; + #[inline] #[deprecated = "call ptr::null instead"] fn null() -> *mut T { null_mut() } @@ -365,7 +373,9 @@ impl PtrExt for *mut T { } #[stable] -impl MutPtrExt for *mut T { +impl MutPtrExt for *mut T { + type Target = T; + #[inline] #[unstable = "return value does not necessarily convey all possible \ information"] diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 7d894ac697be2..07addf7a56969 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -64,57 +64,77 @@ use raw::Slice as RawSlice; /// Extension methods for slices. #[allow(missing_docs)] // docs in libcollections -pub trait SliceExt for Sized? { - fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T]; - fn slice_from<'a>(&'a self, start: uint) -> &'a [T]; - fn slice_to<'a>(&'a self, end: uint) -> &'a [T]; - fn split_at<'a>(&'a self, mid: uint) -> (&'a [T], &'a [T]); - fn iter<'a>(&'a self) -> Iter<'a, T>; - fn split<'a, P>(&'a self, pred: P) -> Split<'a, T, P> - where P: FnMut(&T) -> bool; - fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitN<'a, T, P> - where P: FnMut(&T) -> bool; - fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> RSplitN<'a, T, P> - where P: FnMut(&T) -> bool; - fn windows<'a>(&'a self, size: uint) -> Windows<'a, T>; - fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, T>; - fn get<'a>(&'a self, index: uint) -> Option<&'a T>; - fn first<'a>(&'a self) -> Option<&'a T>; - fn tail<'a>(&'a self) -> &'a [T]; - fn init<'a>(&'a self) -> &'a [T]; - fn last<'a>(&'a self) -> Option<&'a T>; - unsafe fn get_unchecked<'a>(&'a self, index: uint) -> &'a T; - fn as_ptr(&self) -> *const T; +pub trait SliceExt for Sized? { + 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> + where P: FnMut(&Self::Item) -> bool; + fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitN<'a, Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> RSplitN<'a, Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + fn windows<'a>(&'a self, size: uint) -> Windows<'a, Self::Item>; + fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, Self::Item>; + fn get<'a>(&'a self, index: uint) -> Option<&'a Self::Item>; + fn first<'a>(&'a self) -> Option<&'a Self::Item>; + fn tail<'a>(&'a self) -> &'a [Self::Item]; + fn init<'a>(&'a self) -> &'a [Self::Item]; + fn last<'a>(&'a self) -> Option<&'a Self::Item>; + unsafe fn get_unchecked<'a>(&'a self, index: uint) -> &'a Self::Item; + fn as_ptr(&self) -> *const Self::Item; fn binary_search_by(&self, f: F) -> Result where - F: FnMut(&T) -> Ordering; + F: FnMut(&Self::Item) -> Ordering; fn len(&self) -> uint; fn is_empty(&self) -> bool { self.len() == 0 } - fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut T>; - fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T]; - fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [T]; - fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T]; - fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T]; - fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T>; - fn first_mut<'a>(&'a mut self) -> Option<&'a mut T>; - fn tail_mut<'a>(&'a mut self) -> &'a mut [T]; - fn init_mut<'a>(&'a mut self) -> &'a mut [T]; - fn last_mut<'a>(&'a mut self) -> Option<&'a mut T>; - fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, T, P> - where P: FnMut(&T) -> bool; - fn splitn_mut

(&mut self, n: uint, pred: P) -> SplitNMut - where P: FnMut(&T) -> bool; - fn rsplitn_mut

(&mut self, n: uint, pred: P) -> RSplitNMut - where P: FnMut(&T) -> bool; - fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> ChunksMut<'a, T>; + 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]; + fn init_mut<'a>(&'a mut self) -> &'a mut [Self::Item]; + fn last_mut<'a>(&'a mut self) -> Option<&'a mut Self::Item>; + fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + fn splitn_mut

(&mut self, n: uint, pred: P) -> SplitNMut + where P: FnMut(&Self::Item) -> bool; + fn rsplitn_mut

(&mut self, n: uint, pred: P) -> RSplitNMut + where P: FnMut(&Self::Item) -> bool; + fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> ChunksMut<'a, Self::Item>; fn swap(&mut self, a: uint, b: uint); - fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]); + fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [Self::Item], &'a mut [Self::Item]); fn reverse(&mut self); - unsafe fn get_unchecked_mut<'a>(&'a mut self, index: uint) -> &'a mut T; - fn as_mut_ptr(&mut self) -> *mut T; + unsafe fn get_unchecked_mut<'a>(&'a mut self, index: uint) -> &'a mut Self::Item; + fn as_mut_ptr(&mut self) -> *mut Self::Item; + + fn position_elem(&self, t: &Self::Item) -> Option where Self::Item: PartialEq; + + fn rposition_elem(&self, t: &Self::Item) -> Option where Self::Item: PartialEq; + + fn contains(&self, x: &Self::Item) -> bool where Self::Item: PartialEq; + + fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq; + + fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq; + + fn binary_search(&self, x: &Self::Item) -> Result where Self::Item: Ord; + fn next_permutation(&mut self) -> bool where Self::Item: Ord; + fn prev_permutation(&mut self) -> bool where Self::Item: Ord; + + fn clone_from_slice(&mut self, &[Self::Item]) -> uint where Self::Item: Clone; } #[unstable] -impl SliceExt for [T] { +impl SliceExt for [T] { + type Item = T; + #[inline] fn slice(&self, start: uint, end: uint) -> &[T] { assert!(start <= end); @@ -404,153 +424,41 @@ impl SliceExt for [T] { fn as_mut_ptr(&mut self) -> *mut T { self.repr().data as *mut T } -} - -impl ops::Index for [T] { - fn index(&self, &index: &uint) -> &T { - assert!(index < self.len()); - - unsafe { mem::transmute(self.repr().data.offset(index as int)) } - } -} - -impl ops::IndexMut for [T] { - fn index_mut(&mut self, &index: &uint) -> &mut T { - assert!(index < self.len()); - - unsafe { mem::transmute(self.repr().data.offset(index as int)) } - } -} - -impl ops::Slice for [T] { - #[inline] - fn as_slice_<'a>(&'a self) -> &'a [T] { - self - } - - #[inline] - fn slice_from_or_fail<'a>(&'a self, start: &uint) -> &'a [T] { - self.slice_or_fail(start, &self.len()) - } - - #[inline] - fn slice_to_or_fail<'a>(&'a self, end: &uint) -> &'a [T] { - self.slice_or_fail(&0, end) - } - #[inline] - fn slice_or_fail<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] { - assert!(*start <= *end); - assert!(*end <= self.len()); - unsafe { - transmute(RawSlice { - data: self.as_ptr().offset(*start as int), - len: (*end - *start) - }) - } - } -} - -impl ops::SliceMut for [T] { - #[inline] - fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] { - self - } - - #[inline] - fn slice_from_or_fail_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] { - let len = &self.len(); - self.slice_or_fail_mut(start, len) - } - - #[inline] - fn slice_to_or_fail_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] { - self.slice_or_fail_mut(&0, end) - } - #[inline] - fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] { - assert!(*start <= *end); - assert!(*end <= self.len()); - unsafe { - transmute(RawSlice { - data: self.as_ptr().offset(*start as int), - len: (*end - *start) - }) - } - } -} - -/// Extension methods for slices containing `PartialEq` elements. -#[unstable = "may merge with SliceExt"] -pub trait PartialEqSliceExt for Sized? { - /// Find the first index containing a matching value. - #[experimental] - fn position_elem(&self, t: &T) -> Option; - - /// Find the last index containing a matching value. - #[experimental] - fn rposition_elem(&self, t: &T) -> Option; - - /// Return true if the slice contains an element with the given value. - #[stable] - fn contains(&self, x: &T) -> bool; - - /// Returns true if `needle` is a prefix of the slice. - #[stable] - fn starts_with(&self, needle: &[T]) -> bool; - - /// Returns true if `needle` is a suffix of the slice. - #[stable] - fn ends_with(&self, needle: &[T]) -> bool; -} -#[unstable = "trait is unstable"] -impl PartialEqSliceExt for [T] { #[inline] - fn position_elem(&self, x: &T) -> Option { + fn position_elem(&self, x: &T) -> Option where T: PartialEq { self.iter().position(|y| *x == *y) } #[inline] - fn rposition_elem(&self, t: &T) -> Option { + fn rposition_elem(&self, t: &T) -> Option where T: PartialEq { self.iter().rposition(|x| *x == *t) } #[inline] - fn contains(&self, x: &T) -> bool { + fn contains(&self, x: &T) -> bool where T: PartialEq { self.iter().any(|elt| *x == *elt) } #[inline] - fn starts_with(&self, needle: &[T]) -> bool { + fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq { let n = needle.len(); self.len() >= n && needle == self[..n] } #[inline] - fn ends_with(&self, needle: &[T]) -> bool { + fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq { let (m, n) = (self.len(), needle.len()); m >= n && needle == self[m-n..] } -} -/// Extension methods for slices containing `Ord` elements. -#[unstable = "may merge with other traits"] -#[allow(missing_docs)] // docs in libcollections -pub trait OrdSliceExt for Sized? { - fn binary_search(&self, x: &T) -> Result; - fn next_permutation(&mut self) -> bool; - fn prev_permutation(&mut self) -> bool; -} - -#[unstable = "trait is unstable"] -impl OrdSliceExt for [T] { #[unstable] - fn binary_search(&self, x: &T) -> Result { + fn binary_search(&self, x: &T) -> Result where T: Ord { self.binary_search_by(|p| p.cmp(x)) } #[experimental] - fn next_permutation(&mut self) -> bool { + fn next_permutation(&mut self) -> bool where T: Ord { // These cases only have 1 permutation each, so we can't do anything. if self.len() < 2 { return false; } @@ -581,7 +489,7 @@ impl OrdSliceExt for [T] { } #[experimental] - fn prev_permutation(&mut self) -> bool { + fn prev_permutation(&mut self) -> bool where T: Ord { // These cases only have 1 permutation each, so we can't do anything. if self.len() < 2 { return false; } @@ -610,19 +518,9 @@ impl OrdSliceExt for [T] { true } -} -/// Extension methods for slices on Clone elements -#[unstable = "may merge with other traits"] -#[allow(missing_docs)] // docs in libcollections -pub trait CloneSliceExt for Sized? { - fn clone_from_slice(&mut self, &[T]) -> uint; -} - -#[unstable = "trait is unstable"] -impl CloneSliceExt for [T] { #[inline] - fn clone_from_slice(&mut self, src: &[T]) -> uint { + 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); @@ -633,6 +531,79 @@ impl CloneSliceExt for [T] { } } +impl ops::Index for [T] { + fn index(&self, &index: &uint) -> &T { + assert!(index < self.len()); + + unsafe { mem::transmute(self.repr().data.offset(index as int)) } + } +} + +impl ops::IndexMut for [T] { + fn index_mut(&mut self, &index: &uint) -> &mut T { + assert!(index < self.len()); + + unsafe { mem::transmute(self.repr().data.offset(index as int)) } + } +} + +impl ops::Slice for [T] { + #[inline] + fn as_slice_<'a>(&'a self) -> &'a [T] { + self + } + + #[inline] + fn slice_from_or_fail<'a>(&'a self, start: &uint) -> &'a [T] { + self.slice_or_fail(start, &self.len()) + } + + #[inline] + fn slice_to_or_fail<'a>(&'a self, end: &uint) -> &'a [T] { + self.slice_or_fail(&0, end) + } + #[inline] + fn slice_or_fail<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] { + assert!(*start <= *end); + assert!(*end <= self.len()); + unsafe { + transmute(RawSlice { + data: self.as_ptr().offset(*start as int), + len: (*end - *start) + }) + } + } +} + +impl ops::SliceMut for [T] { + #[inline] + fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] { + self + } + + #[inline] + fn slice_from_or_fail_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] { + let len = &self.len(); + self.slice_or_fail_mut(start, len) + } + + #[inline] + fn slice_to_or_fail_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] { + self.slice_or_fail_mut(&0, end) + } + #[inline] + fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] { + assert!(*start <= *end); + assert!(*end <= self.len()); + unsafe { + transmute(RawSlice { + data: self.as_ptr().offset(*start as int), + len: (*end - *start) + }) + } + } +} + //////////////////////////////////////////////////////////////////////////////// // Common traits //////////////////////////////////////////////////////////////////////////////// diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index c84f31bf6c3bc..125f39b1a43e5 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -21,8 +21,10 @@ use super::VtableImplData; use middle::infer; use middle::subst::Subst; -use middle::ty::{mod, AsPredicate, RegionEscape, HasProjectionTypes, ToPolyTraitRef, Ty}; +use middle::ty::{mod, AsPredicate, ReferencesError, RegionEscape, + HasProjectionTypes, ToPolyTraitRef, Ty}; use middle::ty_fold::{mod, TypeFoldable, TypeFolder}; +use std::rc::Rc; use util::ppaux::Repr; pub type PolyProjectionObligation<'tcx> = @@ -372,6 +374,15 @@ fn project_type<'cx,'tcx>( return Err(ProjectionTyError::TraitSelectionError(Overflow)); } + let obligation_trait_ref = + selcx.infcx().resolve_type_vars_if_possible(&obligation.predicate.trait_ref); + + debug!("project: obligation_trait_ref={}", obligation_trait_ref.repr(selcx.tcx())); + + if obligation_trait_ref.references_error() { + return Ok(ProjectedTy::Progress(selcx.tcx().types.err, vec!())); + } + let mut candidates = ProjectionTyCandidateSet { vec: Vec::new(), ambiguous: false, @@ -379,15 +390,18 @@ fn project_type<'cx,'tcx>( assemble_candidates_from_object_type(selcx, obligation, + &obligation_trait_ref, &mut candidates); if candidates.vec.is_empty() { assemble_candidates_from_param_env(selcx, obligation, + &obligation_trait_ref, &mut candidates); if let Err(e) = assemble_candidates_from_impls(selcx, obligation, + &obligation_trait_ref, &mut candidates) { return Err(ProjectionTyError::TraitSelectionError(e)); } @@ -421,17 +435,20 @@ fn project_type<'cx,'tcx>( /// there that can answer this question. fn assemble_candidates_from_param_env<'cx,'tcx>( selcx: &mut SelectionContext<'cx,'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTyObligation<'tcx>, + obligation_trait_ref: &Rc>, candidate_set: &mut ProjectionTyCandidateSet<'tcx>) { let env_predicates = selcx.param_env().caller_bounds.predicates.clone(); let env_predicates = env_predicates.iter().cloned().collect(); - assemble_candidates_from_predicates(selcx, obligation, candidate_set, env_predicates); + assemble_candidates_from_predicates(selcx, obligation, obligation_trait_ref, + candidate_set, env_predicates); } fn assemble_candidates_from_predicates<'cx,'tcx>( selcx: &mut SelectionContext<'cx,'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTyObligation<'tcx>, + obligation_trait_ref: &Rc>, candidate_set: &mut ProjectionTyCandidateSet<'tcx>, env_predicates: Vec>) { @@ -445,7 +462,7 @@ fn assemble_candidates_from_predicates<'cx,'tcx>( let is_match = infcx.probe(|_| { let origin = infer::Misc(obligation.cause.span); let obligation_poly_trait_ref = - obligation.predicate.trait_ref.to_poly_trait_ref(); + obligation_trait_ref.to_poly_trait_ref(); let data_poly_trait_ref = data.to_poly_trait_ref(); infcx.sub_poly_trait_refs(false, @@ -466,14 +483,14 @@ fn assemble_candidates_from_predicates<'cx,'tcx>( fn assemble_candidates_from_object_type<'cx,'tcx>( selcx: &mut SelectionContext<'cx,'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTyObligation<'tcx>, + obligation_trait_ref: &Rc>, candidate_set: &mut ProjectionTyCandidateSet<'tcx>) { let infcx = selcx.infcx(); - let trait_ref = infcx.resolve_type_vars_if_possible(&obligation.predicate.trait_ref); debug!("assemble_candidates_from_object_type(trait_ref={})", - trait_ref.repr(infcx.tcx)); - let self_ty = trait_ref.self_ty(); + obligation_trait_ref.repr(infcx.tcx)); + let self_ty = obligation_trait_ref.self_ty(); let data = match self_ty.sty { ty::ty_trait(ref data) => data, _ => { return; } @@ -482,21 +499,21 @@ fn assemble_candidates_from_object_type<'cx,'tcx>( let env_predicates = projection_bounds.iter() .map(|p| p.as_predicate()) .collect(); - assemble_candidates_from_predicates(selcx, obligation, candidate_set, env_predicates) + assemble_candidates_from_predicates(selcx, obligation, obligation_trait_ref, + candidate_set, env_predicates) } fn assemble_candidates_from_impls<'cx,'tcx>( selcx: &mut SelectionContext<'cx,'tcx>, obligation: &ProjectionTyObligation<'tcx>, + obligation_trait_ref: &Rc>, candidate_set: &mut ProjectionTyCandidateSet<'tcx>) -> Result<(), SelectionError<'tcx>> { // If we are resolving `>::Item == Type`, // start out by selecting the predicate `T as TraitRef<...>`: - let trait_ref = - obligation.predicate.trait_ref.to_poly_trait_ref(); - let trait_obligation = - obligation.with(trait_ref.to_poly_trait_predicate()); + let poly_trait_ref = obligation_trait_ref.to_poly_trait_ref(); + let trait_obligation = obligation.with(poly_trait_ref.to_poly_trait_predicate()); let vtable = match selcx.select(&trait_obligation) { Ok(Some(vtable)) => vtable, Ok(None) => { diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index f9dced088f8c1..a7eb883f337ed 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -289,6 +289,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } + fn evaluate_predicates_recursively<'a,'o,I>(&mut self, + stack: Option<&TraitObligationStack<'o, 'tcx>>, + mut predicates: I) + -> EvaluationResult<'tcx> + where I : Iterator<&'a PredicateObligation<'tcx>>, 'tcx:'a + { + let mut result = EvaluatedToOk; + for obligation in predicates { + match self.evaluate_predicate_recursively(stack, obligation) { + EvaluatedToErr(e) => { return EvaluatedToErr(e); } + EvaluatedToAmbig => { result = EvaluatedToAmbig; } + EvaluatedToOk => { } + } + } + result + } + fn evaluate_predicate_recursively<'o>(&mut self, previous_stack: Option<&TraitObligationStack<'o, 'tcx>>, obligation: &PredicateObligation<'tcx>) @@ -320,9 +337,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { EvaluatedToOk } - ty::Predicate::Projection(..) => { - // FIXME(#20296) -- we should be able to give a more precise answer here - EvaluatedToAmbig + ty::Predicate::Projection(ref data) => { + self.infcx.probe(|_| { + let project_obligation = obligation.with(data.clone()); + match project::poly_project_and_unify_type(self, &project_obligation) { + Ok(Some(subobligations)) => { + self.evaluate_predicates_recursively(previous_stack, + subobligations.iter()) + } + Ok(None) => { + EvaluatedToAmbig + } + Err(_) => { + EvaluatedToErr(Unimplemented) + } + } + }) } } } @@ -1026,15 +1056,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { selection: Selection<'tcx>) -> EvaluationResult<'tcx> { - let mut result = EvaluatedToOk; - for obligation in selection.iter_nested() { - match self.evaluate_predicate_recursively(stack, obligation) { - EvaluatedToErr(e) => { return EvaluatedToErr(e); } - EvaluatedToAmbig => { result = EvaluatedToAmbig; } - EvaluatedToOk => { } - } - } - result + self.evaluate_predicates_recursively(stack, selection.iter_nested()) } /// Returns true if `candidate_i` should be dropped in favor of `candidate_j`. diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 7bc5d3d070894..399d537088c7b 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -7269,7 +7269,7 @@ impl ReferencesError for Binder { impl ReferencesError for Rc { fn references_error(&self) -> bool { - (&*self).references_error() + (&**self).references_error() } } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 7dbcc810b571b..56459b722251e 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -95,13 +95,15 @@ struct GraphBuilder<'a, 'b:'a, 'tcx:'b> { resolver: &'a mut Resolver<'b, 'tcx> } -impl<'a, 'b:'a, 'tcx:'b> Deref> for GraphBuilder<'a, 'b, 'tcx> { +impl<'a, 'b:'a, 'tcx:'b> Deref for GraphBuilder<'a, 'b, 'tcx> { + type Target = Resolver<'b, 'tcx>; + fn deref(&self) -> &Resolver<'b, 'tcx> { &*self.resolver } } -impl<'a, 'b:'a, 'tcx:'b> DerefMut> for GraphBuilder<'a, 'b, 'tcx> { +impl<'a, 'b:'a, 'tcx:'b> DerefMut for GraphBuilder<'a, 'b, 'tcx> { fn deref_mut(&mut self) -> &mut Resolver<'b, 'tcx> { &mut *self.resolver } diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 78527315199ca..4395bb05040c8 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -33,13 +33,15 @@ struct UnusedImportCheckVisitor<'a, 'b:'a, 'tcx:'b> { } // Deref and DerefMut impls allow treating UnusedImportCheckVisitor as Resolver. -impl<'a, 'b, 'tcx:'b> Deref> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { +impl<'a, 'b, 'tcx:'b> Deref for UnusedImportCheckVisitor<'a, 'b, 'tcx> { + type Target = Resolver<'b, 'tcx>; + fn deref<'c>(&'c self) -> &'c Resolver<'b, 'tcx> { &*self.resolver } } -impl<'a, 'b, 'tcx:'b> DerefMut> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { +impl<'a, 'b, 'tcx:'b> DerefMut for UnusedImportCheckVisitor<'a, 'b, 'tcx> { fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b, 'tcx> { &mut *self.resolver } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 10756f21551a0..75731b5e7cda5 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -18,6 +18,7 @@ #![feature(globs, phase, slicing_syntax)] #![feature(rustc_diagnostic_macros)] +#![feature(associated_types)] #[phase(plugin, link)] extern crate log; #[phase(plugin, link)] extern crate syntax; diff --git a/src/librustc_resolve/record_exports.rs b/src/librustc_resolve/record_exports.rs index 9c2437c376ddd..9bfed1e8eb9c1 100644 --- a/src/librustc_resolve/record_exports.rs +++ b/src/librustc_resolve/record_exports.rs @@ -34,13 +34,15 @@ struct ExportRecorder<'a, 'b:'a, 'tcx:'b> { } // Deref and DerefMut impls allow treating ExportRecorder as Resolver. -impl<'a, 'b, 'tcx:'b> Deref> for ExportRecorder<'a, 'b, 'tcx> { +impl<'a, 'b, 'tcx:'b> Deref for ExportRecorder<'a, 'b, 'tcx> { + type Target = Resolver<'b, 'tcx>; + fn deref<'c>(&'c self) -> &'c Resolver<'b, 'tcx> { &*self.resolver } } -impl<'a, 'b, 'tcx:'b> DerefMut> for ExportRecorder<'a, 'b, 'tcx> { +impl<'a, 'b, 'tcx:'b> DerefMut for ExportRecorder<'a, 'b, 'tcx> { fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b, 'tcx> { &mut *self.resolver } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index f8a0b88b4088d..e95b8d3d8ab24 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1811,6 +1811,18 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, Ok(()) } +fn assoc_type(w: &mut fmt::Formatter, it: &clean::Item, + typ: &clean::TyParam) -> fmt::Result { + try!(write!(w, "type {}", it.name.as_ref().unwrap())); + if typ.bounds.len() > 0 { + try!(write!(w, ": {}", TyParamBounds(&*typ.bounds))) + } + if let Some(ref default) = typ.default { + try!(write!(w, " = {}", default)); + } + Ok(()) +} + fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result { fn method(w: &mut fmt::Formatter, it: &clean::Item, unsafety: ast::Unsafety, g: &clean::Generics, selfty: &clean::SelfTy, @@ -1827,17 +1839,6 @@ fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result { decl = Method(selfty, d), where_clause = WhereClause(g)) } - fn assoc_type(w: &mut fmt::Formatter, it: &clean::Item, - typ: &clean::TyParam) -> fmt::Result { - try!(write!(w, "type {}", it.name.as_ref().unwrap())); - if typ.bounds.len() > 0 { - try!(write!(w, ": {}", TyParamBounds(&*typ.bounds))) - } - if let Some(ref default) = typ.default { - try!(write!(w, " = {}", default)); - } - Ok(()) - } match meth.inner { clean::TyMethodItem(ref m) => { method(w, meth, m.unsafety, &m.generics, &m.self_, &m.decl) @@ -2122,6 +2123,15 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result { try!(write!(w, "type {} = {}", name, tydef.type_)); try!(write!(w, "\n")); } + clean::AssociatedTypeItem(ref typaram) => { + let name = item.name.as_ref().unwrap(); + try!(write!(w, "

{}", + *name, + shortty(item), + ConciseStability(&item.stability))); + try!(assoc_type(w, item, typaram)); + try!(write!(w, "

\n")); + } _ => panic!("can't make docs for trait item with name {}", item.name) } match item.doc_value() { diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs index 46498610e5604..a11a4408019c1 100644 --- a/src/libstd/c_str.rs +++ b/src/libstd/c_str.rs @@ -539,7 +539,7 @@ pub unsafe fn from_c_multistring(buf: *const libc::c_char, #[cfg(test)] mod tests { use super::*; - use prelude::{spawn, Some, None, Option, FnOnce, ToString, CloneSliceExt}; + use prelude::{spawn, Some, None, Option, FnOnce, ToString}; use prelude::{Clone, PtrExt, Iterator, SliceExt, StrExt}; use ptr; use thread::Thread; diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index f6063df543489..e61b9af5a12b1 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -311,7 +311,7 @@ fn search_hashed(table: M, hash: SafeHash, mut is_match: F) -> SearchResult where - M: Deref>, + M: Deref>, F: FnMut(&K) -> bool, { let size = table.size(); diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 6938ab9b0b6d7..a687ba3da8d7f 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -210,7 +210,7 @@ impl Bucket { } } -impl>> Bucket { +impl>> Bucket { pub fn new(table: M, hash: SafeHash) -> Bucket { Bucket::at_index(table, hash.inspect() as uint) } @@ -279,7 +279,7 @@ impl>> Bucket { } } -impl>> EmptyBucket { +impl>> EmptyBucket { #[inline] pub fn next(self) -> Bucket { let mut bucket = self.into_bucket(); @@ -315,7 +315,7 @@ impl>> EmptyBucket { } } -impl>> EmptyBucket { +impl> + DerefMut> EmptyBucket { /// Puts given key and value pair, along with the key's hash, /// into this bucket in the hashtable. Note how `self` is 'moved' into /// this function, because this slot will no longer be empty when @@ -337,7 +337,7 @@ impl>> EmptyBucket { } } -impl>> FullBucket { +impl>> FullBucket { #[inline] pub fn next(self) -> Bucket { let mut bucket = self.into_bucket(); @@ -384,7 +384,7 @@ impl>> FullBucket { } } -impl>> FullBucket { +impl> + DerefMut> FullBucket { /// Removes this bucket's key and value from the hashtable. /// /// This works similarly to `put`, building an `EmptyBucket` out of the @@ -428,7 +428,7 @@ impl>> FullBucket { } } -impl<'t, K, V, M: Deref> + 't> FullBucket { +impl<'t, K, V, M: Deref> + 't> FullBucket { /// Exchange a bucket state for immutable references into the table. /// Because the underlying reference to the table is also consumed, /// no further changes to the structure of the table are possible; @@ -442,7 +442,7 @@ impl<'t, K, V, M: Deref> + 't> FullBucket { } } -impl<'t, K, V, M: DerefMut> + 't> FullBucket { +impl<'t, K, V, M: Deref> + DerefMut + 't> FullBucket { /// This works similarly to `into_refs`, exchanging a bucket state /// for mutable references into the table. pub fn into_mut_refs(self) -> (&'t mut K, &'t mut V) { @@ -463,7 +463,7 @@ impl BucketState { } } -impl>> GapThenFull { +impl>> GapThenFull { #[inline] pub fn full(&self) -> &FullBucket { &self.full diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs index 077f75e2edd6f..dda37765b4a66 100644 --- a/src/libstd/io/comm_adapters.rs +++ b/src/libstd/io/comm_adapters.rs @@ -14,7 +14,7 @@ use comm::{Sender, Receiver}; use io; use option::Option::{None, Some}; use result::Result::{Ok, Err}; -use slice::{bytes, CloneSliceExt, SliceExt}; +use slice::{bytes, SliceExt}; use super::{Buffer, Reader, Writer, IoResult}; use vec::Vec; diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs index f8ea373f8f456..af5d1630ca6f9 100644 --- a/src/libstd/io/mem.rs +++ b/src/libstd/io/mem.rs @@ -401,7 +401,7 @@ mod test { extern crate "test" as test_crate; use super::*; use io::{SeekSet, SeekCur, SeekEnd, Reader, Writer, Seek}; - use prelude::{Ok, Err, range, Vec, Buffer, AsSlice, SliceExt, IteratorExt, CloneSliceExt}; + use prelude::{Ok, Err, range, Vec, Buffer, AsSlice, SliceExt, IteratorExt}; use io; use self::test_crate::Bencher; diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index e8b852ee492b9..d01840b6da0fc 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1919,7 +1919,7 @@ impl fmt::Show for FilePermission { mod tests { use self::BadReaderBehavior::*; use super::{IoResult, Reader, MemReader, NoProgress, InvalidInput, Writer}; - use prelude::{Ok, Vec, Buffer, CloneSliceExt}; + use prelude::{Ok, Vec, Buffer, SliceExt}; use uint; #[deriving(Clone, PartialEq, Show)] diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs index 49ab9ddb92487..78d8ac307c28d 100644 --- a/src/libstd/io/net/ip.rs +++ b/src/libstd/io/net/ip.rs @@ -25,7 +25,7 @@ use ops::FnOnce; use option::Option; use option::Option::{None, Some}; use result::Result::{Ok, Err}; -use slice::{CloneSliceExt, SliceExt}; +use slice::SliceExt; use str::{FromStr, StrExt}; use vec::Vec; diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index b7d069eb19e58..e58ff1c3ac415 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -117,13 +117,15 @@ pub struct StdinReaderGuard<'a> { inner: MutexGuard<'a, RaceBox>, } -impl<'a> Deref> for StdinReaderGuard<'a> { +impl<'a> Deref for StdinReaderGuard<'a> { + type Target = BufferedReader; + fn deref(&self) -> &BufferedReader { &self.inner.0 } } -impl<'a> DerefMut> for StdinReaderGuard<'a> { +impl<'a> DerefMut for StdinReaderGuard<'a> { fn deref_mut(&mut self) -> &mut BufferedReader { &mut self.inner.0 } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 74c387c5eeaf1..654096ce49d5e 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -107,6 +107,7 @@ #![feature(macro_rules, globs, linkage, thread_local, asm)] #![feature(default_type_params, phase, lang_items, unsafe_destructor)] #![feature(slicing_syntax, unboxed_closures)] +#![feature(associated_types)] // Don't link to std. We are std. #![no_std] diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index ebb64bc2f2d51..34693be39b39b 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -317,9 +317,8 @@ macro_rules! try { #[macro_export] macro_rules! vec { ($($x:expr),*) => ({ - use std::slice::BoxedSliceExt; let xs: ::std::boxed::Box<[_]> = box [$($x),*]; - xs.into_vec() + ::std::slice::SliceExt::into_vec(xs) }); ($($x:expr,)*) => (vec![$($x),*]) } diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index febdf5f6118a5..6c64251091a31 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -20,7 +20,7 @@ use char::{mod, Char}; use num::{mod, Int, Float, ToPrimitive}; use num::FpCategory as Fp; use ops::FnMut; -use slice::{SliceExt, CloneSliceExt}; +use slice::SliceExt; use str::StrExt; use string::String; use vec::Vec; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index df50b7f81afcf..7aea83a069ad2 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -52,7 +52,6 @@ use ptr; use result::Result; use result::Result::{Err, Ok}; use slice::{AsSlice, SliceExt}; -use slice::CloneSliceExt; use str::{Str, StrExt}; use string::{String, ToString}; use sync::atomic::{AtomicInt, INIT_ATOMIC_INT, SeqCst}; diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index 30f3f56bc1c10..fae90e8d3938c 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -71,8 +71,7 @@ use option::Option::{None, Some}; use str; use str::{CowString, MaybeOwned, Str, StrExt}; use string::String; -use slice::{AsSlice, CloneSliceExt}; -use slice::{PartialEqSliceExt, SliceExt}; +use slice::{AsSlice, SliceExt}; use vec::Vec; /// Typedef for POSIX file paths. diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index bd4031e623085..8718d509f001c 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -22,8 +22,7 @@ use option::Option::{None, Some}; use kinds::Sized; use str::{FromStr, Str}; use str; -use slice::{CloneSliceExt, Split, AsSlice, SliceConcatExt, - PartialEqSliceExt, SliceExt}; +use slice::{Split, AsSlice, SliceConcatExt, SliceExt}; use vec::Vec; use super::{BytesContainer, GenericPath, GenericPathUnsafe}; @@ -449,7 +448,7 @@ static dot_dot_static: &'static [u8] = b".."; mod tests { use super::*; use prelude::Option::{mod, Some, None}; - use prelude::{Vec, Clone, AsSlice, SliceExt, CloneSliceExt, IteratorExt}; + use prelude::{Vec, Clone, AsSlice, SliceExt, IteratorExt}; use prelude::{DoubleEndedIteratorExt, Str, StrExt, ToString, GenericPath}; use str; diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 751ed4b70fb38..10f4adbfe560b 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -1121,7 +1121,7 @@ fn prefix_len(p: Option) -> uint { mod tests { use super::*; use prelude::Option::{mod, Some, None}; - use prelude::{Vec, Clone, AsSlice, SliceExt, CloneSliceExt, IteratorExt}; + use prelude::{Vec, Clone, AsSlice, SliceExt, IteratorExt}; use prelude::{DoubleEndedIteratorExt, Str, ToString, GenericPath}; use super::PathPrefix::*; use super::parse_prefix; diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index f016683e3d0a9..95b82959562c1 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -82,9 +82,7 @@ #[doc(no_inline)] pub use core::prelude::{Tuple9, Tuple10, Tuple11, Tuple12}; #[doc(no_inline)] pub use str::{Str, StrExt}; #[doc(no_inline)] pub use slice::AsSlice; -#[doc(no_inline)] pub use slice::{SliceConcatExt, PartialEqSliceExt}; -#[doc(no_inline)] pub use slice::{CloneSliceExt, OrdSliceExt, SliceExt}; -#[doc(no_inline)] pub use slice::{BoxedSliceExt}; +#[doc(no_inline)] pub use slice::{SliceConcatExt, SliceExt}; #[doc(no_inline)] pub use string::{IntoString, String, ToString}; #[doc(no_inline)] pub use vec::Vec; diff --git a/src/libstd/rt/exclusive.rs b/src/libstd/rt/exclusive.rs index 88bdb29caecad..e44511169abb4 100644 --- a/src/libstd/rt/exclusive.rs +++ b/src/libstd/rt/exclusive.rs @@ -74,10 +74,12 @@ impl<'a, T: Send> ExclusiveGuard<'a, T> { } } -impl<'a, T: Send> Deref for ExclusiveGuard<'a, T> { +impl<'a, T: Send> Deref for ExclusiveGuard<'a, T> { + type Target = T; + fn deref(&self) -> &T { &*self._data } } -impl<'a, T: Send> DerefMut for ExclusiveGuard<'a, T> { +impl<'a, T: Send> DerefMut for ExclusiveGuard<'a, T> { fn deref_mut(&mut self) -> &mut T { &mut *self._data } } diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 52004bb4a8f5f..08980eb01c628 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -288,12 +288,14 @@ impl<'mutex, T> MutexGuard<'mutex, T> { } } -impl<'mutex, T> Deref for MutexGuard<'mutex, T> { +impl<'mutex, T> Deref for MutexGuard<'mutex, T> { + type Target = T; + fn deref<'a>(&'a self) -> &'a T { unsafe { &*self.__data.get() } } } -impl<'mutex, T> DerefMut for MutexGuard<'mutex, T> { +impl<'mutex, T> DerefMut for MutexGuard<'mutex, T> { fn deref_mut<'a>(&'a mut self) -> &'a mut T { unsafe { &mut *self.__data.get() } } diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index 7f3c77c97adef..7478e90335589 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -326,13 +326,17 @@ impl<'rwlock, T> RWLockWriteGuard<'rwlock, T> { } } -impl<'rwlock, T> Deref for RWLockReadGuard<'rwlock, T> { +impl<'rwlock, T> Deref for RWLockReadGuard<'rwlock, T> { + type Target = T; + fn deref(&self) -> &T { unsafe { &*self.__data.get() } } } -impl<'rwlock, T> Deref for RWLockWriteGuard<'rwlock, T> { +impl<'rwlock, T> Deref for RWLockWriteGuard<'rwlock, T> { + type Target = T; + fn deref(&self) -> &T { unsafe { &*self.__data.get() } } } -impl<'rwlock, T> DerefMut for RWLockWriteGuard<'rwlock, T> { +impl<'rwlock, T> DerefMut for RWLockWriteGuard<'rwlock, T> { fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.__data.get() } } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index d5093c5055c79..d86db4e177e9b 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -26,6 +26,7 @@ #![feature(macro_rules, globs, default_type_params, phase, slicing_syntax)] #![feature(quote, unsafe_destructor)] #![feature(unboxed_closures)] +#![feature(associated_types)] extern crate arena; extern crate fmt_macros; diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs index 3023c547fb053..8c00aaf9beede 100644 --- a/src/libsyntax/owned_slice.rs +++ b/src/libsyntax/owned_slice.rs @@ -54,7 +54,9 @@ impl OwnedSlice { } } -impl Deref<[T]> for OwnedSlice { +impl Deref for OwnedSlice { + type Target = [T]; + fn deref(&self) -> &[T] { self.as_slice() } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index f22a4b5c6ed10..61da1c25926b9 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -606,7 +606,9 @@ impl InternedString { } } -impl Deref for InternedString { +impl Deref for InternedString { + type Target = str; + fn deref(&self) -> &str { &*self.string } } diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs index 1b3ebde2461e6..5d4f50f5fd283 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -75,7 +75,9 @@ impl P { } } -impl Deref for P { +impl Deref for P { + type Target = T; + fn deref<'a>(&'a self) -> &'a T { &*self.ptr } diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 97eb43165833a..5dde8db6155d9 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -124,7 +124,9 @@ impl BorrowFrom for str { } } -impl Deref for RcStr { +impl Deref for RcStr { + type Target = str; + fn deref(&self) -> &str { self.string[] } } diff --git a/src/snapshots.txt b/src/snapshots.txt index 6a9bfa07cf771..34beb53bd07cc 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -1,3 +1,12 @@ +S 2015-01-01 7d4f487 + freebsd-x86_64 5dc87adb17bc33abc08f1bf4c092e0b5b92a6ca4 + linux-i386 63bf82a5b540d8acbbf1e445ce48be0fa0f003fc + linux-x86_64 b1a414355ef5d2feff18ab9d008a2e9afc7b4625 + macos-i386 26042e3e648eb40848bf02f3e05ba31fd686179c + macos-x86_64 f01d7c6faf5db480a18a521c6971364f4ce8ddca + winnt-i386 6f04af045d26a0c87d487ba7254d4ad0c166ecaf + winnt-x86_64 392ab49482ec926de6a167afe920518b9a502a3f + S 2014-12-30 023dfb0 freebsd-x86_64 41ecd0ac557c823831c46696c7d78dc250398f25 linux-i386 fe6b59bf70a397e18629cb82264f7c6a70df34d4 diff --git a/src/test/auxiliary/overloaded_autoderef_xc.rs b/src/test/auxiliary/overloaded_autoderef_xc.rs index 26d61e166f26b..05960a5b8e1dd 100644 --- a/src/test/auxiliary/overloaded_autoderef_xc.rs +++ b/src/test/auxiliary/overloaded_autoderef_xc.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(associated_types)] + use std::ops::Deref; struct DerefWithHelper { @@ -24,7 +26,9 @@ impl Helper for Option { } } -impl> Deref for DerefWithHelper { +impl> Deref for DerefWithHelper { + type Target = T; + fn deref(&self) -> &T { self.helper.helper_borrow() } diff --git a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs new file mode 100644 index 0000000000000..5743216b6ca69 --- /dev/null +++ b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs @@ -0,0 +1,34 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that we do not ICE when the self type is `ty::err`, but rather +// just propagate the error. + +#![crate_type = "lib"] +#![feature(associated_types, default_type_params, lang_items)] +#![no_std] + +#[lang="sized"] +pub trait Sized for Sized? { + // Empty. +} + +#[lang = "add"] +trait Add { + type Output; + + fn add(self, RHS) -> Self::Output; +} + +fn ice
(a: A) { + let r = loop {}; + r = r + a; // here the type `r` is not yet inferred, hence `r+a` generates an error. + //~^ ERROR type of this value must be known +} diff --git a/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref-mut.rs b/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref-mut.rs index 05bc0d1e13b2d..7cd170f7773e9 100644 --- a/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref-mut.rs +++ b/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref-mut.rs @@ -11,19 +11,23 @@ // Test how overloaded deref interacts with borrows when DerefMut // is implemented. +#![feature(associated_types)] + use std::ops::{Deref, DerefMut}; struct Own { value: *mut T } -impl Deref for Own { +impl Deref for Own { + type Target = T; + fn deref(&self) -> &T { unsafe { &*self.value } } } -impl DerefMut for Own { +impl DerefMut for Own { fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.value } } diff --git a/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref.rs b/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref.rs index 5aaefd0173990..759467aeda36e 100644 --- a/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref.rs +++ b/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref.rs @@ -11,13 +11,17 @@ // Test how overloaded deref interacts with borrows when only // Deref and not DerefMut is implemented. +#![feature(associated_types)] + use std::ops::Deref; struct Rc { value: *const T } -impl Deref for Rc { +impl Deref for Rc { + type Target = T; + fn deref(&self) -> &T { unsafe { &*self.value } } diff --git a/src/test/compile-fail/borrowck-borrow-overloaded-deref-mut.rs b/src/test/compile-fail/borrowck-borrow-overloaded-deref-mut.rs index 974fe3bc5d553..74dceab18ea48 100644 --- a/src/test/compile-fail/borrowck-borrow-overloaded-deref-mut.rs +++ b/src/test/compile-fail/borrowck-borrow-overloaded-deref-mut.rs @@ -11,19 +11,23 @@ // Test how overloaded deref interacts with borrows when DerefMut // is implemented. +#![feature(associated_types)] + use std::ops::{Deref, DerefMut}; struct Own { value: *mut T } -impl Deref for Own { +impl Deref for Own { + type Target = T; + fn deref<'a>(&'a self) -> &'a T { unsafe { &*self.value } } } -impl DerefMut for Own { +impl DerefMut for Own { fn deref_mut<'a>(&'a mut self) -> &'a mut T { unsafe { &mut *self.value } } diff --git a/src/test/compile-fail/borrowck-borrow-overloaded-deref.rs b/src/test/compile-fail/borrowck-borrow-overloaded-deref.rs index 5397c5b8a569f..635e440c6fe12 100644 --- a/src/test/compile-fail/borrowck-borrow-overloaded-deref.rs +++ b/src/test/compile-fail/borrowck-borrow-overloaded-deref.rs @@ -11,13 +11,17 @@ // Test how overloaded deref interacts with borrows when only // Deref and not DerefMut is implemented. +#![feature(associated_types)] + use std::ops::Deref; struct Rc { value: *const T } -impl Deref for Rc { +impl Deref for Rc { + type Target = T; + fn deref<'a>(&'a self) -> &'a T { unsafe { &*self.value } } diff --git a/src/test/compile-fail/infinite-autoderef.rs b/src/test/compile-fail/infinite-autoderef.rs index e4c6fa7d47f4a..ab770c099e125 100644 --- a/src/test/compile-fail/infinite-autoderef.rs +++ b/src/test/compile-fail/infinite-autoderef.rs @@ -10,11 +10,15 @@ // error-pattern: reached the recursion limit while auto-dereferencing +#![feature(associated_types)] + use std::ops::Deref; struct Foo; -impl Deref for Foo { +impl Deref for Foo { + type Target = Foo; + fn deref(&self) -> &Foo { self } diff --git a/src/test/compile-fail/issue-18566.rs b/src/test/compile-fail/issue-18566.rs index f64d8fee2d8b3..1ccd1753c76d7 100644 --- a/src/test/compile-fail/issue-18566.rs +++ b/src/test/compile-fail/issue-18566.rs @@ -8,8 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(associated_types)] + struct MyPtr<'a>(&'a mut uint); -impl<'a> Deref for MyPtr<'a> { +impl<'a> Deref for MyPtr<'a> { + type Target = uint; + fn deref<'b>(&'b self) -> &'b uint { self.0 } } diff --git a/src/test/run-pass/associated-types-conditional-dispatch.rs b/src/test/run-pass/associated-types-conditional-dispatch.rs new file mode 100644 index 0000000000000..3b53203d218e0 --- /dev/null +++ b/src/test/run-pass/associated-types-conditional-dispatch.rs @@ -0,0 +1,73 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that we evaluate projection predicates to winnow out +// candidates during trait selection and method resolution (#20296). +// If we don't properly winnow out candidates based on the output type +// `Target=[A]`, then the impl marked with `(*)` is seen to conflict +// with all the others. + +#![feature(associated_types, default_type_params)] + +use std::ops::Deref; + +pub trait MyEq for Sized? { + fn eq(&self, u: &U) -> bool; +} + +impl MyEq<[B]> for [A] + where A : MyEq +{ + fn eq(&self, other: &[B]) -> bool { + self.len() == other.len() && + self.iter().zip(other.iter()) + .all(|(a, b)| MyEq::eq(a, b)) + } +} + +// (*) This impl conflicts with everything unless the `Target=[A]` +// constraint is considered. +impl<'a, A, B, Lhs> MyEq<[B; 0]> for Lhs + where A: MyEq, Lhs: Deref +{ + fn eq(&self, other: &[B; 0]) -> bool { + MyEq::eq(&**self, other.as_slice()) + } +} + +struct DerefWithHelper { + pub helper: H +} + +trait Helper { + fn helper_borrow(&self) -> &T; +} + +impl Helper for Option { + fn helper_borrow(&self) -> &T { + self.as_ref().unwrap() + } +} + +impl> Deref for DerefWithHelper { + type Target = T; + + fn deref(&self) -> &T { + self.helper.helper_borrow() + } +} + +pub fn check(x: T, y: T) -> bool { + let d: DerefWithHelper, T> = DerefWithHelper { helper: Some(x) }; + d.eq(&y) +} + +pub fn main() { +} diff --git a/src/test/run-pass/deref-mut-on-ref.rs b/src/test/run-pass/deref-mut-on-ref.rs index dcf7c483b2cdc..03848b2d8207a 100644 --- a/src/test/run-pass/deref-mut-on-ref.rs +++ b/src/test/run-pass/deref-mut-on-ref.rs @@ -10,7 +10,7 @@ // Test that `&mut T` implements `DerefMut` -fn inc>(mut t: T) { +fn inc + DerefMut>(mut t: T) { *t += 1; } diff --git a/src/test/run-pass/deref-on-ref.rs b/src/test/run-pass/deref-on-ref.rs index 27e7d8f3ba2a4..7ebf7a9cd30fb 100644 --- a/src/test/run-pass/deref-on-ref.rs +++ b/src/test/run-pass/deref-on-ref.rs @@ -10,7 +10,7 @@ // Test that `&T` and `&mut T` implement `Deref` -fn deref>(t: T) -> U { +fn deref>(t: T) -> U { *t } diff --git a/src/test/run-pass/dst-deref-mut.rs b/src/test/run-pass/dst-deref-mut.rs index c2707a1ae6e90..72a07ca7d3585 100644 --- a/src/test/run-pass/dst-deref-mut.rs +++ b/src/test/run-pass/dst-deref-mut.rs @@ -10,17 +10,21 @@ // Test that a custom deref with a fat pointer return type does not ICE +#![feature(associated_types)] + pub struct Arr { ptr: Box<[uint]> } -impl Deref<[uint]> for Arr { +impl Deref for Arr { + type Target = [uint]; + fn deref(&self) -> &[uint] { panic!(); } } -impl DerefMut<[uint]> for Arr { +impl DerefMut for Arr { fn deref_mut(&mut self) -> &mut [uint] { &mut *self.ptr } diff --git a/src/test/run-pass/dst-deref.rs b/src/test/run-pass/dst-deref.rs index 43b7d116d3038..8d32216697d62 100644 --- a/src/test/run-pass/dst-deref.rs +++ b/src/test/run-pass/dst-deref.rs @@ -10,11 +10,15 @@ // Test that a custom deref with a fat pointer return type does not ICE +#![feature(associated_types)] + pub struct Arr { ptr: Box<[uint]> } -impl Deref<[uint]> for Arr { +impl Deref for Arr { + type Target = [uint]; + fn deref(&self) -> &[uint] { &*self.ptr } diff --git a/src/test/run-pass/fixup-deref-mut.rs b/src/test/run-pass/fixup-deref-mut.rs index d2812ce1d2ce9..9c2a8575bb9ec 100644 --- a/src/test/run-pass/fixup-deref-mut.rs +++ b/src/test/run-pass/fixup-deref-mut.rs @@ -8,18 +8,22 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(associated_types)] + // Generic unique/owned smaht pointer. struct Own { value: *mut T } -impl Deref for Own { +impl Deref for Own { + type Target = T; + fn deref<'a>(&'a self) -> &'a T { unsafe { &*self.value } } } -impl DerefMut for Own { +impl DerefMut for Own { fn deref_mut<'a>(&'a mut self) -> &'a mut T { unsafe { &mut *self.value } } diff --git a/src/test/run-pass/issue-13264.rs b/src/test/run-pass/issue-13264.rs index 06ab67f2f3e97..aac33f3d8a66b 100644 --- a/src/test/run-pass/issue-13264.rs +++ b/src/test/run-pass/issue-13264.rs @@ -8,11 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(associated_types)] + struct Root { jsref: JSRef } -impl Deref for Root { +impl Deref for Root { + type Target = JSRef; + fn deref<'a>(&'a self) -> &'a JSRef { &self.jsref } @@ -23,7 +27,9 @@ struct JSRef { node: *const Node } -impl Deref for JSRef { +impl Deref for JSRef { + type Target = Node; + fn deref<'a>(&'a self) -> &'a Node { self.get() } diff --git a/src/test/run-pass/issue-16774.rs b/src/test/run-pass/issue-16774.rs index ebc879d82fbb1..1b5016d198dd9 100644 --- a/src/test/run-pass/issue-16774.rs +++ b/src/test/run-pass/issue-16774.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] +#![feature(associated_types, unboxed_closures)] struct X(Box); @@ -23,14 +23,16 @@ impl Drop for X { } } -impl Deref for X { +impl Deref for X { + type Target = int; + fn deref(&self) -> &int { let &X(box ref x) = self; x } } -impl DerefMut for X { +impl DerefMut for X { fn deref_mut(&mut self) -> &mut int { let &X(box ref mut x) = self; x diff --git a/src/test/run-pass/overloaded-autoderef-count.rs b/src/test/run-pass/overloaded-autoderef-count.rs index 4cf5e07413935..5b105646dacad 100644 --- a/src/test/run-pass/overloaded-autoderef-count.rs +++ b/src/test/run-pass/overloaded-autoderef-count.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(associated_types)] + use std::cell::Cell; use std::ops::{Deref, DerefMut}; @@ -32,14 +34,16 @@ impl DerefCounter { } } -impl Deref for DerefCounter { +impl Deref for DerefCounter { + type Target = T; + fn deref(&self) -> &T { self.count_imm.set(self.count_imm.get() + 1); &self.value } } -impl DerefMut for DerefCounter { +impl DerefMut for DerefCounter { fn deref_mut(&mut self) -> &mut T { self.count_mut += 1; &mut self.value diff --git a/src/test/run-pass/overloaded-autoderef-indexing.rs b/src/test/run-pass/overloaded-autoderef-indexing.rs index 5c4befcd0c825..7d550c925b74e 100644 --- a/src/test/run-pass/overloaded-autoderef-indexing.rs +++ b/src/test/run-pass/overloaded-autoderef-indexing.rs @@ -8,11 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(associated_types)] + struct DerefArray<'a, T:'a> { inner: &'a [T] } -impl<'a, T> Deref<&'a [T]> for DerefArray<'a, T> { +impl<'a, T> Deref for DerefArray<'a, T> { + type Target = &'a [T]; + fn deref<'b>(&'b self) -> &'b &'a [T] { &self.inner } diff --git a/src/test/run-pass/overloaded-autoderef-order.rs b/src/test/run-pass/overloaded-autoderef-order.rs index f0daf371ca79e..5b45413e76052 100644 --- a/src/test/run-pass/overloaded-autoderef-order.rs +++ b/src/test/run-pass/overloaded-autoderef-order.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(associated_types)] + use std::rc::Rc; struct DerefWrapper { @@ -23,7 +25,9 @@ impl DerefWrapper { } } -impl Deref for DerefWrapper { +impl Deref for DerefWrapper { + type Target = Y; + fn deref(&self) -> &Y { &self.y } @@ -46,7 +50,9 @@ mod priv_test { } } - impl Deref for DerefWrapperHideX { + impl Deref for DerefWrapperHideX { + type Target = Y; + fn deref(&self) -> &Y { &self.y } diff --git a/src/test/run-pass/overloaded-autoderef-vtable.rs b/src/test/run-pass/overloaded-autoderef-vtable.rs index f71afb9650743..23efba157495c 100644 --- a/src/test/run-pass/overloaded-autoderef-vtable.rs +++ b/src/test/run-pass/overloaded-autoderef-vtable.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(associated_types)] + use std::ops::Deref; struct DerefWithHelper { @@ -24,7 +26,9 @@ impl Helper for Option { } } -impl> Deref for DerefWithHelper { +impl> Deref for DerefWithHelper { + type Target = T; + fn deref(&self) -> &T { self.helper.helper_borrow() } diff --git a/src/test/run-pass/overloaded-deref-count.rs b/src/test/run-pass/overloaded-deref-count.rs index 7645500c02f54..b6fb38d5cc2cf 100644 --- a/src/test/run-pass/overloaded-deref-count.rs +++ b/src/test/run-pass/overloaded-deref-count.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(associated_types)] + use std::cell::Cell; use std::ops::{Deref, DerefMut}; use std::vec::Vec; @@ -32,14 +34,16 @@ impl DerefCounter { } } -impl Deref for DerefCounter { +impl Deref for DerefCounter { + type Target = T; + fn deref(&self) -> &T { self.count_imm.set(self.count_imm.get() + 1); &self.value } } -impl DerefMut for DerefCounter { +impl DerefMut for DerefCounter { fn deref_mut(&mut self) -> &mut T { self.count_mut += 1; &mut self.value