about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJorge Aparicio <japaricious@gmail.com>2015-01-01 14:53:20 -0500
committerJorge Aparicio <japaricious@gmail.com>2015-01-02 12:19:59 -0500
commit64b7c22c46b204520a6fae1c5cd750a3d3c6a66a (patch)
tree6e9a504759c5ac42f747c5739b4173d6646cd8c8
parentd55577255434d1a9969b74cc4ac5dff4c04d6054 (diff)
downloadrust-64b7c22c46b204520a6fae1c5cd750a3d3c6a66a.tar.gz
rust-64b7c22c46b204520a6fae1c5cd750a3d3c6a66a.zip
core: use assoc types in `Deref[Mut]`
-rw-r--r--src/liballoc/arc.rs4
-rw-r--r--src/liballoc/boxed.rs8
-rw-r--r--src/liballoc/lib.rs1
-rw-r--r--src/liballoc/rc.rs4
-rw-r--r--src/libcollections/btree/map.rs6
-rw-r--r--src/libcollections/btree/node.rs48
-rw-r--r--src/libcollections/string.rs8
-rw-r--r--src/libcollections/vec.rs10
-rw-r--r--src/libcore/array.rs4
-rw-r--r--src/libcore/borrow.rs4
-rw-r--r--src/libcore/cell.rs10
-rw-r--r--src/libcore/iter.rs8
-rw-r--r--src/libcore/nonzero.rs4
-rw-r--r--src/libcore/ops.rs32
-rw-r--r--src/libcore/option.rs2
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs6
-rw-r--r--src/librustc_resolve/check_unused.rs6
-rw-r--r--src/librustc_resolve/lib.rs1
-rw-r--r--src/librustc_resolve/record_exports.rs6
-rw-r--r--src/libstd/collections/hash/map.rs2
-rw-r--r--src/libstd/collections/hash/table.rs16
-rw-r--r--src/libstd/io/stdio.rs6
-rw-r--r--src/libstd/rt/exclusive.rs6
-rw-r--r--src/libstd/sync/mutex.rs6
-rw-r--r--src/libstd/sync/rwlock.rs10
-rw-r--r--src/libsyntax/lib.rs1
-rw-r--r--src/libsyntax/owned_slice.rs4
-rw-r--r--src/libsyntax/parse/token.rs4
-rw-r--r--src/libsyntax/ptr.rs4
-rw-r--r--src/libsyntax/util/interner.rs4
-rw-r--r--src/test/auxiliary/overloaded_autoderef_xc.rs6
-rw-r--r--src/test/compile-fail/borrowck-borrow-overloaded-auto-deref-mut.rs8
-rw-r--r--src/test/compile-fail/borrowck-borrow-overloaded-auto-deref.rs6
-rw-r--r--src/test/compile-fail/borrowck-borrow-overloaded-deref-mut.rs8
-rw-r--r--src/test/compile-fail/borrowck-borrow-overloaded-deref.rs6
-rw-r--r--src/test/compile-fail/infinite-autoderef.rs6
-rw-r--r--src/test/compile-fail/issue-18566.rs6
-rw-r--r--src/test/run-pass/deref-mut-on-ref.rs2
-rw-r--r--src/test/run-pass/deref-on-ref.rs2
-rw-r--r--src/test/run-pass/dst-deref-mut.rs8
-rw-r--r--src/test/run-pass/dst-deref.rs6
-rw-r--r--src/test/run-pass/fixup-deref-mut.rs8
-rw-r--r--src/test/run-pass/issue-13264.rs10
-rw-r--r--src/test/run-pass/issue-16774.rs8
-rw-r--r--src/test/run-pass/overloaded-autoderef-count.rs8
-rw-r--r--src/test/run-pass/overloaded-autoderef-indexing.rs6
-rw-r--r--src/test/run-pass/overloaded-autoderef-order.rs10
-rw-r--r--src/test/run-pass/overloaded-autoderef-vtable.rs6
-rw-r--r--src/test/run-pass/overloaded-deref-count.rs8
49 files changed, 256 insertions, 107 deletions
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 820a3838978..d38b77eb6fd 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 74f0599e486..0d6ada4b229 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -153,11 +153,13 @@ impl fmt::Show for Box<Any+'static> {
     }
 }
 
-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 }
 }
 
@@ -210,7 +212,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 61b5d43d1cb..c4858aea022 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -65,6 +65,7 @@
 
 #![no_std]
 #![feature(lang_items, phase, unsafe_destructor, default_type_params)]
+#![feature(associated_types)]
 
 #[phase(plugin, link)]
 extern crate core;
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 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 87b40aa1cee..4b85d2da4ac 100644
--- a/src/libcollections/btree/map.rs
+++ b/src/libcollections/btree/map.rs
@@ -515,13 +515,15 @@ mod stack {
         marker: marker::InvariantLifetime<'id>
     }
 
-    impl<'id, T> Deref<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 3907f28092a..d1a2916a140 100644
--- a/src/libcollections/btree/node.rs
+++ b/src/libcollections/btree/node.rs
@@ -455,7 +455,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
@@ -511,7 +513,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*
@@ -588,7 +590,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`.
@@ -597,7 +599,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.
@@ -653,7 +657,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.
     //
@@ -667,7 +671,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> {
@@ -684,8 +688,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.
     ///
@@ -717,7 +722,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> {
@@ -800,7 +807,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.
@@ -862,7 +871,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.
     //
@@ -881,8 +890,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.
@@ -898,7 +908,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> {
@@ -918,7 +930,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)
@@ -929,7 +943,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/string.rs b/src/libcollections/string.rs
index b69db8b00b5..c52993ff353 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -935,7 +935,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[]) }
     }
@@ -947,7 +949,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 ce0519a2395..140c15b2f7f 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -1301,12 +1301,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() }
 }
 
@@ -1716,7 +1718,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 4b246860006..4939fc49958 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -422,7 +422,9 @@ pub struct Ref<'b, T:'b> {
 }
 
 #[unstable = "waiting for `Deref` to become stable"]
-impl<'b, T> Deref<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
@@ -478,7 +480,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
@@ -486,7 +490,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 7c53503b1ce..64bbc248ee1 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -1174,7 +1174,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 }
     }
@@ -1185,7 +1185,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()
     }
@@ -1195,7 +1195,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()
@@ -1203,7 +1203,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 af07869e95f..17a3c93d980 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -827,11 +827,14 @@ pub struct RangeTo<Idx> {
 /// struct.
 ///
 /// ```
+/// #![feature(associated_types)]
 /// 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
 ///     }
@@ -843,16 +846,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 }
 }
 
@@ -865,17 +874,20 @@ impl<'a, Sized? T> Deref<T> for &'a mut T {
 /// struct.
 ///
 /// ```
+/// #![feature(associated_types)]
 /// 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
 ///     }
@@ -888,12 +900,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/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 7dbcc810b57..56459b72225 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -95,13 +95,15 @@ struct GraphBuilder<'a, 'b:'a, 'tcx:'b> {
     resolver: &'a mut Resolver<'b, 'tcx>
 }
 
-impl<'a, 'b:'a, 'tcx:'b> Deref<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 78527315199..4395bb05040 100644
--- a/src/librustc_resolve/check_unused.rs
+++ b/src/librustc_resolve/check_unused.rs
@@ -33,13 +33,15 @@ struct UnusedImportCheckVisitor<'a, 'b:'a, 'tcx:'b> {
 }
 
 // Deref and DerefMut impls allow treating UnusedImportCheckVisitor as Resolver.
-impl<'a, 'b, 'tcx:'b> Deref<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 10756f21551..75731b5e7cd 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 9c2437c376d..9bfed1e8eb9 100644
--- a/src/librustc_resolve/record_exports.rs
+++ b/src/librustc_resolve/record_exports.rs
@@ -34,13 +34,15 @@ struct ExportRecorder<'a, 'b:'a, 'tcx:'b> {
 }
 
 // Deref and DerefMut impls allow treating ExportRecorder as Resolver.
-impl<'a, 'b, 'tcx:'b> Deref<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/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index f6063df5434..e61b9af5a12 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/stdio.rs b/src/libstd/io/stdio.rs
index b7d069eb19e..e58ff1c3ac4 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/rt/exclusive.rs b/src/libstd/rt/exclusive.rs
index 88bdb29caec..e44511169ab 100644
--- a/src/libstd/rt/exclusive.rs
+++ b/src/libstd/rt/exclusive.rs
@@ -74,10 +74,12 @@ impl<'a, T: Send> ExclusiveGuard<'a, T> {
     }
 }
 
-impl<'a, T: Send> Deref<T> for ExclusiveGuard<'a, T> {
+impl<'a, T: Send> Deref for ExclusiveGuard<'a, T> {
+    type Target = T;
+
     fn deref(&self) -> &T { &*self._data }
 }
-impl<'a, T: Send> DerefMut<T> for ExclusiveGuard<'a, T> {
+impl<'a, T: Send> DerefMut for ExclusiveGuard<'a, T> {
     fn deref_mut(&mut self) -> &mut T { &mut *self._data }
 }
 
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index 52004bb4a8f..08980eb01c6 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -288,12 +288,14 @@ impl<'mutex, T> MutexGuard<'mutex, T> {
     }
 }
 
-impl<'mutex, T> Deref<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 7f3c77c97ad..7478e903355 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -326,13 +326,17 @@ impl<'rwlock, T> RWLockWriteGuard<'rwlock, T> {
     }
 }
 
-impl<'rwlock, T> Deref<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 d5093c5055c..d86db4e177e 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -26,6 +26,7 @@
 #![feature(macro_rules, globs, default_type_params, phase, slicing_syntax)]
 #![feature(quote, unsafe_destructor)]
 #![feature(unboxed_closures)]
+#![feature(associated_types)]
 
 extern crate arena;
 extern crate fmt_macros;
diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs
index 3023c547fb0..8c00aaf9bee 100644
--- a/src/libsyntax/owned_slice.rs
+++ b/src/libsyntax/owned_slice.rs
@@ -54,7 +54,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 f22a4b5c6ed..61da1c25926 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -606,7 +606,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 1b3ebde2461..5d4f50f5fd2 100644
--- a/src/libsyntax/ptr.rs
+++ b/src/libsyntax/ptr.rs
@@ -75,7 +75,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 97eb4316583..5dde8db6155 100644
--- a/src/libsyntax/util/interner.rs
+++ b/src/libsyntax/util/interner.rs
@@ -124,7 +124,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/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/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 f64d8fee2d8..1ccd1753c76 100644
--- a/src/test/compile-fail/issue-18566.rs
+++ b/src/test/compile-fail/issue-18566.rs
@@ -8,8 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
+
 struct MyPtr<'a>(&'a mut uint);
-impl<'a> Deref<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/deref-mut-on-ref.rs b/src/test/run-pass/deref-mut-on-ref.rs
index dcf7c483b2c..03848b2d820 100644
--- a/src/test/run-pass/deref-mut-on-ref.rs
+++ b/src/test/run-pass/deref-mut-on-ref.rs
@@ -10,7 +10,7 @@
 
 // Test that `&mut T` implements `DerefMut<T>`
 
-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 27e7d8f3ba2..7ebf7a9cd30 100644
--- a/src/test/run-pass/deref-on-ref.rs
+++ b/src/test/run-pass/deref-on-ref.rs
@@ -10,7 +10,7 @@
 
 // Test that `&T` and `&mut T` implement `Deref<T>`
 
-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 c2707a1ae6e..72a07ca7d35 100644
--- a/src/test/run-pass/dst-deref-mut.rs
+++ b/src/test/run-pass/dst-deref-mut.rs
@@ -10,17 +10,21 @@
 
 // Test that a custom deref with a fat pointer return type does not ICE
 
+#![feature(associated_types)]
+
 pub struct Arr {
     ptr: Box<[uint]>
 }
 
-impl Deref<[uint]> for Arr {
+impl Deref for Arr {
+    type Target = [uint];
+
     fn deref(&self) -> &[uint] {
         panic!();
     }
 }
 
-impl DerefMut<[uint]> for Arr {
+impl DerefMut for Arr {
     fn deref_mut(&mut self) -> &mut [uint] {
         &mut *self.ptr
     }
diff --git a/src/test/run-pass/dst-deref.rs b/src/test/run-pass/dst-deref.rs
index 43b7d116d30..8d32216697d 100644
--- a/src/test/run-pass/dst-deref.rs
+++ b/src/test/run-pass/dst-deref.rs
@@ -10,11 +10,15 @@
 
 // Test that a custom deref with a fat pointer return type does not ICE
 
+#![feature(associated_types)]
+
 pub struct Arr {
     ptr: Box<[uint]>
 }
 
-impl Deref<[uint]> for Arr {
+impl Deref for Arr {
+    type Target = [uint];
+
     fn deref(&self) -> &[uint] {
         &*self.ptr
     }
diff --git a/src/test/run-pass/fixup-deref-mut.rs b/src/test/run-pass/fixup-deref-mut.rs
index d2812ce1d2c..9c2a8575bb9 100644
--- a/src/test/run-pass/fixup-deref-mut.rs
+++ b/src/test/run-pass/fixup-deref-mut.rs
@@ -8,18 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
+
 // Generic unique/owned smaht pointer.
 struct Own<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 06ab67f2f3e..aac33f3d8a6 100644
--- a/src/test/run-pass/issue-13264.rs
+++ b/src/test/run-pass/issue-13264.rs
@@ -8,11 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
+
 struct Root {
     jsref: JSRef
 }
 
-impl Deref<JSRef> for Root {
+impl Deref for Root {
+    type Target = JSRef;
+
     fn deref<'a>(&'a self) -> &'a JSRef {
         &self.jsref
     }
@@ -23,7 +27,9 @@ struct JSRef {
     node: *const Node
 }
 
-impl Deref<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 ebc879d82fb..1b5016d198d 100644
--- a/src/test/run-pass/issue-16774.rs
+++ b/src/test/run-pass/issue-16774.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(unboxed_closures)]
+#![feature(associated_types, unboxed_closures)]
 
 struct X(Box<int>);
 
@@ -23,14 +23,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 4cf5e074139..5b105646dac 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 5c4befcd0c8..7d550c925b7 100644
--- a/src/test/run-pass/overloaded-autoderef-indexing.rs
+++ b/src/test/run-pass/overloaded-autoderef-indexing.rs
@@ -8,11 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
+
 struct DerefArray<'a, T:'a> {
     inner: &'a [T]
 }
 
-impl<'a, T> Deref<&'a [T]> for DerefArray<'a, T> {
+impl<'a, T> Deref for DerefArray<'a, T> {
+    type Target = &'a [T];
+
     fn deref<'b>(&'b self) -> &'b &'a [T] {
         &self.inner
     }
diff --git a/src/test/run-pass/overloaded-autoderef-order.rs b/src/test/run-pass/overloaded-autoderef-order.rs
index f0daf371ca7..5b45413e760 100644
--- a/src/test/run-pass/overloaded-autoderef-order.rs
+++ b/src/test/run-pass/overloaded-autoderef-order.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
+
 use std::rc::Rc;
 
 struct DerefWrapper<X, Y> {
@@ -23,7 +25,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
     }
@@ -46,7 +50,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