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
This commit is contained in:
Alex Crichton 2015-01-02 12:16:41 -08:00
commit 340f3fd7a9
74 changed files with 947 additions and 637 deletions

View File

@ -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

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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

View File

@ -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
}

View File

@ -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) {

View File

@ -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;

View File

@ -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,23 +951,71 @@ 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
////////////////////////////////////////////////////////////////////////////////
/// Returns a copy of `v`.
#[inline]
fn to_vec(&self) -> Vec<T> where T: Clone {
let mut vector = Vec::with_capacity(self.len());
vector.push_all(self);
vector
}
/// 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> {
#[inline]
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> where T: Clone {
Permutations{
swaps: ElementSwaps::new(self.len()),
v: self.to_vec(),
}
}
fn clone_from_slice(&mut self, src: &[T]) -> uint where T: Clone {
core_slice::SliceExt::clone_from_slice(self, src)
}
#[inline]
fn sort(&mut self) where T: Ord {
self.sort_by(|a, b| a.cmp(b))
}
fn binary_search(&self, x: &T) -> Result<uint, uint> where T: Ord {
core_slice::SliceExt::binary_search(self, x)
}
fn next_permutation(&mut self) -> bool where T: Ord {
core_slice::SliceExt::next_permutation(self)
}
fn prev_permutation(&mut self) -> bool where T: Ord {
core_slice::SliceExt::prev_permutation(self)
}
fn position_elem(&self, t: &T) -> Option<uint> where T: PartialEq {
core_slice::SliceExt::position_elem(self, t)
}
fn rposition_elem(&self, t: &T) -> Option<uint> where T: PartialEq {
core_slice::SliceExt::rposition_elem(self, t)
}
fn contains(&self, x: &T) -> bool where T: PartialEq {
core_slice::SliceExt::contains(self, x)
}
fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq {
core_slice::SliceExt::starts_with(self, needle)
}
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);
@ -806,204 +1024,9 @@ impl<T> BoxedSliceExt<T> for Box<[T]> {
}
}
/// 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> {
let mut vector = Vec::with_capacity(self.len());
vector.push_all(self);
vector
}
#[inline]
fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
self.iter().cloned().partition(f)
}
/// Returns an iterator over all permutations of a vector.
fn permutations(&self) -> Permutations<T> {
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)
}
}
/// 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);
/// 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>;
/// Deprecated: use `binary_search` instead.
#[deprecated = "use binary_search instead"]
fn binary_search_elem(&self, x: &T) -> Result<uint, uint> {
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;
/// 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;
}
#[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 binary_search(&self, x: &T) -> Result<uint, uint> {
core_slice::OrdSliceExt::binary_search(self, x)
}
fn next_permutation(&mut self) -> bool {
core_slice::OrdSliceExt::next_permutation(self)
}
fn prev_permutation(&mut self) -> bool {
core_slice::OrdSliceExt::prev_permutation(self)
}
}
////////////////////////////////////////////////////////////////////////////////
// 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;

View File

@ -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) }
}

View File

@ -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
}

View File

@ -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[]) }

View File

@ -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,

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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 }
}

View File

@ -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"]

View File

@ -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};

View File

@ -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"]

View File

@ -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,6 +424,111 @@ impl<T> SliceExt<T> for [T] {
fn as_mut_ptr(&mut self) -> *mut T {
self.repr().data as *mut T
}
#[inline]
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> where T: PartialEq {
self.iter().rposition(|x| *x == *t)
}
#[inline]
fn contains(&self, x: &T) -> bool where T: PartialEq {
self.iter().any(|elt| *x == *elt)
}
#[inline]
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 where T: PartialEq {
let (m, n) = (self.len(), needle.len());
m >= n && needle == self[m-n..]
}
#[unstable]
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 where T: Ord {
// These cases only have 1 permutation each, so we can't do anything.
if self.len() < 2 { return false; }
// Step 1: Identify the longest, rightmost weakly decreasing part of the vector
let mut i = self.len() - 1;
while i > 0 && self[i-1] >= self[i] {
i -= 1;
}
// If that is the entire vector, this is the last-ordered permutation.
if i == 0 {
return false;
}
// Step 2: Find the rightmost element larger than the pivot (i-1)
let mut j = self.len() - 1;
while j >= i && self[j] <= self[i-1] {
j -= 1;
}
// Step 3: Swap that element with the pivot
self.swap(j, i-1);
// Step 4: Reverse the (previously) weakly decreasing part
self.slice_from_mut(i).reverse();
true
}
#[experimental]
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; }
// Step 1: Identify the longest, rightmost weakly increasing part of the vector
let mut i = self.len() - 1;
while i > 0 && self[i-1] <= self[i] {
i -= 1;
}
// If that is the entire vector, this is the first-ordered permutation.
if i == 0 {
return false;
}
// Step 2: Reverse the weakly increasing part
self.slice_from_mut(i).reverse();
// Step 3: Find the rightmost element equal to or bigger than the pivot (i-1)
let mut j = self.len() - 1;
while j >= i && self[j-1] < self[i-1] {
j -= 1;
}
// Step 4: Swap that element with the pivot
self.swap(i-1, j);
true
}
#[inline]
fn clone_from_slice(&mut self, src: &[T]) -> uint where T: Clone {
let min = cmp::min(self.len(), src.len());
let dst = self.slice_to_mut(min);
let src = src.slice_to(min);
for i in range(0, min) {
dst[i].clone_from(&src[i]);
}
min
}
}
impl<T> ops::Index<uint, T> for [T] {
@ -479,160 +604,6 @@ impl<T> ops::SliceMut<uint, [T]> for [T] {
}
}
/// 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> {
self.iter().position(|y| *x == *y)
}
#[inline]
fn rposition_elem(&self, t: &T) -> Option<uint> {
self.iter().rposition(|x| *x == *t)
}
#[inline]
fn contains(&self, x: &T) -> bool {
self.iter().any(|elt| *x == *elt)
}
#[inline]
fn starts_with(&self, needle: &[T]) -> bool {
let n = needle.len();
self.len() >= n && needle == self[..n]
}
#[inline]
fn ends_with(&self, needle: &[T]) -> bool {
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> {
self.binary_search_by(|p| p.cmp(x))
}
#[experimental]
fn next_permutation(&mut self) -> bool {
// These cases only have 1 permutation each, so we can't do anything.
if self.len() < 2 { return false; }
// Step 1: Identify the longest, rightmost weakly decreasing part of the vector
let mut i = self.len() - 1;
while i > 0 && self[i-1] >= self[i] {
i -= 1;
}
// If that is the entire vector, this is the last-ordered permutation.
if i == 0 {
return false;
}
// Step 2: Find the rightmost element larger than the pivot (i-1)
let mut j = self.len() - 1;
while j >= i && self[j] <= self[i-1] {
j -= 1;
}
// Step 3: Swap that element with the pivot
self.swap(j, i-1);
// Step 4: Reverse the (previously) weakly decreasing part
self.slice_from_mut(i).reverse();
true
}
#[experimental]
fn prev_permutation(&mut self) -> bool {
// These cases only have 1 permutation each, so we can't do anything.
if self.len() < 2 { return false; }
// Step 1: Identify the longest, rightmost weakly increasing part of the vector
let mut i = self.len() - 1;
while i > 0 && self[i-1] <= self[i] {
i -= 1;
}
// If that is the entire vector, this is the first-ordered permutation.
if i == 0 {
return false;
}
// Step 2: Reverse the weakly increasing part
self.slice_from_mut(i).reverse();
// Step 3: Find the rightmost element equal to or bigger than the pivot (i-1)
let mut j = self.len() - 1;
while j >= i && self[j-1] < self[i-1] {
j -= 1;
}
// Step 4: Swap that element with the pivot
self.swap(i-1, j);
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 {
let min = cmp::min(self.len(), src.len());
let dst = self.slice_to_mut(min);
let src = src.slice_to(min);
for i in range(0, min) {
dst[i].clone_from(&src[i]);
}
min
}
}
////////////////////////////////////////////////////////////////////////////////
// Common traits
////////////////////////////////////////////////////////////////////////////////

View File

@ -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

View File

@ -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`.

View File

@ -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()
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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;

View File

@ -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
}

View File

@ -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() {

View File

@ -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;

View File

@ -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();

View File

@ -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

View File

@ -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;

View File

@ -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]

View File

@ -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)]

View File

@ -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;

View File

@ -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
}

View File

@ -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]

View File

@ -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),*])
}

View File

@ -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;

View File

@ -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};

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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() }
}

View File

@ -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() }
}

View File

@ -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;

View File

@ -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()
}

View File

@ -608,7 +608,9 @@ impl InternedString {
}
}
impl Deref<str> for InternedString {
impl Deref for InternedString {
type Target = str;
fn deref(&self) -> &str { &*self.string }
}

View File

@ -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
}

View File

@ -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[] }
}

View File

@ -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

View File

@ -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()
}

View File

@ -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
}

View File

@ -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 }
}

View File

@ -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 }
}

View File

@ -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 }
}

View File

@ -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 }
}

View File

@ -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
}

View File

@ -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 }
}

View File

@ -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() {
}

View File

@ -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;
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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 }
}

View File

@ -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()
}

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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
}

View File

@ -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()
}

View File

@ -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

View File

@ -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) {