diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs
index 5fd9690d9b0..cb764228155 100644
--- a/src/libextra/num/bigint.rs
+++ b/src/libextra/num/bigint.rs
@@ -525,7 +525,7 @@ impl BigUint {
     #[inline]
     pub fn new(v: ~[BigDigit]) -> BigUint {
         // omit trailing zeros
-        let new_len = v.rposition(|n| *n != 0).map_move_default(0, |p| p + 1);
+        let new_len = v.iter().rposition(|n| *n != 0).map_move_default(0, |p| p + 1);
 
         if new_len == v.len() { return BigUint { data: v }; }
         let mut v = v;
diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs
index e2ac9f03395..d1b59c30978 100644
--- a/src/libstd/iterator.rs
+++ b/src/libstd/iterator.rs
@@ -18,7 +18,7 @@ implementing the `Iterator` trait.
 */
 
 use cmp;
-use num::{Zero, One, Integer, CheckedAdd, Saturating};
+use num::{Zero, One, Integer, CheckedAdd, CheckedSub, Saturating};
 use option::{Option, Some, None};
 use ops::{Add, Mul, Sub};
 use cmp::Ord;
@@ -604,6 +604,37 @@ impl<'self, A, T: DoubleEndedIterator<&'self mut A>> MutableDoubleEndedIterator
     }
 }
 
+/// A double-ended iterator with known size
+pub trait ExactSizeDoubleEndedIterator<A> {
+    /// Return the index of the last element satisfying the specified predicate
+    ///
+    /// If no element matches, None is returned.
+    #[inline]
+    fn rposition(&mut self, predicate: &fn(A) -> bool) -> Option<uint>;
+}
+
+impl<A, T: DoubleEndedIterator<A> + ExactSizeHint> ExactSizeDoubleEndedIterator<A> for T {
+    fn rposition(&mut self, predicate: &fn(A) -> bool) -> Option<uint> {
+        let (size, _) = self.size_hint();
+        let mut i = size;
+        loop {
+            match self.next_back() {
+                None => break,
+                Some(x) => {
+                    i = match i.checked_sub(&1) {
+                        Some(x) => x,
+                        None => fail!("rposition: incorrect ExactSizeHint")
+                    };
+                    if predicate(x) {
+                        return Some(i)
+                    }
+                }
+            }
+        }
+        None
+    }
+}
+
 /// An object implementing random access indexing by `uint`
 ///
 /// A `RandomAccessIterator` should be either infinite or a `DoubleEndedIterator`.
diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs
index 24b3dc20260..e8eb6d871ee 100644
--- a/src/libstd/prelude.rs
+++ b/src/libstd/prelude.rs
@@ -52,7 +52,7 @@ pub use hash::Hash;
 pub use num::Times;
 pub use iterator::{FromIterator, Extendable};
 pub use iterator::{Iterator, DoubleEndedIterator, RandomAccessIterator, ClonableIterator};
-pub use iterator::{OrdIterator, MutableDoubleEndedIterator};
+pub use iterator::{OrdIterator, MutableDoubleEndedIterator, ExactSizeDoubleEndedIterator};
 pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul};
 pub use num::{Orderable, Signed, Unsigned, Round};
 pub use num::{Algebraic, Trigonometric, Exponential, Hyperbolic};
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 6ddb2a72286..39560bd47e6 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -274,7 +274,7 @@ impl<'self, T> Iterator<&'self [T]> for RSplitIterator<'self, T> {
             return Some(self.v);
         }
 
-        match self.v.rposition(|x| (self.pred)(x)) {
+        match self.v.iter().rposition(|x| (self.pred)(x)) {
             None => {
                 self.finished = true;
                 Some(self.v)
@@ -832,7 +832,6 @@ pub trait ImmutableVector<'self, T> {
     fn initn(&self, n: uint) -> &'self [T];
     fn last(&self) -> &'self T;
     fn last_opt(&self) -> Option<&'self T>;
-    fn rposition(&self, f: &fn(t: &T) -> bool) -> Option<uint>;
     fn flat_map<U>(&self, f: &fn(t: &T) -> ~[U]) -> ~[U];
     unsafe fn unsafe_ref(&self, index: uint) -> *T;
 
@@ -1048,21 +1047,6 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
             if self.len() == 0 { None } else { Some(&self[self.len() - 1]) }
     }
 
-    /**
-     * Find the last index matching some predicate
-     *
-     * Apply function `f` to each element of `v` in reverse order.  When
-     * function `f` returns true then an option containing the index is
-     * returned. If `f` matches no elements then None is returned.
-     */
-    #[inline]
-    fn rposition(&self, f: &fn(t: &T) -> bool) -> Option<uint> {
-        for (i, t) in self.rev_iter().enumerate() {
-            if f(t) { return Some(self.len() - i - 1); }
-        }
-        None
-    }
-
     /**
      * Apply a function to each element of a vector and return a concatenation
      * of each result vector
@@ -1145,7 +1129,7 @@ impl<'self,T:Eq> ImmutableEqVector<T> for &'self [T] {
     /// Find the last index containing a matching value
     #[inline]
     fn rposition_elem(&self, t: &T) -> Option<uint> {
-        self.rposition(|x| *x == *t)
+        self.iter().rposition(|x| *x == *t)
     }
 
     /// Return true if a vector contains an element with the given value
@@ -2932,8 +2916,8 @@ mod tests {
         fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' }
         let v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
 
-        assert_eq!(v.rposition(f), Some(3u));
-        assert!(v.rposition(g).is_none());
+        assert_eq!(v.iter().rposition(f), Some(3u));
+        assert!(v.iter().rposition(g).is_none());
     }
 
     #[test]
@@ -3215,20 +3199,6 @@ mod tests {
         };
     }
 
-    #[test]
-    #[should_fail]
-    fn test_rposition_fail() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do v.rposition |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 1;
-            false
-        };
-    }
-
     #[test]
     #[should_fail]
     fn test_permute_fail() {