diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-01-02 12:16:41 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-01-02 13:51:50 -0800 |
| commit | 340f3fd7a909b30509a63916df06f2b885d113f7 (patch) | |
| tree | 344f3d621e187b41d23ef01f621ff68ebe810a03 | |
| parent | 8cf9929a9a901b68d4624167542924e8b181e96a (diff) | |
| parent | 1abee08cbdbd62a83805aa5b5068df9e00471f06 (diff) | |
| download | rust-340f3fd7a909b30509a63916df06f2b885d113f7.tar.gz rust-340f3fd7a909b30509a63916df06f2b885d113f7.zip | |
rollup merge of #20410: japaric/assoc-types
Conflicts: src/liballoc/lib.rs src/libcollections/lib.rs src/libcollections/slice.rs src/libcore/ops.rs src/libcore/prelude.rs src/libcore/ptr.rs src/librustc/middle/traits/project.rs src/libstd/c_str.rs src/libstd/io/mem.rs src/libstd/io/mod.rs src/libstd/lib.rs src/libstd/path/posix.rs src/libstd/path/windows.rs src/libstd/prelude.rs src/libstd/rt/exclusive.rs src/libsyntax/lib.rs src/test/compile-fail/issue-18566.rs src/test/run-pass/deref-mut-on-ref.rs src/test/run-pass/deref-on-ref.rs src/test/run-pass/dst-deref-mut.rs src/test/run-pass/dst-deref.rs src/test/run-pass/fixup-deref-mut.rs src/test/run-pass/issue-13264.rs src/test/run-pass/overloaded-autoderef-indexing.rs
74 files changed, 898 insertions, 588 deletions
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index aa5a7586118..59106aa9777 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -247,7 +247,9 @@ impl<T> BorrowFrom<Arc<T>> for T { } #[experimental = "Deref is experimental."] -impl<T> Deref<T> for Arc<T> { +impl<T> Deref for Arc<T> { + type Target = T; + #[inline] fn deref(&self) -> &T { &self.inner().data diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 5f8789bf1c7..e836b08459b 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -155,11 +155,13 @@ impl fmt::Show for Box<Any> { } } -impl<Sized? T> Deref<T> for Box<T> { +impl<Sized? T> Deref for Box<T> { + type Target = T; + fn deref(&self) -> &T { &**self } } -impl<Sized? T> DerefMut<T> for Box<T> { +impl<Sized? T> DerefMut for Box<T> { fn deref_mut(&mut self) -> &mut T { &mut **self } } @@ -212,7 +214,7 @@ mod test { #[test] fn deref() { - fn homura<T: Deref<i32>>(_: T) { } + fn homura<T: Deref<Target=i32>>(_: T) { } homura(box 765i32); } } diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index d17a54ce6e5..aab513ddeb7 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -66,6 +66,7 @@ #![no_std] #![allow(unknown_features)] #![feature(lang_items, phase, unsafe_destructor, default_type_params, old_orphan_check)] +#![feature(associated_types)] #[phase(plugin, link)] extern crate core; diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index bd250938836..c57231fc434 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -355,7 +355,9 @@ impl<T> BorrowFrom<Rc<T>> for T { } #[experimental = "Deref is experimental."] -impl<T> Deref<T> for Rc<T> { +impl<T> Deref for Rc<T> { + 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 6d41883dc8d..da98c19e888 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -518,13 +518,15 @@ mod stack { marker: marker::InvariantLifetime<'id> } - impl<'id, T> Deref<T> 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<T> 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 05356368365..3dddcae11ce 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -457,7 +457,9 @@ impl<K: Clone, V: Clone> Clone for Node<K, V> { /// flag: &'a Cell<bool>, /// } /// -/// impl<'a> Deref<Node<uint, uint>> for Nasty<'a> { +/// impl<'a> Deref for Nasty<'a> { +/// type Target = Node<uint, uint>; +/// /// fn deref(&self) -> &Node<uint, uint> { /// if self.flag.get() { /// &*self.second @@ -513,7 +515,7 @@ impl<K: Ord, V> Node<K, V> { /// 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<Sized? Q, NodeRef: Deref<Node<K, V>>>(node: NodeRef, key: &Q) + pub fn search<Sized? Q, NodeRef: Deref<Target=Node<K, V>>>(node: NodeRef, key: &Q) -> SearchResult<NodeRef> where Q: BorrowFrom<K> + 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* @@ -590,7 +592,7 @@ impl <K, V> Node<K, V> { } } -impl<K, V, NodeRef: Deref<Node<K, V>>, Type, NodeType> Handle<NodeRef, Type, NodeType> { +impl<K, V, NodeRef: Deref<Target=Node<K, V>>, Type, NodeType> Handle<NodeRef, Type, NodeType> { /// 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`. @@ -599,7 +601,9 @@ impl<K, V, NodeRef: Deref<Node<K, V>>, Type, NodeType> Handle<NodeRef, Type, Nod } } -impl<K, V, NodeRef: DerefMut<Node<K, V>>, Type, NodeType> Handle<NodeRef, Type, NodeType> { +impl<K, V, NodeRef, Type, NodeType> Handle<NodeRef, Type, NodeType> where + NodeRef: Deref<Target=Node<K, V>> + 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. @@ -655,7 +659,7 @@ impl<'a, K: 'a, V: 'a> Handle<&'a mut Node<K, V>, handle::Edge, handle::Internal } } -impl<K, V, NodeRef: Deref<Node<K, V>>> Handle<NodeRef, handle::Edge, handle::Internal> { +impl<K, V, NodeRef: Deref<Target=Node<K, V>>> Handle<NodeRef, handle::Edge, handle::Internal> { // This doesn't exist because there are no uses for it, // but is fine to add, analagous to edge_mut. // @@ -669,7 +673,7 @@ pub enum ForceResult<NodeRef, Type> { Internal(Handle<NodeRef, Type, handle::Internal>) } -impl<K, V, NodeRef: Deref<Node<K, V>>, Type> Handle<NodeRef, Type, handle::LeafOrInternal> { +impl<K, V, NodeRef: Deref<Target=Node<K, V>>, Type> Handle<NodeRef, Type, handle::LeafOrInternal> { /// 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<NodeRef, Type> { @@ -686,8 +690,9 @@ impl<K, V, NodeRef: Deref<Node<K, V>>, Type> Handle<NodeRef, Type, handle::LeafO } } } - -impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::Edge, handle::Leaf> { +impl<K, V, NodeRef> Handle<NodeRef, handle::Edge, handle::Leaf> where + NodeRef: Deref<Target=Node<K, V>> + 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. /// @@ -719,7 +724,9 @@ impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::Edge, handle:: } } -impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::Edge, handle::Internal> { +impl<K, V, NodeRef> Handle<NodeRef, handle::Edge, handle::Internal> where + NodeRef: Deref<Target=Node<K, V>> + 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<K, V> { @@ -802,7 +809,9 @@ impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::Edge, handle:: } } -impl<K, V, NodeRef: DerefMut<Node<K, V>>, NodeType> Handle<NodeRef, handle::Edge, NodeType> { +impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::Edge, NodeType> where + NodeRef: Deref<Target=Node<K, V>> + 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. @@ -864,7 +873,7 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a mut Node<K, V>, handle::KV, NodeType } } -impl<'a, K: 'a, V: 'a, NodeRef: Deref<Node<K, V>> + 'a, NodeType> Handle<NodeRef, handle::KV, +impl<'a, K: 'a, V: 'a, NodeRef: Deref<Target=Node<K, V>> + 'a, NodeType> Handle<NodeRef, handle::KV, NodeType> { // These are fine to include, but are currently unneeded. // @@ -883,8 +892,9 @@ impl<'a, K: 'a, V: 'a, NodeRef: Deref<Node<K, V>> + 'a, NodeType> Handle<NodeRef // } } -impl<'a, K: 'a, V: 'a, NodeRef: DerefMut<Node<K, V>> + 'a, NodeType> Handle<NodeRef, handle::KV, - NodeType> { +impl<'a, K: 'a, V: 'a, NodeRef, NodeType> Handle<NodeRef, handle::KV, NodeType> where + NodeRef: 'a + Deref<Target=Node<K, V>> + 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. @@ -900,7 +910,9 @@ impl<'a, K: 'a, V: 'a, NodeRef: DerefMut<Node<K, V>> + 'a, NodeType> Handle<Node } } -impl<K, V, NodeRef: DerefMut<Node<K, V>>, NodeType> Handle<NodeRef, handle::KV, NodeType> { +impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::KV, NodeType> where + NodeRef: Deref<Target=Node<K, V>> + 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<K, V>, handle::Edge, NodeType> { @@ -920,7 +932,9 @@ impl<K, V, NodeRef: DerefMut<Node<K, V>>, NodeType> Handle<NodeRef, handle::KV, } } -impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::KV, handle::Leaf> { +impl<K, V, NodeRef> Handle<NodeRef, handle::KV, handle::Leaf> where + NodeRef: Deref<Target=Node<K, V>> + DerefMut, +{ /// Removes the key/value pair at the handle's location. /// /// # Panics (in debug build) @@ -931,7 +945,9 @@ impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::KV, handle::Le } } -impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::KV, handle::Internal> { +impl<K, V, NodeRef> Handle<NodeRef, handle::KV, handle::Internal> where + NodeRef: Deref<Target=Node<K, V>> + 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 82175c39494..fac9ab8107a 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -26,6 +26,7 @@ #![feature(unsafe_destructor, slicing_syntax)] #![feature(unboxed_closures)] #![feature(old_orphan_check)] +#![feature(associated_types)] #![no_std] #[phase(plugin, link)] extern crate core; @@ -121,7 +122,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}; @@ -130,7 +130,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 9e2b4b77910..1c1b48f8cef 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -91,7 +91,7 @@ use alloc::boxed::Box; use core::borrow::{BorrowFrom, BorrowFromMut, ToOwned}; use core::clone::Clone; use core::cmp::Ordering::{mod, Greater, Less}; -use core::cmp::{mod, Ord}; +use core::cmp::{mod, Ord, PartialEq}; use core::iter::{Iterator, IteratorExt, IteratorCloneExt}; use core::iter::{range, range_step, MultiplicativeIterator}; use core::kinds::Sized; @@ -108,7 +108,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}; @@ -126,7 +126,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<T> for Sized? { +pub trait SliceExt for Sized? { + type Item; + /// Sorts the slice, in place, using `compare` to compare /// elements. /// @@ -145,7 +147,7 @@ pub trait SliceExt<T> for Sized? { /// assert!(v == [5, 4, 3, 2, 1]); /// ``` #[stable] - fn sort_by<F>(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering; + fn sort_by<F>(&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). @@ -169,7 +171,7 @@ pub trait SliceExt<T> for Sized? { /// assert!(a == [6i, 7, 8, 4, 5]); /// ``` #[experimental = "uncertain about this API approach"] - fn move_from(&mut self, src: Vec<T>, start: uint, end: uint) -> uint; + fn move_from(&mut self, src: Vec<Self::Item>, start: uint, end: uint) -> uint; /// Returns a subslice spanning the interval [`start`, `end`). /// @@ -178,7 +180,7 @@ pub trait SliceExt<T> 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. /// @@ -186,7 +188,7 @@ pub trait SliceExt<T> 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`. /// @@ -194,7 +196,7 @@ pub trait SliceExt<T> 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. /// @@ -204,32 +206,32 @@ pub trait SliceExt<T> 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<T>; + fn iter(&self) -> Iter<Self::Item>; /// Returns an iterator over subslices separated by elements that match /// `pred`. The matched element is not contained in the subslices. #[stable] - fn split<F>(&self, pred: F) -> Split<T, F> - where F: FnMut(&T) -> bool; + fn split<F>(&self, pred: F) -> Split<Self::Item, F> + 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<F>(&self, n: uint, pred: F) -> SplitN<T, F> - where F: FnMut(&T) -> bool; + fn splitn<F>(&self, n: uint, pred: F) -> SplitN<Self::Item, F> + 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<F>(&self, n: uint, pred: F) -> RSplitN<T, F> - where F: FnMut(&T) -> bool; + fn rsplitn<F>(&self, n: uint, pred: F) -> RSplitN<Self::Item, F> + 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 @@ -251,7 +253,7 @@ pub trait SliceExt<T> for Sized? { /// } /// ``` #[stable] - fn windows(&self, size: uint) -> Windows<T>; + fn windows(&self, size: uint) -> Windows<Self::Item>; /// Returns an iterator over `size` elements of the slice at a /// time. The chunks do not overlap. If `size` does not divide the @@ -274,41 +276,41 @@ pub trait SliceExt<T> for Sized? { /// } /// ``` #[stable] - fn chunks(&self, size: uint) -> Chunks<T>; + fn chunks(&self, size: uint) -> Chunks<Self::Item>; /// 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) } @@ -320,7 +322,7 @@ pub trait SliceExt<T> 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. /// @@ -356,7 +358,7 @@ pub trait SliceExt<T> for Sized? { /// ``` #[stable] fn binary_search_by<F>(&self, f: F) -> Result<uint, uint> where - F: FnMut(&T) -> Ordering; + F: FnMut(&Self::Item) -> Ordering; /// Return the number of elements in the slice /// @@ -383,12 +385,12 @@ pub trait SliceExt<T> 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`). /// @@ -397,7 +399,7 @@ pub trait SliceExt<T> 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. /// @@ -405,7 +407,7 @@ pub trait SliceExt<T> 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`. /// @@ -413,54 +415,54 @@ pub trait SliceExt<T> 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<T>; + fn iter_mut(&mut self) -> IterMut<Self::Item>; /// 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<F>(&mut self, pred: F) -> SplitMut<T, F> - where F: FnMut(&T) -> bool; + fn split_mut<F>(&mut self, pred: F) -> SplitMut<Self::Item, F> + 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<F>(&mut self, n: uint, pred: F) -> SplitNMut<T, F> - where F: FnMut(&T) -> bool; + fn splitn_mut<F>(&mut self, n: uint, pred: F) -> SplitNMut<Self::Item, F> + 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<F>(&mut self, n: uint, pred: F) -> RSplitNMut<T, F> - where F: FnMut(&T) -> bool; + fn rsplitn_mut<F>(&mut self, n: uint, pred: F) -> RSplitNMut<Self::Item, F> + 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 @@ -471,7 +473,7 @@ pub trait SliceExt<T> for Sized? { /// /// Panics if `chunk_size` is 0. #[stable] - fn chunks_mut(&mut self, chunk_size: uint) -> ChunksMut<T>; + fn chunks_mut(&mut self, chunk_size: uint) -> ChunksMut<Self::Item>; /// Swaps two elements in a slice. /// @@ -529,7 +531,7 @@ pub trait SliceExt<T> 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. /// @@ -545,11 +547,11 @@ pub trait SliceExt<T> 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) } @@ -562,11 +564,179 @@ pub trait SliceExt<T> 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<Self::Item> where Self::Item: Clone; + + /// Deprecated: use `iter().cloned().partition(f)` instead. + #[deprecated = "use iter().cloned().partition(f) instead"] + fn partitioned<F>(&self, f: F) -> (Vec<Self::Item>, Vec<Self::Item>) 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<Self::Item> 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<uint, uint> where Self::Item: Ord; + + /// Deprecated: use `binary_search` instead. + #[deprecated = "use binary_search instead"] + fn binary_search_elem(&self, x: &Self::Item) -> Result<uint, uint> 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<uint> where Self::Item: PartialEq; + + /// Find the last index containing a matching value. + #[experimental] + fn rposition_elem(&self, t: &Self::Item) -> Option<uint> 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<Self>) -> Vec<Self::Item>; } #[unstable = "trait is unstable"] -impl<T> SliceExt<T> for [T] { +impl<T> SliceExt for [T] { + type Item = T; + #[inline] fn sort_by<F>(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering { merge_sort(self, compare) @@ -781,96 +951,10 @@ impl<T> SliceExt<T> 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<T> { - /// Convert `self` into a vector without clones or allocation. - #[experimental] - fn into_vec(self) -> Vec<T>; -} - -#[experimental = "trait is experimental"] -impl<T> BoxedSliceExt<T> for Box<[T]> { - fn into_vec(mut self) -> Vec<T> { - 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<T> for Sized? { - /// Copies `self` into a new `Vec`. - #[stable] - fn to_vec(&self) -> Vec<T>; - - /// Deprecated: use `iter().cloned().partition(f)` instead. - #[deprecated = "use iter().cloned().partition(f) instead"] - fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) 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<T>; - - /// 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<T: Clone> CloneSliceExt<T> for [T] { /// Returns a copy of `v`. #[inline] - fn to_vec(&self) -> Vec<T> { + fn to_vec(&self) -> Vec<T> where T: Clone { let mut vector = Vec::with_capacity(self.len()); vector.push_all(self); vector @@ -878,132 +962,71 @@ impl<T: Clone> CloneSliceExt<T> for [T] { #[inline] - fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool { + fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) 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<T> { + fn permutations(&self) -> Permutations<T> 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<T> 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<uint, uint>; + fn binary_search(&self, x: &T) -> Result<uint, uint> 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<uint, uint> { - 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<uint> where T: PartialEq { + core_slice::SliceExt::position_elem(self, t) + } -#[unstable = "trait is unstable"] -impl<T: Ord> OrdSliceExt<T> for [T] { - #[inline] - fn sort(&mut self) { - self.sort_by(|a, b| a.cmp(b)) + fn rposition_elem(&self, t: &T) -> Option<uint> where T: PartialEq { + core_slice::SliceExt::rposition_elem(self, t) } - fn binary_search(&self, x: &T) -> Result<uint, uint> { - 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<Self>) -> Vec<T> { + 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<Sized? T, U> for Sized? { @@ -1423,7 +1446,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 f631af6f642..769679ec4d4 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -29,7 +29,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}; @@ -96,7 +95,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 @@ -942,7 +941,9 @@ impl ops::Slice<uint, str> for String { } #[experimental = "waiting on Deref stabilization"] -impl ops::Deref<str> for String { +impl ops::Deref for String { + type Target = str; + fn deref<'a>(&'a self) -> &'a str { unsafe { mem::transmute(self.vec[]) } } @@ -954,7 +955,9 @@ pub struct DerefString<'a> { x: DerefVec<'a, u8> } -impl<'a> Deref<String> 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 351151c0f07..7e367927421 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -65,8 +65,6 @@ use core::ptr; use core::raw::Slice as RawSlice; use core::uint; -use slice::CloneSliceExt; - /// A growable list type, written `Vec<T>` but pronounced 'vector.' /// /// # Examples @@ -1220,7 +1218,7 @@ unsafe fn dealloc<T>(ptr: *mut T, len: uint) { #[unstable] impl<T:Clone> Clone for Vec<T> { - fn clone(&self) -> Vec<T> { self.as_slice().to_vec() } + fn clone(&self) -> Vec<T> { ::slice::SliceExt::to_vec(self.as_slice()) } fn clone_from(&mut self, other: &Vec<T>) { // drop anything in self that will not be overwritten @@ -1305,12 +1303,14 @@ impl<T> ops::SliceMut<uint, [T]> for Vec<T> { } #[experimental = "waiting on Deref stability"] -impl<T> ops::Deref<[T]> for Vec<T> { +impl<T> ops::Deref for Vec<T> { + type Target = [T]; + fn deref<'a>(&'a self) -> &'a [T] { self.as_slice() } } #[experimental = "waiting on DerefMut stability"] -impl<T> ops::DerefMut<[T]> for Vec<T> { +impl<T> ops::DerefMut for Vec<T> { fn deref_mut<'a>(&'a mut self) -> &'a mut [T] { self.as_mut_slice() } } @@ -1720,7 +1720,9 @@ pub struct DerefVec<'a, T> { } #[experimental] -impl<'a, T> Deref<Vec<T>> for DerefVec<'a, T> { +impl<'a, T> Deref for DerefVec<'a, T> { + type Target = Vec<T>; + fn deref<'b>(&'b self) -> &'b Vec<T> { &self.x } diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 28563a60b61..ba7714ad9bc 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<Rhs> for [A; $N] where A: PartialEq<B>, - Rhs: Deref<[B]>, + Rhs: Deref<Target=[B]>, { #[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<B>, - Lhs: Deref<[A]> + Lhs: Deref<Target=[A]> { #[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 3a2cb8ea7d9..7e4d73d598d 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<T> { } } -impl<'a, T, Sized? B> Deref<B> for Cow<'a, T, B> where B: ToOwned<T> { +impl<'a, T, Sized? B> Deref for Cow<'a, T, B> where B: ToOwned<T> { + 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 94e9441abc8..47204dfc422 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -424,7 +424,9 @@ pub struct Ref<'b, T:'b> { } #[unstable = "waiting for `Deref` to become stable"] -impl<'b, T> Deref<T> 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 @@ -480,7 +482,9 @@ pub struct RefMut<'b, T:'b> { } #[unstable = "waiting for `Deref` to become stable"] -impl<'b, T> Deref<T> 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 @@ -488,7 +492,7 @@ impl<'b, T> Deref<T> for RefMut<'b, T> { } #[unstable = "waiting for `DerefMut` to become stable"] -impl<'b, T> DerefMut<T> 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 53b5c617300..d7a675b3104 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -1175,7 +1175,7 @@ pub trait IteratorCloneExt<A> { } #[unstable = "trait is unstable"] -impl<A: Clone, D: Deref<A>, I: Iterator<D>> IteratorCloneExt<A> for I { +impl<A: Clone, D: Deref<Target=A>, I: Iterator<D>> IteratorCloneExt<A> for I { fn cloned(self) -> Cloned<I> { Cloned { it: self } } @@ -1186,7 +1186,7 @@ pub struct Cloned<I> { it: I, } -impl<A: Clone, D: Deref<A>, I: Iterator<D>> Iterator<A> for Cloned<I> { +impl<A: Clone, D: Deref<Target=A>, I: Iterator<D>> Iterator<A> for Cloned<I> { fn next(&mut self) -> Option<A> { self.it.next().cloned() } @@ -1196,7 +1196,7 @@ impl<A: Clone, D: Deref<A>, I: Iterator<D>> Iterator<A> for Cloned<I> { } } -impl<A: Clone, D: Deref<A>, I: DoubleEndedIterator<D>> +impl<A: Clone, D: Deref<Target=A>, I: DoubleEndedIterator<D>> DoubleEndedIterator<A> for Cloned<I> { fn next_back(&mut self) -> Option<A> { self.it.next_back().cloned() @@ -1204,7 +1204,7 @@ impl<A: Clone, D: Deref<A>, I: DoubleEndedIterator<D>> } #[unstable = "trait is unstable"] -impl<A: Clone, D: Deref<A>, I: ExactSizeIterator<D>> ExactSizeIterator<A> for Cloned<I> {} +impl<A: Clone, D: Deref<Target=A>, I: ExactSizeIterator<D>> ExactSizeIterator<A> for Cloned<I> {} #[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 c429e4b8212..ba9103520d8 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -44,7 +44,9 @@ impl<T: Zeroable> NonZero<T> { } } -impl<T: Zeroable> Deref<T> for NonZero<T> { +impl<T: Zeroable> Deref for NonZero<T> { + 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 15016562699..b51d4d91c2f 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -861,13 +861,17 @@ pub struct RangeTo<Idx> { /// struct. /// /// ``` +/// #![feature(associated_types)] +/// /// use std::ops::Deref; /// /// struct DerefExample<T> { /// value: T /// } /// -/// impl<T> Deref<T> for DerefExample<T> { +/// impl<T> Deref for DerefExample<T> { +/// type Target = T; +/// /// fn deref<'a>(&'a self) -> &'a T { /// &self.value /// } @@ -879,16 +883,22 @@ pub struct RangeTo<Idx> { /// } /// ``` #[lang="deref"] -pub trait Deref<Sized? Result> 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<T> for &'a T { +impl<'a, Sized? T> Deref for &'a T { + type Target = T; + fn deref(&self) -> &T { *self } } -impl<'a, Sized? T> Deref<T> for &'a mut T { +impl<'a, Sized? T> Deref for &'a mut T { + type Target = T; + fn deref(&self) -> &T { *self } } @@ -901,19 +911,23 @@ impl<'a, Sized? T> Deref<T> for &'a mut T { /// struct. /// /// ``` +/// #![feature(associated_types)] +/// /// use std::ops::{Deref, DerefMut}; /// /// struct DerefMutExample<T> { /// value: T /// } /// -/// impl<T> Deref<T> for DerefMutExample<T> { +/// impl<T> Deref for DerefMutExample<T> { +/// type Target = T; +/// /// fn deref<'a>(&'a self) -> &'a T { /// &self.value /// } /// } /// -/// impl<T> DerefMut<T> for DerefMutExample<T> { +/// impl<T> DerefMut for DerefMutExample<T> { /// fn deref_mut<'a>(&'a mut self) -> &'a mut T { /// &mut self.value /// } @@ -926,12 +940,12 @@ impl<'a, Sized? T> Deref<T> for &'a mut T { /// } /// ``` #[lang="deref_mut"] -pub trait DerefMut<Sized? Result> for Sized? : Deref<Result> { +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 <Self as Deref>::Target; } -impl<'a, Sized? T> DerefMut<T> 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 d831a57893b..b9749f57d58 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -699,7 +699,7 @@ impl<T> Option<T> { } } -impl<'a, T: Clone, D: Deref<T>> Option<D> { +impl<'a, T: Clone, D: Deref<Target=T>> Option<D> { /// Maps an Option<D> to an Option<T> by dereffing and cloning the contents of the Option. /// Useful for converting an Option<&T> to an Option<T>. #[unstable = "recently added as part of collections reform"] diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 210850be13a..8cb63138009 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -49,5 +49,4 @@ pub use option::Option::{mod, Some, None}; pub use ptr::{PtrExt, MutPtrExt}; pub use result::Result::{mod, Ok, Err}; pub use slice::{AsSlice, SliceExt}; -pub use slice::{PartialEqSliceExt, OrdSliceExt}; pub use str::{Str, StrExt}; diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 38e47a5ad33..f29d7518149 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -243,7 +243,9 @@ pub unsafe fn write<T>(dst: *mut T, src: T) { /// Methods on raw pointers #[stable] -pub trait PtrExt<T> : Sized { +pub trait PtrExt: Sized { + type Target; + /// Returns the null pointer. #[deprecated = "call ptr::null instead"] fn null() -> Self; @@ -271,7 +273,7 @@ pub trait PtrExt<T> : Sized { /// 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::<T>()` bytes. @@ -287,7 +289,9 @@ pub trait PtrExt<T> : Sized { /// Methods on mutable raw pointers #[stable] -pub trait MutPtrExt<T>{ +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<T>{ /// 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<T> PtrExt<T> for *const T { +impl<T> PtrExt for *const T { + type Target = T; + #[inline] #[deprecated = "call ptr::null instead"] fn null() -> *const T { null() } @@ -333,7 +339,9 @@ impl<T> PtrExt<T> for *const T { } #[stable] -impl<T> PtrExt<T> for *mut T { +impl<T> PtrExt for *mut T { + type Target = T; + #[inline] #[deprecated = "call ptr::null instead"] fn null() -> *mut T { null_mut() } @@ -365,7 +373,9 @@ impl<T> PtrExt<T> for *mut T { } #[stable] -impl<T> MutPtrExt<T> for *mut T { +impl<T> 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 7d894ac697b..07addf7a569 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<T> 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<F>(&self, f: F) -> Result<uint, uint> 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<P>(&mut self, n: uint, pred: P) -> SplitNMut<T, P> - where P: FnMut(&T) -> bool; - fn rsplitn_mut<P>(&mut self, n: uint, pred: P) -> RSplitNMut<T, P> - 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<P>(&mut self, n: uint, pred: P) -> SplitNMut<Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + fn rsplitn_mut<P>(&mut self, n: uint, pred: P) -> RSplitNMut<Self::Item, P> + 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<uint> where Self::Item: PartialEq; + + fn rposition_elem(&self, t: &Self::Item) -> Option<uint> 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<uint, uint> 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<T> SliceExt<T> for [T] { +impl<T> SliceExt for [T] { + type Item = T; + #[inline] fn slice(&self, start: uint, end: uint) -> &[T] { assert!(start <= end); @@ -404,153 +424,41 @@ impl<T> SliceExt<T> for [T] { fn as_mut_ptr(&mut self) -> *mut T { self.repr().data as *mut T } -} - -impl<T> ops::Index<uint, T> for [T] { - fn index(&self, &index: &uint) -> &T { - assert!(index < self.len()); - - unsafe { mem::transmute(self.repr().data.offset(index as int)) } - } -} - -impl<T> ops::IndexMut<uint, T> 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<T> ops::Slice<uint, [T]> 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<T> ops::SliceMut<uint, [T]> 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<T: PartialEq> for Sized? { - /// Find the first index containing a matching value. - #[experimental] - fn position_elem(&self, t: &T) -> Option<uint>; - - /// Find the last index containing a matching value. - #[experimental] - fn rposition_elem(&self, t: &T) -> Option<uint>; - - /// 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<T: PartialEq> PartialEqSliceExt<T> for [T] { #[inline] - fn position_elem(&self, x: &T) -> Option<uint> { + fn position_elem(&self, x: &T) -> Option<uint> where T: PartialEq { self.iter().position(|y| *x == *y) } #[inline] - fn rposition_elem(&self, t: &T) -> Option<uint> { + fn rposition_elem(&self, t: &T) -> Option<uint> 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<T: Ord> for Sized? { - fn binary_search(&self, x: &T) -> Result<uint, uint>; - fn next_permutation(&mut self) -> bool; - fn prev_permutation(&mut self) -> bool; -} - -#[unstable = "trait is unstable"] -impl<T: Ord> OrdSliceExt<T> for [T] { #[unstable] - fn binary_search(&self, x: &T) -> Result<uint, uint> { + fn binary_search(&self, x: &T) -> Result<uint, uint> 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<T: Ord> OrdSliceExt<T> 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<T: Ord> OrdSliceExt<T> 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<T> for Sized? { - fn clone_from_slice(&mut self, &[T]) -> uint; -} - -#[unstable = "trait is unstable"] -impl<T: Clone> CloneSliceExt<T> 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<T: Clone> CloneSliceExt<T> for [T] { } } +impl<T> ops::Index<uint, T> for [T] { + fn index(&self, &index: &uint) -> &T { + assert!(index < self.len()); + + unsafe { mem::transmute(self.repr().data.offset(index as int)) } + } +} + +impl<T> ops::IndexMut<uint, T> 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<T> ops::Slice<uint, [T]> 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<T> ops::SliceMut<uint, [T]> 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 0544e32b62c..d7f570df072 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,10 +390,12 @@ fn project_type<'cx,'tcx>( 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)); } @@ -415,17 +428,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<ty::TraitRef<'tcx>>, 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<ty::TraitRef<'tcx>>, candidate_set: &mut ProjectionTyCandidateSet<'tcx>, env_predicates: Vec<ty::Predicate<'tcx>>) { @@ -439,7 +455,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, @@ -461,6 +477,7 @@ fn assemble_candidates_from_predicates<'cx,'tcx>( fn assemble_candidates_from_object_type<'cx,'tcx>( selcx: &mut SelectionContext<'cx,'tcx>, obligation: &ProjectionTyObligation<'tcx>, + obligation_trait_ref: &Rc<ty::TraitRef<'tcx>>, candidate_set: &mut ProjectionTyCandidateSet<'tcx>, object_ty: Ty<'tcx>) { @@ -480,21 +497,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<ty::TraitRef<'tcx>>, candidate_set: &mut ProjectionTyCandidateSet<'tcx>) -> Result<(), SelectionError<'tcx>> { // If we are resolving `<T as TraitRef<...>>::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) => { @@ -515,7 +532,8 @@ fn assemble_candidates_from_impls<'cx,'tcx>( } super::VtableObject(data) => { assemble_candidates_from_object_type( - selcx, obligation, candidate_set, data.object_ty); + selcx, obligation, obligation_trait_ref, candidate_set, + data.object_ty); } super::VtableParam(..) => { // This case tell us nothing about the value of an diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index ca4bf7863be..d09f2a250b0 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -293,6 +293,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>) @@ -324,9 +341,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) + } + } + }) } } } @@ -1087,15 +1117,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 0a03a8e836b..999bc23c270 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -7265,7 +7265,7 @@ impl<T:ReferencesError> ReferencesError for Binder<T> { impl<T:ReferencesError> ReferencesError for Rc<T> { 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 c054dec7de4..aa3ac83c027 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -96,13 +96,15 @@ struct GraphBuilder<'a, 'b:'a, 'tcx:'b> { resolver: &'a mut Resolver<'b, 'tcx> } -impl<'a, 'b:'a, 'tcx:'b> Deref<Resolver<'b, 'tcx>> 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<Resolver<'b, 'tcx>> 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 b3d0d30726c..1bfe4c0407a 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -35,13 +35,15 @@ struct UnusedImportCheckVisitor<'a, 'b:'a, 'tcx:'b> { } // Deref and DerefMut impls allow treating UnusedImportCheckVisitor as Resolver. -impl<'a, 'b, 'tcx:'b> Deref<Resolver<'b, 'tcx>> 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<Resolver<'b, 'tcx>> 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 6baecfc30e2..4ac9224969c 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 4f314291da6..ff415750d64 100644 --- a/src/librustc_resolve/record_exports.rs +++ b/src/librustc_resolve/record_exports.rs @@ -35,13 +35,15 @@ struct ExportRecorder<'a, 'b:'a, 'tcx:'b> { } // Deref and DerefMut impls allow treating ExportRecorder as Resolver. -impl<'a, 'b, 'tcx:'b> Deref<Resolver<'b, 'tcx>> 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<Resolver<'b, 'tcx>> 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 11ee16b0445..0cfc1042ae6 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1812,6 +1812,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, @@ -1828,17 +1840,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) @@ -2123,6 +2124,15 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result { try!(write!(w, "type {} = {}", name, tydef.type_)); try!(write!(w, "</code></h4>\n")); } + clean::AssociatedTypeItem(ref typaram) => { + let name = item.name.as_ref().unwrap(); + try!(write!(w, "<h4 id='assoc_type.{}' class='{}'>{}<code>", + *name, + shortty(item), + ConciseStability(&item.stability))); + try!(assoc_type(w, item, typaram)); + try!(write!(w, "</code></h4>\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 33cf33848f0..b1433ad7fdc 100644 --- a/src/libstd/c_str.rs +++ b/src/libstd/c_str.rs @@ -549,8 +549,8 @@ pub unsafe fn from_c_multistring<F>(buf: *const libc::c_char, #[cfg(test)] mod tests { - use super::*; use prelude::v1::*; + use super::*; use ptr; use thread::Thread; use libc; diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 4738c830bd3..d4fc4150fae 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -311,7 +311,7 @@ fn search_hashed<K, V, M, F>(table: M, hash: SafeHash, mut is_match: F) -> SearchResult<K, V, M> where - M: Deref<RawTable<K, V>>, + M: Deref<Target=RawTable<K, V>>, 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 6938ab9b0b6..a687ba3da8d 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -210,7 +210,7 @@ impl<K, V, M> Bucket<K, V, M> { } } -impl<K, V, M: Deref<RawTable<K, V>>> Bucket<K, V, M> { +impl<K, V, M: Deref<Target=RawTable<K, V>>> Bucket<K, V, M> { pub fn new(table: M, hash: SafeHash) -> Bucket<K, V, M> { Bucket::at_index(table, hash.inspect() as uint) } @@ -279,7 +279,7 @@ impl<K, V, M: Deref<RawTable<K, V>>> Bucket<K, V, M> { } } -impl<K, V, M: Deref<RawTable<K, V>>> EmptyBucket<K, V, M> { +impl<K, V, M: Deref<Target=RawTable<K, V>>> EmptyBucket<K, V, M> { #[inline] pub fn next(self) -> Bucket<K, V, M> { let mut bucket = self.into_bucket(); @@ -315,7 +315,7 @@ impl<K, V, M: Deref<RawTable<K, V>>> EmptyBucket<K, V, M> { } } -impl<K, V, M: DerefMut<RawTable<K, V>>> EmptyBucket<K, V, M> { +impl<K, V, M: Deref<Target=RawTable<K, V>> + DerefMut> EmptyBucket<K, V, M> { /// 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<K, V, M: DerefMut<RawTable<K, V>>> EmptyBucket<K, V, M> { } } -impl<K, V, M: Deref<RawTable<K, V>>> FullBucket<K, V, M> { +impl<K, V, M: Deref<Target=RawTable<K, V>>> FullBucket<K, V, M> { #[inline] pub fn next(self) -> Bucket<K, V, M> { let mut bucket = self.into_bucket(); @@ -384,7 +384,7 @@ impl<K, V, M: Deref<RawTable<K, V>>> FullBucket<K, V, M> { } } -impl<K, V, M: DerefMut<RawTable<K, V>>> FullBucket<K, V, M> { +impl<K, V, M: Deref<Target=RawTable<K, V>> + DerefMut> FullBucket<K, V, M> { /// 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<K, V, M: DerefMut<RawTable<K, V>>> FullBucket<K, V, M> { } } -impl<'t, K, V, M: Deref<RawTable<K, V>> + 't> FullBucket<K, V, M> { +impl<'t, K, V, M: Deref<Target=RawTable<K, V>> + 't> FullBucket<K, V, M> { /// 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<RawTable<K, V>> + 't> FullBucket<K, V, M> { } } -impl<'t, K, V, M: DerefMut<RawTable<K, V>> + 't> FullBucket<K, V, M> { +impl<'t, K, V, M: Deref<Target=RawTable<K, V>> + DerefMut + 't> FullBucket<K, V, M> { /// 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<K, V, M> BucketState<K, V, M> { } } -impl<K, V, M: Deref<RawTable<K, V>>> GapThenFull<K, V, M> { +impl<K, V, M: Deref<Target=RawTable<K, V>>> GapThenFull<K, V, M> { #[inline] pub fn full(&self) -> &FullBucket<K, V, M> { &self.full diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs index 3cdfa8beb07..f47f6237b72 100644 --- a/src/libstd/io/comm_adapters.rs +++ b/src/libstd/io/comm_adapters.rs @@ -14,7 +14,7 @@ use sync::mpsc::{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 e5d95974edb..ad921e43c0c 100644 --- a/src/libstd/io/mem.rs +++ b/src/libstd/io/mem.rs @@ -402,8 +402,8 @@ mod test { use prelude::v1::*; use super::*; - use io; use io::{SeekSet, SeekCur, SeekEnd}; + use io; use self::test_crate::Bencher; #[test] diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 8f7de1c4dca..0a7815aeb53 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1941,8 +1941,8 @@ impl fmt::Show for FilePermission { #[cfg(test)] mod tests { use self::BadReaderBehavior::*; - use super::{IoResult, MemReader, NoProgress, InvalidInput}; - use prelude::v1::*; + use super::{IoResult, Reader, MemReader, NoProgress, InvalidInput, Writer}; + use prelude::v1::{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 7ce1d1fc13b..2a18b839778 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 ba709b2dc74..cd991c5f884 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<BufferedReader<StdReader>> for StdinReaderGuard<'a> { +impl<'a> Deref for StdinReaderGuard<'a> { + type Target = BufferedReader<StdReader>; + fn deref(&self) -> &BufferedReader<StdReader> { &self.inner.0 } } -impl<'a> DerefMut<BufferedReader<StdReader>> for StdinReaderGuard<'a> { +impl<'a> DerefMut for StdinReaderGuard<'a> { fn deref_mut(&mut self) -> &mut BufferedReader<StdReader> { &mut self.inner.0 } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 848d3604953..7c8aab2b31d 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -108,6 +108,7 @@ #![feature(default_type_params, phase, lang_items, unsafe_destructor)] #![feature(slicing_syntax, unboxed_closures)] #![feature(old_orphan_check)] +#![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 47be8b2dcf9..63fd3209cc0 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 febdf5f6118..6c64251091a 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 02e520daaf2..615a20baf89 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, ATOMIC_INT_INIT, SeqCst}; diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index 024dc56073d..731c3bbe427 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 102da31a293..6075010f3b5 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}; @@ -453,7 +452,7 @@ mod tests { use iter::{IteratorExt, DoubleEndedIteratorExt}; use option::Option::{mod, Some, None}; use path::GenericPath; - use slice::{AsSlice, SliceExt, CloneSliceExt}; + use slice::{AsSlice, SliceExt}; use str::{mod, Str, StrExt}; use string::ToString; use vec::Vec; diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index a6d30dc5778..55086ad3a23 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -1127,7 +1127,7 @@ mod tests { use iter::{IteratorExt, DoubleEndedIteratorExt}; use option::Option::{mod, Some, None}; use path::GenericPath; - use slice::{AsSlice, SliceExt, CloneSliceExt}; + use slice::{AsSlice, SliceExt}; use str::Str; use string::ToString; use vec::Vec; diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs index 33146f5e622..cb5dfafb4a1 100644 --- a/src/libstd/prelude/v1.rs +++ b/src/libstd/prelude/v1.rs @@ -36,9 +36,7 @@ #[stable] #[doc(no_inline)] pub use ptr::{PtrExt, MutPtrExt}; #[stable] #[doc(no_inline)] pub use result::Result::{mod, Ok, Err}; #[stable] #[doc(no_inline)] pub use slice::AsSlice; -#[stable] #[doc(no_inline)] pub use slice::{BoxedSliceExt, SliceExt}; -#[stable] #[doc(no_inline)] pub use slice::{CloneSliceExt, OrdSliceExt}; -#[stable] #[doc(no_inline)] pub use slice::{PartialEqSliceExt, SliceConcatExt}; +#[stable] #[doc(no_inline)] pub use slice::{SliceExt, SliceConcatExt}; #[stable] #[doc(no_inline)] pub use str::{Str, StrExt}; #[stable] #[doc(no_inline)] pub use string::{String, ToString}; #[stable] #[doc(no_inline)] pub use vec::Vec; diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 270c57f1ec0..f9f9a809221 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -291,12 +291,14 @@ impl<'mutex, T> MutexGuard<'mutex, T> { } } -impl<'mutex, T> Deref<T> 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<T> 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 b23fff31c0a..431aeb9cae9 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -327,13 +327,17 @@ impl<'rwlock, T> RWLockWriteGuard<'rwlock, T> { } } -impl<'rwlock, T> Deref<T> 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<T> 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<T> 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 7a6824ac27c..18cdb3fc647 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -27,6 +27,7 @@ #![feature(quote, unsafe_destructor)] #![feature(unboxed_closures)] #![feature(old_orphan_check)] +#![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 f7d2331c9ec..bc2e0923115 100644 --- a/src/libsyntax/owned_slice.rs +++ b/src/libsyntax/owned_slice.rs @@ -56,7 +56,9 @@ impl<T> OwnedSlice<T> { } } -impl<T> Deref<[T]> for OwnedSlice<T> { +impl<T> Deref for OwnedSlice<T> { + 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 9c6644c5204..2745b7e13e9 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -608,7 +608,9 @@ impl InternedString { } } -impl Deref<str> 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 8b1aed483c3..a989b323723 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -77,7 +77,9 @@ impl<T: 'static> P<T> { } } -impl<T> Deref<T> for P<T> { +impl<T> Deref for P<T> { + 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 d25161a12a7..6e087778de9 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -126,7 +126,9 @@ impl BorrowFrom<RcStr> for str { } } -impl Deref<str> 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 6a9bfa07cf7..34beb53bd07 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 26d61e166f2..05960a5b8e1 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<H, T> { @@ -24,7 +26,9 @@ impl<T> Helper<T> for Option<T> { } } -impl<T, H: Helper<T>> Deref<T> for DerefWithHelper<H, T> { +impl<T, H: Helper<T>> Deref for DerefWithHelper<H, T> { + 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 00000000000..5743216b6ca --- /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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<RHS=Self> { + type Output; + + fn add(self, RHS) -> Self::Output; +} + +fn ice<A>(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 05bc0d1e13b..7cd170f7773 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<T> { value: *mut T } -impl<T> Deref<T> for Own<T> { +impl<T> Deref for Own<T> { + type Target = T; + fn deref(&self) -> &T { unsafe { &*self.value } } } -impl<T> DerefMut<T> for Own<T> { +impl<T> DerefMut for Own<T> { 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 5aaefd01739..759467aeda3 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<T> { value: *const T } -impl<T> Deref<T> for Rc<T> { +impl<T> Deref for Rc<T> { + 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 974fe3bc5d5..74dceab18ea 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<T> { value: *mut T } -impl<T> Deref<T> for Own<T> { +impl<T> Deref for Own<T> { + type Target = T; + fn deref<'a>(&'a self) -> &'a T { unsafe { &*self.value } } } -impl<T> DerefMut<T> for Own<T> { +impl<T> DerefMut for Own<T> { 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 5397c5b8a56..635e440c6fe 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<T> { value: *const T } -impl<T> Deref<T> for Rc<T> { +impl<T> Deref for Rc<T> { + 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 e4c6fa7d47f..ab770c099e1 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<Foo> 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 c2e4629e14d..491707a9e31 100644 --- a/src/test/compile-fail/issue-18566.rs +++ b/src/test/compile-fail/issue-18566.rs @@ -8,10 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(associated_types)] + use std::ops::Deref; struct MyPtr<'a>(&'a mut uint); -impl<'a> Deref<uint> 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 00000000000..3b53203d218 --- /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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<Sized? U=Self> for Sized? { + fn eq(&self, u: &U) -> bool; +} + +impl<A, B> MyEq<[B]> for [A] + where A : MyEq<B> +{ + 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<B>, Lhs: Deref<Target=[A]> +{ + fn eq(&self, other: &[B; 0]) -> bool { + MyEq::eq(&**self, other.as_slice()) + } +} + +struct DerefWithHelper<H, T> { + pub helper: H +} + +trait Helper<T> { + fn helper_borrow(&self) -> &T; +} + +impl<T> Helper<T> for Option<T> { + fn helper_borrow(&self) -> &T { + self.as_ref().unwrap() + } +} + +impl<T, H: Helper<T>> Deref for DerefWithHelper<H, T> { + type Target = T; + + fn deref(&self) -> &T { + self.helper.helper_borrow() + } +} + +pub fn check<T: MyEq>(x: T, y: T) -> bool { + let d: DerefWithHelper<Option<T>, 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 5a98952c127..f43be177862 100644 --- a/src/test/run-pass/deref-mut-on-ref.rs +++ b/src/test/run-pass/deref-mut-on-ref.rs @@ -10,9 +10,9 @@ // Test that `&mut T` implements `DerefMut<T>` -use std::ops::DerefMut; +use std::ops::{Deref, DerefMut}; -fn inc<T:DerefMut<int>>(mut t: T) { +fn inc<T: Deref<Target=int> + 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 f245c11f090..e95d942c8cf 100644 --- a/src/test/run-pass/deref-on-ref.rs +++ b/src/test/run-pass/deref-on-ref.rs @@ -12,7 +12,7 @@ use std::ops::Deref; -fn deref<U:Copy,T:Deref<U>>(t: T) -> U { +fn deref<U:Copy,T:Deref<Target=U>>(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 0cbcee3e253..0e0ed1f436c 100644 --- a/src/test/run-pass/dst-deref-mut.rs +++ b/src/test/run-pass/dst-deref-mut.rs @@ -10,19 +10,23 @@ // Test that a custom deref with a fat pointer return type does not ICE +#![feature(associated_types)] + use std::ops::{Deref, DerefMut}; 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 96a9c117dea..a39670a27b9 100644 --- a/src/test/run-pass/dst-deref.rs +++ b/src/test/run-pass/dst-deref.rs @@ -10,13 +10,17 @@ // Test that a custom deref with a fat pointer return type does not ICE +#![feature(associated_types)] + use std::ops::Deref; 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 70d14ba3623..8fb3893e5de 100644 --- a/src/test/run-pass/fixup-deref-mut.rs +++ b/src/test/run-pass/fixup-deref-mut.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, DerefMut}; // Generic unique/owned smaht pointer. @@ -15,13 +17,15 @@ struct Own<T> { value: *mut T } -impl<T> Deref<T> for Own<T> { +impl<T> Deref for Own<T> { + type Target = T; + fn deref<'a>(&'a self) -> &'a T { unsafe { &*self.value } } } -impl<T> DerefMut<T> for Own<T> { +impl<T> DerefMut for Own<T> { 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 5f82730c27c..00b508ab92c 100644 --- a/src/test/run-pass/issue-13264.rs +++ b/src/test/run-pass/issue-13264.rs @@ -8,13 +8,17 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(associated_types)] + use std::ops::Deref; struct Root { jsref: JSRef } -impl Deref<JSRef> for Root { +impl Deref for Root { + type Target = JSRef; + fn deref<'a>(&'a self) -> &'a JSRef { &self.jsref } @@ -25,7 +29,9 @@ struct JSRef { node: *const Node } -impl Deref<Node> 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 0b9a85851c5..45cfabcd872 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)] use std::ops::{Deref, DerefMut}; @@ -25,14 +25,16 @@ impl Drop for X { } } -impl Deref<int> for X { +impl Deref for X { + type Target = int; + fn deref(&self) -> &int { let &X(box ref x) = self; x } } -impl DerefMut<int> 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 baf1b1b0237..e9eb924d449 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<T> DerefCounter<T> { } } -impl<T> Deref<T> for DerefCounter<T> { +impl<T> Deref for DerefCounter<T> { + type Target = T; + fn deref(&self) -> &T { self.count_imm.set(self.count_imm.get() + 1); &self.value } } -impl<T> DerefMut<T> for DerefCounter<T> { +impl<T> DerefMut for DerefCounter<T> { 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 d1fb69b87a3..6d8d09b321e 100644 --- a/src/test/run-pass/overloaded-autoderef-indexing.rs +++ b/src/test/run-pass/overloaded-autoderef-indexing.rs @@ -8,13 +8,17 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(associated_types)] + use std::ops::Deref; 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 23a8285063f..cafb665fc37 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; use std::ops::Deref; @@ -24,7 +26,9 @@ impl<X, Y> DerefWrapper<X, Y> { } } -impl<X, Y> Deref<Y> for DerefWrapper<X, Y> { +impl<X, Y> Deref for DerefWrapper<X, Y> { + type Target = Y; + fn deref(&self) -> &Y { &self.y } @@ -49,7 +53,9 @@ mod priv_test { } } - impl<X, Y> Deref<Y> for DerefWrapperHideX<X, Y> { + impl<X, Y> Deref for DerefWrapperHideX<X, Y> { + 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 f71afb96507..23efba15749 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<H, T> { @@ -24,7 +26,9 @@ impl<T> Helper<T> for Option<T> { } } -impl<T, H: Helper<T>> Deref<T> for DerefWithHelper<H, T> { +impl<T, H: Helper<T>> Deref for DerefWithHelper<H, T> { + 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 7645500c02f..b6fb38d5cc2 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<T> DerefCounter<T> { } } -impl<T> Deref<T> for DerefCounter<T> { +impl<T> Deref for DerefCounter<T> { + type Target = T; + fn deref(&self) -> &T { self.count_imm.set(self.count_imm.get() + 1); &self.value } } -impl<T> DerefMut<T> for DerefCounter<T> { +impl<T> DerefMut for DerefCounter<T> { fn deref_mut(&mut self) -> &mut T { self.count_mut += 1; &mut self.value diff --git a/src/test/run-pass/tcp-stress.rs b/src/test/run-pass/tcp-stress.rs index 2efd0ad14bd..62b61c153c7 100644 --- a/src/test/run-pass/tcp-stress.rs +++ b/src/test/run-pass/tcp-stress.rs @@ -49,7 +49,7 @@ fn main() { stream.write(&[2]); } }).detach(); - let addr = rx.recv().unwarp(); + let addr = rx.recv().unwrap(); let (tx, rx) = channel(); for _ in range(0u, 1000) { |
