about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/flate.rs2
-rw-r--r--src/libcore/hashmap.rs2
-rw-r--r--src/libcore/os.rs2
-rw-r--r--src/libcore/rand.rs551
-rw-r--r--src/libcore/run.rs218
-rw-r--r--src/libcore/unstable/at_exit.rs2
-rw-r--r--src/librustpkg/path_util.rs4
-rw-r--r--src/libstd/bitv.rs5
-rw-r--r--src/libstd/sort.rs45
-rw-r--r--src/libstd/tempfile.rs4
-rw-r--r--src/libstd/test.rs19
-rw-r--r--src/libstd/timer.rs8
-rw-r--r--src/libstd/treemap.rs7
-rw-r--r--src/test/bench/core-map.rs3
-rw-r--r--src/test/bench/core-set.rs23
-rw-r--r--src/test/bench/core-std.rs14
-rw-r--r--src/test/bench/graph500-bfs.rs11
-rw-r--r--src/test/bench/noise.rs8
-rw-r--r--src/test/bench/shootout-fasta.rs4
-rw-r--r--src/test/run-pass/morestack6.rs3
20 files changed, 397 insertions, 538 deletions
diff --git a/src/libcore/flate.rs b/src/libcore/flate.rs
index 70c96c9c806..5c4181c10cf 100644
--- a/src/libcore/flate.rs
+++ b/src/libcore/flate.rs
@@ -85,7 +85,7 @@ pub fn inflate_bytes(bytes: &const [u8]) -> ~[u8] {
 #[test]
 #[allow(non_implicitly_copyable_typarams)]
 fn test_flate_round_trip() {
-    let r = rand::Rng();
+    let r = rand::rng();
     let mut words = ~[];
     for 20.times {
         words.push(r.gen_bytes(r.gen_uint_range(1, 10)));
diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs
index 1d7cc8515a6..d2be0416371 100644
--- a/src/libcore/hashmap.rs
+++ b/src/libcore/hashmap.rs
@@ -56,7 +56,7 @@ fn resize_at(capacity: uint) -> uint {
 pub fn linear_map_with_capacity<K:Eq + Hash,V>(
     initial_capacity: uint) -> HashMap<K, V> {
     let r = rand::task_rng();
-    linear_map_with_capacity_and_keys(r.gen_u64(), r.gen_u64(),
+    linear_map_with_capacity_and_keys(r.gen(), r.gen(),
                                       initial_capacity)
 }
 
diff --git a/src/libcore/os.rs b/src/libcore/os.rs
index fa3ca4577c6..1000fd88b52 100644
--- a/src/libcore/os.rs
+++ b/src/libcore/os.rs
@@ -1259,7 +1259,7 @@ mod tests {
     }
 
     fn make_rand_name() -> ~str {
-        let rng: @rand::Rng = rand::Rng();
+        let rng = rand::rng();
         let n = ~"TEST" + rng.gen_str(10u);
         assert!(getenv(n).is_none());
         n
diff --git a/src/libcore/rand.rs b/src/libcore/rand.rs
index 919c7bbb036..cdf6a5bb63d 100644
--- a/src/libcore/rand.rs
+++ b/src/libcore/rand.rs
@@ -8,7 +8,34 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Random number generation
+/*!
+Random number generation.
+
+The key functions are `random()` and `RngUtil::gen()`. These are polymorphic
+and so can be used to generate any type that implements `Rand`. Type inference
+means that often a simple call to `rand::random()` or `rng.gen()` will
+suffice, but sometimes an annotation is required, e.g. `rand::random::<float>()`.
+
+# Examples
+~~~
+use core::rand::RngUtil;
+
+fn main() {
+    let rng = rand::rng();
+    if rng.gen() { // bool
+        println(fmt!("int: %d, uint: %u", rng.gen(), rng.gen()))
+    }
+}
+~~~
+
+~~~
+fn main () {
+    let tuple_ptr = rand::random::<~(f64, char)>();
+    println(fmt!("%?", tuple_ptr))
+}
+~~~
+*/
+
 
 use int;
 use prelude::*;
@@ -20,98 +47,111 @@ use util;
 use vec;
 use libc::size_t;
 
-/// A type that can be randomly generated using an RNG
+/// A type that can be randomly generated using an Rng
 pub trait Rand {
-    fn rand(rng: @rand::Rng) -> Self;
+    fn rand<R: Rng>(rng: &R) -> Self;
 }
 
 impl Rand for int {
-    fn rand(rng: @rand::Rng) -> int {
-        rng.gen_int()
+    fn rand<R: Rng>(rng: &R) -> int {
+        if int::bits == 32 {
+            rng.next() as int
+        } else {
+            rng.gen::<i64>() as int
+        }
     }
 }
 
 impl Rand for i8 {
-    fn rand(rng: @rand::Rng) -> i8 {
-        rng.gen_i8()
+    fn rand<R: Rng>(rng: &R) -> i8 {
+        rng.next() as i8
     }
 }
 
 impl Rand for i16 {
-    fn rand(rng: @rand::Rng) -> i16 {
-        rng.gen_i16()
+    fn rand<R: Rng>(rng: &R) -> i16 {
+        rng.next() as i16
     }
 }
 
 impl Rand for i32 {
-    fn rand(rng: @rand::Rng) -> i32 {
-        rng.gen_i32()
+    fn rand<R: Rng>(rng: &R) -> i32 {
+        rng.next() as i32
     }
 }
 
 impl Rand for i64 {
-    fn rand(rng: @rand::Rng) -> i64 {
-        rng.gen_i64()
+    fn rand<R: Rng>(rng: &R) -> i64 {
+        (rng.next() as i64 << 32) | rng.next() as i64
     }
 }
 
 impl Rand for uint {
-    fn rand(rng: @rand::Rng) -> uint {
-        rng.gen_uint()
+    fn rand<R: Rng>(rng: &R) -> uint {
+        if uint::bits == 32 {
+            rng.next() as uint
+        } else {
+            rng.gen::<u64>() as uint
+        }
     }
 }
 
 impl Rand for u8 {
-    fn rand(rng: @rand::Rng) -> u8 {
-        rng.gen_u8()
+    fn rand<R: Rng>(rng: &R) -> u8 {
+        rng.next() as u8
     }
 }
 
 impl Rand for u16 {
-    fn rand(rng: @rand::Rng) -> u16 {
-        rng.gen_u16()
+    fn rand<R: Rng>(rng: &R) -> u16 {
+        rng.next() as u16
     }
 }
 
 impl Rand for u32 {
-    fn rand(rng: @rand::Rng) -> u32 {
-        rng.gen_u32()
+    fn rand<R: Rng>(rng: &R) -> u32 {
+        rng.next()
     }
 }
 
 impl Rand for u64 {
-    fn rand(rng: @rand::Rng) -> u64 {
-        rng.gen_u64()
+    fn rand<R: Rng>(rng: &R) -> u64 {
+        (rng.next() as u64 << 32) | rng.next() as u64
     }
 }
 
 impl Rand for float {
-    fn rand(rng: @rand::Rng) -> float {
-        rng.gen_float()
+    fn rand<R: Rng>(rng: &R) -> float {
+        rng.gen::<f64>() as float
     }
 }
 
 impl Rand for f32 {
-    fn rand(rng: @rand::Rng) -> f32 {
-        rng.gen_f32()
+    fn rand<R: Rng>(rng: &R) -> f32 {
+        rng.gen::<f64>() as f32
     }
 }
 
+static scale : f64 = (u32::max_value as f64) + 1.0f64;
 impl Rand for f64 {
-    fn rand(rng: @rand::Rng) -> f64 {
-        rng.gen_f64()
+    fn rand<R: Rng>(rng: &R) -> f64 {
+        let u1 = rng.next() as f64;
+        let u2 = rng.next() as f64;
+        let u3 = rng.next() as f64;
+
+        ((u1 / scale + u2) / scale + u3) / scale
     }
 }
 
 impl Rand for char {
-    fn rand(rng: @rand::Rng) -> char {
-        rng.gen_char()
+    fn rand<R: Rng>(rng: &R) -> char {
+        rng.next() as char
     }
 }
 
 impl Rand for bool {
-    fn rand(rng: @rand::Rng) -> bool {
-        rng.gen_bool()
+    fn rand<R: Rng>(rng: &R) -> bool {
+        rng.next() & 1u32 == 1u32
     }
 }
 
@@ -123,10 +163,10 @@ macro_rules! tuple_impl {
             $( $tyvar : Rand ),*
             > Rand for ( $( $tyvar ),* , ) {
 
-            fn rand (_rng: @Rng) -> ( $( $tyvar ),* , ) {
+            fn rand<R: Rng>(_rng: &R) -> ( $( $tyvar ),* , ) {
                 (
-                    // use the $var's to get the appropriate number of repeats
-                    // (they're not actually needed)
+                    // use the $tyvar's to get the appropriate number of
+                    // repeats (they're not actually needed)
                     $(
                         _rng.gen::<$tyvar>()
                     ),*
@@ -137,7 +177,7 @@ macro_rules! tuple_impl {
     }
 }
 
-impl Rand for () { fn rand(_: @Rng) -> () { () } }
+impl Rand for () { fn rand<R: Rng>(_: &R) -> () { () } }
 tuple_impl!{A}
 tuple_impl!{A, B}
 tuple_impl!{A, B, C}
@@ -150,9 +190,9 @@ tuple_impl!{A, B, C, D, E, F, G, H, I}
 tuple_impl!{A, B, C, D, E, F, G, H, I, J}
 
 impl<T:Rand> Rand for Option<T> {
-    fn rand(rng: @rand::Rng) -> Option<T> {
-        if rng.gen_bool() {
-            Some(Rand::rand(rng))
+    fn rand<R: Rng>(rng: &R) -> Option<T> {
+        if rng.gen() {
+            Some(rng.gen())
         } else {
             None
         }
@@ -160,11 +200,11 @@ impl<T:Rand> Rand for Option<T> {
 }
 
 impl<T: Rand> Rand for ~T {
-    fn rand(rng: @Rng) -> ~T { ~rng.gen() }
+    fn rand<R: Rng>(rng: &R) -> ~T { ~rng.gen() }
 }
 
 impl<T: Rand> Rand for @T {
-    fn rand(rng: @Rng) -> @T { @rng.gen() }
+    fn rand<R: Rng>(rng: &R) -> @T { @rng.gen() }
 }
 
 #[allow(non_camel_case_types)] // runtime type
@@ -173,7 +213,7 @@ pub enum rust_rng {}
 #[abi = "cdecl"]
 pub mod rustrt {
     use libc::size_t;
-    use rand::rust_rng;
+    use super::rust_rng;
 
     pub extern {
         unsafe fn rand_seed_size() -> size_t;
@@ -187,7 +227,7 @@ pub mod rustrt {
 /// A random number generator
 pub trait Rng {
     /// Return the next random integer
-    fn next(&self) -> u32;
+    pub fn next(&self) -> u32;
 }
 
 /// A value with a particular weight compared to other values
@@ -197,91 +237,23 @@ pub struct Weighted<T> {
 }
 
 pub trait RngUtil {
-    /// Return a random value for a Rand type
+    /// Return a random value of a Rand type
     fn gen<T:Rand>(&self) -> T;
     /**
-     * Return a random int
-     *
-     * *Example*
-     *
-     * ~~~
-     *
-     * use core::rand::RngUtil;
-     *
-     * fn main() {
-     *     rng = rand::Rng();
-     *     println(fmt!("%d",rng.gen_int()));
-     * }
-     * ~~~
+     * Return a int randomly chosen from the range [start, end),
+     * failing if start >= end
      */
-    fn gen_int(&self) -> int;
     fn gen_int_range(&self, start: int, end: int) -> int;
-    /// Return a random i8
-    fn gen_i8(&self) -> i8;
-    /// Return a random i16
-    fn gen_i16(&self) -> i16;
-    /// Return a random i32
-    fn gen_i32(&self) -> i32;
-    /// Return a random i64
-    fn gen_i64(&self) -> i64;
-    /// Return a random uint
-    fn gen_uint(&self) -> uint;
     /**
      * Return a uint randomly chosen from the range [start, end),
      * failing if start >= end
      */
     fn gen_uint_range(&self, start: uint, end: uint) -> uint;
-    /// Return a random u8
-    fn gen_u8(&self) -> u8;
-    /// Return a random u16
-    fn gen_u16(&self) -> u16;
-    /// Return a random u32
-    fn gen_u32(&self) -> u32;
-    /// Return a random u64
-    fn gen_u64(&self) -> u64;
-    /**
-     * Return random float in the interval [0,1]
-     *
-     * *Example*
-     *
-     * ~~~
-     *
-     * use core::rand::RngUtil;
-     *
-     * fn main() {
-     *     rng = rand::Rng();
-     *     println(fmt!("%f",rng.gen_float()));
-     * }
-     * ~~~
-     */
-    fn gen_float(&self) -> float;
-    /// Return a random f32 in the interval [0,1]
-    fn gen_f32(&self) -> f32;
-    /// Return a random f64 in the interval [0,1]
-    fn gen_f64(&self) -> f64;
-    /// Return a random char
-    fn gen_char(&self) -> char;
     /**
      * Return a char randomly chosen from chars, failing if chars is empty
      */
     fn gen_char_from(&self, chars: &str) -> char;
     /**
-     * Return a random bool
-     *
-     * *Example*
-     *
-     * ~~~
-     *
-     * use core::rand::RngUtil;
-     *
-     * fn main() {
-     *     rng = rand::Rng();
-     *     println(fmt!("%b",rng.gen_bool()));
-     * }
-     * ~~~
-     */
-    fn gen_bool(&self) -> bool;
-    /**
      * Return a bool with a 1 in n chance of true
      *
      * *Example*
@@ -291,7 +263,7 @@ pub trait RngUtil {
      * use core::rand::RngUtil;
      *
      * fn main() {
-     *     rng = rand::Rng();
+     *     rng = rand::rng();
      *     println(fmt!("%b",rng.gen_weighted_bool(3)));
      * }
      * ~~~
@@ -307,7 +279,7 @@ pub trait RngUtil {
      * use core::rand::RngUtil;
      *
      * fn main() {
-     *     rng = rand::Rng();
+     *     rng = rand::rng();
      *     println(rng.gen_str(8));
      * }
      * ~~~
@@ -323,13 +295,12 @@ pub trait RngUtil {
      * use core::rand::RngUtil;
      *
      * fn main() {
-     *     rng = rand::Rng();
+     *     rng = rand::rng();
      *     println(fmt!("%?",rng.gen_bytes(8)));
      * }
      * ~~~
      */
     fn gen_bytes(&self, len: uint) -> ~[u8];
-    ///
     /**
      * Choose an item randomly, failing if values is empty
      *
@@ -340,7 +311,7 @@ pub trait RngUtil {
      * use core::rand::RngUtil;
      *
      * fn main() {
-     *     rng = rand::Rng();
+     *     rng = rand::rng();
      *     println(fmt!("%d",rng.choose([1,2,4,8,16,32])));
      * }
      * ~~~
@@ -359,7 +330,7 @@ pub trait RngUtil {
      * use core::rand::RngUtil;
      *
      * fn main() {
-     *     rng = rand::Rng();
+     *     rng = rand::rng();
      *     let x = [rand::Weighted {weight: 4, item: 'a'},
      *              rand::Weighted {weight: 2, item: 'b'},
      *              rand::Weighted {weight: 2, item: 'c'}];
@@ -379,7 +350,7 @@ pub trait RngUtil {
      * use core::rand::RngUtil;
      *
      * fn main() {
-     *     rng = rand::Rng();
+     *     rng = rand::rng();
      *     let x = [rand::Weighted {weight: 4, item: 'a'},
      *              rand::Weighted {weight: 2, item: 'b'},
      *              rand::Weighted {weight: 2, item: 'c'}];
@@ -399,7 +370,7 @@ pub trait RngUtil {
      * use core::rand::RngUtil;
      *
      * fn main() {
-     *     rng = rand::Rng();
+     *     rng = rand::rng();
      *     let x = [rand::Weighted {weight: 4, item: 'a'},
      *              rand::Weighted {weight: 2, item: 'b'},
      *              rand::Weighted {weight: 2, item: 'c'}];
@@ -418,7 +389,7 @@ pub trait RngUtil {
      * use core::rand::RngUtil;
      *
      * fn main() {
-     *     rng = rand::Rng();
+     *     rng = rand::rng();
      *     println(fmt!("%?",rng.shuffle([1,2,3])));
      * }
      * ~~~
@@ -434,7 +405,7 @@ pub trait RngUtil {
      * use core::rand::RngUtil;
      *
      * fn main() {
-     *     rng = rand::Rng();
+     *     rng = rand::rng();
      *     let mut y = [1,2,3];
      *     rng.shuffle_mut(y);
      *     println(fmt!("%?",y));
@@ -447,15 +418,10 @@ pub trait RngUtil {
 }
 
 /// Extension methods for random number generators
-impl RngUtil for @Rng {
+impl<R: Rng> RngUtil for R {
     /// Return a random value for a Rand type
-    fn gen<T:Rand>(&self) -> T {
-        Rand::rand(*self)
-    }
-
-    /// Return a random int
-    fn gen_int(&self) -> int {
-        self.gen_i64() as int
+    fn gen<T: Rand>(&self) -> T {
+        Rand::rand(self)
     }
 
     /**
@@ -464,32 +430,7 @@ impl RngUtil for @Rng {
      */
     fn gen_int_range(&self, start: int, end: int) -> int {
         assert!(start < end);
-        start + int::abs(self.gen_int() % (end - start))
-    }
-
-    /// Return a random i8
-    fn gen_i8(&self) -> i8 {
-        self.next() as i8
-    }
-
-    /// Return a random i16
-    fn gen_i16(&self) -> i16 {
-        self.next() as i16
-    }
-
-    /// Return a random i32
-    fn gen_i32(&self) -> i32 {
-        self.next() as i32
-    }
-
-    /// Return a random i64
-    fn gen_i64(&self) -> i64 {
-        (self.next() as i64 << 32) | self.next() as i64
-    }
-
-    /// Return a random uint
-    fn gen_uint(&self) -> uint {
-        self.gen_u64() as uint
+        start + int::abs(self.gen::<int>() % (end - start))
     }
 
     /**
@@ -498,51 +439,7 @@ impl RngUtil for @Rng {
      */
     fn gen_uint_range(&self, start: uint, end: uint) -> uint {
         assert!(start < end);
-        start + (self.gen_uint() % (end - start))
-    }
-
-    /// Return a random u8
-    fn gen_u8(&self) -> u8 {
-        self.next() as u8
-    }
-
-    /// Return a random u16
-    fn gen_u16(&self) -> u16 {
-        self.next() as u16
-    }
-
-    /// Return a random u32
-    fn gen_u32(&self) -> u32 {
-        self.next()
-    }
-
-    /// Return a random u64
-    fn gen_u64(&self) -> u64 {
-        (self.next() as u64 << 32) | self.next() as u64
-    }
-
-    /// Return a random float in the interval [0,1]
-    fn gen_float(&self) -> float {
-        self.gen_f64() as float
-    }
-
-    /// Return a random f32 in the interval [0,1]
-    fn gen_f32(&self) -> f32 {
-        self.gen_f64() as f32
-    }
-
-    /// Return a random f64 in the interval [0,1]
-    fn gen_f64(&self) -> f64 {
-        let u1 = self.next() as f64;
-        let u2 = self.next() as f64;
-        let u3 = self.next() as f64;
-        static scale : f64 = (u32::max_value as f64) + 1.0f64;
-        return ((u1 / scale + u2) / scale + u3) / scale;
-    }
-
-    /// Return a random char
-    fn gen_char(&self) -> char {
-        self.next() as char
+        start + (self.gen::<uint>() % (end - start))
     }
 
     /**
@@ -555,11 +452,6 @@ impl RngUtil for @Rng {
         self.choose(cs)
     }
 
-    /// Return a random bool
-    fn gen_bool(&self) -> bool {
-        self.next() & 1u32 == 1u32
-    }
-
     /// Return a bool with a 1-in-n chance of true
     fn gen_weighted_bool(&self, n: uint) -> bool {
         if n == 0u {
@@ -588,7 +480,7 @@ impl RngUtil for @Rng {
     /// Return a random byte string of the specified length
     fn gen_bytes(&self, len: uint) -> ~[u8] {
         do vec::from_fn(len) |_i| {
-            self.gen_u8()
+            self.gen()
         }
     }
 
@@ -605,7 +497,6 @@ impl RngUtil for @Rng {
             Some(values[self.gen_uint_range(0u, values.len())])
         }
     }
-
     /**
      * Choose an item respecting the relative weights, failing if the sum of
      * the weights is 0
@@ -668,14 +559,18 @@ impl RngUtil for @Rng {
             vec::swap(values, i, self.gen_uint_range(0u, i + 1u));
         }
     }
+}
 
+/// Create a random number generator with a default algorithm and seed.
+pub fn rng() -> IsaacRng {
+    IsaacRng::new()
 }
 
-struct RandRes {
-    rng: *rust_rng,
+pub struct IsaacRng {
+    priv rng: *rust_rng,
 }
 
-impl Drop for RandRes {
+impl Drop for IsaacRng {
     fn finalize(&self) {
         unsafe {
             rustrt::rand_free(self.rng);
@@ -683,21 +578,42 @@ impl Drop for RandRes {
     }
 }
 
-fn RandRes(rng: *rust_rng) -> RandRes {
-    RandRes {
-        rng: rng
+pub impl IsaacRng {
+    priv fn from_rust_rng(rng: *rust_rng) -> IsaacRng {
+        IsaacRng {
+            rng: rng
+        }
+    }
+
+    /// Create an ISAAC random number generator with a system specified seed
+    fn new() -> IsaacRng {
+        IsaacRng::new_seeded(seed())
+    }
+
+    /**
+     * Create a random number generator using the specified seed. A generator
+     * constructed with a given seed will generate the same sequence of values as
+     * all other generators constructed with the same seed. The seed may be any
+     * length.
+     */
+    fn new_seeded(seed: &[u8]) -> IsaacRng {
+        unsafe {
+            do vec::as_imm_buf(seed) |p, sz| {
+                IsaacRng::from_rust_rng(rustrt::rand_new_seeded(p, sz as size_t))
+            }
+        }
     }
 }
 
-impl Rng for @RandRes {
-    fn next(&self) -> u32 {
+impl Rng for IsaacRng {
+    pub fn next(&self) -> u32 {
         unsafe {
-            return rustrt::rand_next((*self).rng);
+            return rustrt::rand_next(self.rng);
         }
     }
 }
 
-/// Create a new random seed for seeded_rng
+/// Create a new random seed for IsaacRng::new_seeded
 pub fn seed() -> ~[u8] {
     unsafe {
         let n = rustrt::rand_seed_size() as uint;
@@ -709,38 +625,15 @@ pub fn seed() -> ~[u8] {
     }
 }
 
-/// Create a random number generator with a system specified seed
-pub fn Rng() -> @Rng {
-    seeded_rng(seed())
-}
-
-/**
- * Create a random number generator using the specified seed. A generator
- * constructed with a given seed will generate the same sequence of values as
- * all other generators constructed with the same seed. The seed may be any
- * length.
- */
-pub fn seeded_rng(seed: &[u8]) -> @Rng {
-    @seeded_randres(seed) as @Rng
-}
-
-fn seeded_randres(seed: &[u8]) -> @RandRes {
-    unsafe {
-        do vec::as_imm_buf(seed) |p, sz| {
-            @RandRes(rustrt::rand_new_seeded(p, sz as size_t))
-        }
-    }
-}
-
-struct XorShiftState {
-    mut x: u32,
-    mut y: u32,
-    mut z: u32,
-    mut w: u32,
+struct XorShiftRng {
+    priv mut x: u32,
+    priv mut y: u32,
+    priv mut z: u32,
+    priv mut w: u32,
 }
 
-impl Rng for XorShiftState {
-    fn next(&self) -> u32 {
+impl Rng for XorShiftRng {
+    pub fn next(&self) -> u32 {
         let x = self.x;
         let t = x ^ (x << 11);
         self.x = self.y;
@@ -752,41 +645,54 @@ impl Rng for XorShiftState {
     }
 }
 
-pub fn xorshift() -> @Rng {
-    // constants taken from http://en.wikipedia.org/wiki/Xorshift
-    seeded_xorshift(123456789u32, 362436069u32, 521288629u32, 88675123u32)
-}
+pub impl XorShiftRng {
+    /// Create an xor shift random number generator with a default seed.
+    fn new() -> XorShiftRng {
+        // constants taken from http://en.wikipedia.org/wiki/Xorshift
+        XorShiftRng::new_seeded(123456789u32, 362436069u32, 521288629u32, 88675123u32)
+    }
 
-pub fn seeded_xorshift(x: u32, y: u32, z: u32, w: u32) -> @Rng {
-    @XorShiftState { x: x, y: y, z: z, w: w } as @Rng
-}
+    /**
+     * Create a random number generator using the specified seed. A generator
+     * constructed with a given seed will generate the same sequence of values as
+     * all other generators constructed with the same seed.
+     */
+    fn new_seeded(x: u32, y: u32, z: u32, w: u32) -> XorShiftRng {
+        XorShiftRng { x: x, y: y, z: z, w: w }
+    }
 
+}
 
 // used to make space in TLS for a random number generator
-fn tls_rng_state(_v: @RandRes) {}
+fn tls_rng_state(_v: @IsaacRng) {}
 
 /**
  * Gives back a lazily initialized task-local random number generator,
  * seeded by the system. Intended to be used in method chaining style, ie
- * task_rng().gen_int().
+ * `task_rng().gen::<int>()`.
  */
-pub fn task_rng() -> @Rng {
-    let r : Option<@RandRes>;
+pub fn task_rng() -> @IsaacRng {
+    let r : Option<@IsaacRng>;
     unsafe {
         r = task::local_data::local_data_get(tls_rng_state);
     }
     match r {
         None => {
             unsafe {
-                let rng = seeded_randres(seed());
+                let rng = @IsaacRng::new_seeded(seed());
                 task::local_data::local_data_set(tls_rng_state, rng);
-                @rng as @Rng
+                rng
             }
         }
-        Some(rng) => @rng as @Rng
+        Some(rng) => rng
     }
 }
 
+// Allow direct chaining with `task_rng`
+impl<R: Rng> Rng for @R {
+    fn next(&self) -> u32 { (*self).next() }
+}
+
 /**
  * Returns a random value of a Rand type, using the task's random number
  * generator.
@@ -795,33 +701,32 @@ pub fn random<T: Rand>() -> T {
     task_rng().gen()
 }
 
-
 #[cfg(test)]
 mod tests {
     use option::{Option, Some};
-    use rand;
+    use super::*;
 
     #[test]
-    fn rng_seeded() {
-        let seed = rand::seed();
-        let ra = rand::seeded_rng(seed);
-        let rb = rand::seeded_rng(seed);
+    fn test_rng_seeded() {
+        let seed = seed();
+        let ra = IsaacRng::new_seeded(seed);
+        let rb = IsaacRng::new_seeded(seed);
         assert!(ra.gen_str(100u) == rb.gen_str(100u));
     }
 
     #[test]
-    fn rng_seeded_custom_seed() {
+    fn test_rng_seeded_custom_seed() {
         // much shorter than generated seeds which are 1024 bytes
         let seed = [2u8, 32u8, 4u8, 32u8, 51u8];
-        let ra = rand::seeded_rng(seed);
-        let rb = rand::seeded_rng(seed);
+        let ra = IsaacRng::new_seeded(seed);
+        let rb = IsaacRng::new_seeded(seed);
         assert!(ra.gen_str(100u) == rb.gen_str(100u));
     }
 
     #[test]
-    fn rng_seeded_custom_seed2() {
+    fn test_rng_seeded_custom_seed2() {
         let seed = [2u8, 32u8, 4u8, 32u8, 51u8];
-        let ra = rand::seeded_rng(seed);
+        let ra = IsaacRng::new_seeded(seed);
         // Regression test that isaac is actually using the above vector
         let r = ra.next();
         error!("%?", r);
@@ -830,8 +735,8 @@ mod tests {
     }
 
     #[test]
-    fn gen_int_range() {
-        let r = rand::Rng();
+    fn test_gen_int_range() {
+        let r = rng();
         let a = r.gen_int_range(-3, 42);
         assert!(a >= -3 && a < 42);
         assert!(r.gen_int_range(0, 1) == 0);
@@ -841,13 +746,13 @@ mod tests {
     #[test]
     #[should_fail]
     #[ignore(cfg(windows))]
-    fn gen_int_from_fail() {
-        rand::Rng().gen_int_range(5, -2);
+    fn test_gen_int_from_fail() {
+        rng().gen_int_range(5, -2);
     }
 
     #[test]
-    fn gen_uint_range() {
-        let r = rand::Rng();
+    fn test_gen_uint_range() {
+        let r = rng();
         let a = r.gen_uint_range(3u, 42u);
         assert!(a >= 3u && a < 42u);
         assert!(r.gen_uint_range(0u, 1u) == 0u);
@@ -857,28 +762,28 @@ mod tests {
     #[test]
     #[should_fail]
     #[ignore(cfg(windows))]
-    fn gen_uint_range_fail() {
-        rand::Rng().gen_uint_range(5u, 2u);
+    fn test_gen_uint_range_fail() {
+        rng().gen_uint_range(5u, 2u);
     }
 
     #[test]
-    fn gen_float() {
-        let r = rand::Rng();
-        let a = r.gen_float();
-        let b = r.gen_float();
+    fn test_gen_float() {
+        let r = rng();
+        let a = r.gen::<float>();
+        let b = r.gen::<float>();
         debug!((a, b));
     }
 
     #[test]
-    fn gen_weighted_bool() {
-        let r = rand::Rng();
+    fn test_gen_weighted_bool() {
+        let r = rng();
         assert!(r.gen_weighted_bool(0u) == true);
         assert!(r.gen_weighted_bool(1u) == true);
     }
 
     #[test]
-    fn gen_str() {
-        let r = rand::Rng();
+    fn test_gen_str() {
+        let r = rng();
         debug!(r.gen_str(10u));
         debug!(r.gen_str(10u));
         debug!(r.gen_str(10u));
@@ -888,91 +793,91 @@ mod tests {
     }
 
     #[test]
-    fn gen_bytes() {
-        let r = rand::Rng();
+    fn test_gen_bytes() {
+        let r = rng();
         assert!(r.gen_bytes(0u).len() == 0u);
         assert!(r.gen_bytes(10u).len() == 10u);
         assert!(r.gen_bytes(16u).len() == 16u);
     }
 
     #[test]
-    fn choose() {
-        let r = rand::Rng();
+    fn test_choose() {
+        let r = rng();
         assert!(r.choose([1, 1, 1]) == 1);
     }
 
     #[test]
-    fn choose_option() {
-        let r = rand::Rng();
+    fn test_choose_option() {
+        let r = rng();
         let x: Option<int> = r.choose_option([]);
         assert!(x.is_none());
         assert!(r.choose_option([1, 1, 1]) == Some(1));
     }
 
     #[test]
-    fn choose_weighted() {
-        let r = rand::Rng();
+    fn test_choose_weighted() {
+        let r = rng();
         assert!(r.choose_weighted(~[
-            rand::Weighted { weight: 1u, item: 42 },
+            Weighted { weight: 1u, item: 42 },
         ]) == 42);
         assert!(r.choose_weighted(~[
-            rand::Weighted { weight: 0u, item: 42 },
-            rand::Weighted { weight: 1u, item: 43 },
+            Weighted { weight: 0u, item: 42 },
+            Weighted { weight: 1u, item: 43 },
         ]) == 43);
     }
 
     #[test]
-    fn choose_weighted_option() {
-        let r = rand::Rng();
+    fn test_choose_weighted_option() {
+        let r = rng();
         assert!(r.choose_weighted_option(~[
-            rand::Weighted { weight: 1u, item: 42 },
+            Weighted { weight: 1u, item: 42 },
         ]) == Some(42));
         assert!(r.choose_weighted_option(~[
-            rand::Weighted { weight: 0u, item: 42 },
-            rand::Weighted { weight: 1u, item: 43 },
+            Weighted { weight: 0u, item: 42 },
+            Weighted { weight: 1u, item: 43 },
         ]) == Some(43));
         let v: Option<int> = r.choose_weighted_option([]);
         assert!(v.is_none());
     }
 
     #[test]
-    fn weighted_vec() {
-        let r = rand::Rng();
+    fn test_weighted_vec() {
+        let r = rng();
         let empty: ~[int] = ~[];
         assert!(r.weighted_vec(~[]) == empty);
         assert!(r.weighted_vec(~[
-            rand::Weighted { weight: 0u, item: 3u },
-            rand::Weighted { weight: 1u, item: 2u },
-            rand::Weighted { weight: 2u, item: 1u },
+            Weighted { weight: 0u, item: 3u },
+            Weighted { weight: 1u, item: 2u },
+            Weighted { weight: 2u, item: 1u },
         ]) == ~[2u, 1u, 1u]);
     }
 
     #[test]
-    fn shuffle() {
-        let r = rand::Rng();
+    fn test_shuffle() {
+        let r = rng();
         let empty: ~[int] = ~[];
         assert!(r.shuffle(~[]) == empty);
         assert!(r.shuffle(~[1, 1, 1]) == ~[1, 1, 1]);
     }
 
     #[test]
-    fn task_rng() {
-        let r = rand::task_rng();
-        r.gen_int();
+    fn test_task_rng() {
+        let r = task_rng();
+        r.gen::<int>();
         assert!(r.shuffle(~[1, 1, 1]) == ~[1, 1, 1]);
         assert!(r.gen_uint_range(0u, 1u) == 0u);
     }
 
     #[test]
-    fn random() {
+    fn test_random() {
         // not sure how to test this aside from just getting some values
-        let _n : uint = rand::random();
-        let _f : f32 = rand::random();
-        let _o : Option<Option<i8>> = rand::random();
+        let _n : uint = random();
+        let _f : f32 = random();
+        let _o : Option<Option<i8>> = random();
         let _many : ((),
                      (~uint, @int, ~Option<~(@char, ~(@bool,))>),
                      (u8, i8, u16, i16, u32, i32, u64, i64),
-                     (f32, (f64, (float,)))) = rand::random();
+                     (f32, (f64, (float,)))) = random();
     }
 }
 
diff --git a/src/libcore/run.rs b/src/libcore/run.rs
index 2455954ebe1..e7df95e20c8 100644
--- a/src/libcore/run.rs
+++ b/src/libcore/run.rs
@@ -47,28 +47,117 @@ pub struct RunProgramResult {
     handle: *(),
 }
 
+struct ProgRepr {
+    pid: pid_t,
+    handle: *(),
+    in_fd: c_int,
+    out_file: *libc::FILE,
+    err_file: *libc::FILE,
+    finished: bool,
+}
+
+impl ProgRepr {
+    fn close_input(&mut self) {
+        let invalid_fd = -1i32;
+        if self.in_fd != invalid_fd {
+            unsafe {
+                libc::close(self.in_fd);
+            }
+            self.in_fd = invalid_fd;
+        }
+    }
+
+    fn close_outputs(&mut self) {
+        unsafe {
+            fclose_and_null(&mut self.out_file);
+            fclose_and_null(&mut self.err_file);
+        }
+    }
+
+    fn finish(&mut self) -> int {
+        if self.finished { return 0; }
+        self.finished = true;
+        self.close_input();
+        return waitpid(self.pid);
+    }
+
+    fn destroy(&mut self, force: bool) {
+        killpid(self.pid, force);
+        self.finish();
+        self.close_outputs();
+
+        #[cfg(windows)]
+        fn killpid(pid: pid_t, _force: bool) {
+            unsafe {
+                libc::funcs::extra::kernel32::TerminateProcess(
+                    cast::transmute(pid), 1);
+            }
+        }
+
+        #[cfg(unix)]
+        fn killpid(pid: pid_t, force: bool) {
+            let signal = if force {
+                libc::consts::os::posix88::SIGKILL
+            } else {
+                libc::consts::os::posix88::SIGTERM
+            };
+
+            unsafe {
+                libc::funcs::posix88::signal::kill(pid, signal as c_int);
+            }
+        }
+    }
+}
+
 /// A value representing a child process
-pub trait Program {
+pub struct Program {
+    priv r: ProgRepr,
+}
+
+impl Drop for Program {
+    fn finalize(&self) {
+        // FIXME #4943: transmute is bad.
+        let selfr: &mut ProgRepr = unsafe { cast::transmute(&self.r) };
+
+        selfr.finish();
+        selfr.close_outputs();
+        free_handle(self.r.handle);
+    }
+}
+
+pub impl Program {
+    priv fn new(r: ProgRepr) -> Program {
+        Program {
+            r: r
+        }
+    }
+
     /// Returns the process id of the program
-    fn get_id(&mut self) -> pid_t;
+    fn get_id(&mut self) -> pid_t { self.r.pid }
 
     /// Returns an io::Writer that can be used to write to stdin
-    fn input(&mut self) -> @io::Writer;
+    fn input(&mut self) -> @io::Writer {
+        io::fd_writer(self.r.in_fd, false)
+    }
 
     /// Returns an io::Reader that can be used to read from stdout
-    fn output(&mut self) -> @io::Reader;
+    fn output(&mut self) -> @io::Reader {
+        io::FILE_reader(self.r.out_file, false)
+    }
 
     /// Returns an io::Reader that can be used to read from stderr
-    fn err(&mut self) -> @io::Reader;
+    fn err(&mut self) -> @io::Reader {
+        io::FILE_reader(self.r.err_file, false)
+    }
 
     /// Closes the handle to the child processes standard input
-    fn close_input(&mut self);
+    fn close_input(&mut self) { self.r.close_input(); }
 
     /**
      * Waits for the child process to terminate. Closes the handle
      * to stdin if necessary.
      */
-    fn finish(&mut self) -> int;
+    fn finish(&mut self) -> int { self.r.finish() }
 
     /**
      * Terminate the program, giving it a chance to clean itself up if
@@ -77,7 +166,7 @@ pub trait Program {
      * On Posix OSs SIGTERM will be sent to the process. On Win32
      * TerminateProcess(..) will be called.
      */
-    fn destroy(&mut self);
+    fn destroy(&mut self) { self.r.destroy(false); }
 
     /**
      * Terminate the program as soon as possible without giving it a
@@ -86,7 +175,7 @@ pub trait Program {
      * On Posix OSs SIGKILL will be sent to the process. On Win32
      * TerminateProcess(..) will be called.
      */
-    fn force_destroy(&mut self);
+    fn force_destroy(&mut self) { self.r.destroy(true); }
 }
 
 
@@ -248,9 +337,9 @@ pub fn run_program(prog: &str, args: &[~str]) -> int {
 /**
  * Spawns a process and returns a Program
  *
- * The returned value is a boxed class containing a <Program> object that can
- * be used for sending and receiving data over the standard file descriptors.
- * The class will ensure that file descriptors are closed properly.
+ * The returned value is a <Program> object that can be used for sending and
+ * receiving data over the standard file descriptors.  The class will ensure
+ * that file descriptors are closed properly.
  *
  * # Arguments
  *
@@ -259,9 +348,9 @@ pub fn run_program(prog: &str, args: &[~str]) -> int {
  *
  * # Return value
  *
- * A class with a <program> field
+ * A <Program> object
  */
-pub fn start_program(prog: &str, args: &[~str]) -> @Program {
+pub fn start_program(prog: &str, args: &[~str]) -> Program {
     let pipe_input = os::pipe();
     let pipe_output = os::pipe();
     let pipe_err = os::pipe();
@@ -277,105 +366,6 @@ pub fn start_program(prog: &str, args: &[~str]) -> @Program {
         libc::close(pipe_err.out);
     }
 
-    struct ProgRepr {
-        pid: pid_t,
-        handle: *(),
-        in_fd: c_int,
-        out_file: *libc::FILE,
-        err_file: *libc::FILE,
-        finished: bool,
-    }
-
-    fn close_repr_input(r: &mut ProgRepr) {
-        let invalid_fd = -1i32;
-        if r.in_fd != invalid_fd {
-            unsafe {
-                libc::close(r.in_fd);
-            }
-            r.in_fd = invalid_fd;
-        }
-    }
-
-    fn close_repr_outputs(r: &mut ProgRepr) {
-        unsafe {
-            fclose_and_null(&mut r.out_file);
-            fclose_and_null(&mut r.err_file);
-        }
-    }
-
-    fn finish_repr(r: &mut ProgRepr) -> int {
-        if r.finished { return 0; }
-        r.finished = true;
-        close_repr_input(&mut *r);
-        return waitpid(r.pid);
-    }
-
-    fn destroy_repr(r: &mut ProgRepr, force: bool) {
-        killpid(r.pid, force);
-        finish_repr(&mut *r);
-        close_repr_outputs(&mut *r);
-
-        #[cfg(windows)]
-        fn killpid(pid: pid_t, _force: bool) {
-            unsafe {
-                libc::funcs::extra::kernel32::TerminateProcess(
-                    cast::transmute(pid), 1);
-            }
-        }
-
-        #[cfg(unix)]
-        fn killpid(pid: pid_t, force: bool) {
-
-            let signal = if force {
-                libc::consts::os::posix88::SIGKILL
-            } else {
-                libc::consts::os::posix88::SIGTERM
-            };
-
-            unsafe {
-                libc::funcs::posix88::signal::kill(pid, signal as c_int);
-            }
-        }
-    }
-
-    struct ProgRes {
-        r: ProgRepr,
-    }
-
-    impl Drop for ProgRes {
-        fn finalize(&self) {
-            unsafe {
-                // FIXME #4943: transmute is bad.
-                finish_repr(cast::transmute(&self.r));
-                close_repr_outputs(cast::transmute(&self.r));
-            }
-            free_handle(self.r.handle);
-        }
-    }
-
-    fn ProgRes(r: ProgRepr) -> ProgRes {
-        ProgRes {
-            r: r
-        }
-    }
-
-    impl Program for ProgRes {
-        fn get_id(&mut self) -> pid_t { return self.r.pid; }
-        fn input(&mut self) -> @io::Writer {
-            io::fd_writer(self.r.in_fd, false)
-        }
-        fn output(&mut self) -> @io::Reader {
-            io::FILE_reader(self.r.out_file, false)
-        }
-        fn err(&mut self) -> @io::Reader {
-            io::FILE_reader(self.r.err_file, false)
-        }
-        fn close_input(&mut self) { close_repr_input(&mut self.r); }
-        fn finish(&mut self) -> int { finish_repr(&mut self.r) }
-        fn destroy(&mut self) { destroy_repr(&mut self.r, false); }
-        fn force_destroy(&mut self) { destroy_repr(&mut self.r, true); }
-    }
-
     let repr = ProgRepr {
         pid: res.pid,
         handle: res.handle,
@@ -385,7 +375,7 @@ pub fn start_program(prog: &str, args: &[~str]) -> @Program {
         finished: false,
     };
 
-    @ProgRes(repr) as @Program
+    Program::new(repr)
 }
 
 fn read_all(rd: @io::Reader) -> ~str {
diff --git a/src/libcore/unstable/at_exit.rs b/src/libcore/unstable/at_exit.rs
index 83f0c3695e8..bc4ec620aa8 100644
--- a/src/libcore/unstable/at_exit.rs
+++ b/src/libcore/unstable/at_exit.rs
@@ -62,7 +62,7 @@ fn exit_runner(exit_fns: *ExitFunctions) {
     // give us ownership of the array of functions
     let mut exit_fns_vec = unsafe { vec::from_buf(start, count as uint) };
     // Let's not make any promises about execution order
-    rand::Rng().shuffle_mut(exit_fns_vec);
+    rand::rng().shuffle_mut(exit_fns_vec);
 
     debug!("running %u exit functions", exit_fns_vec.len());
 
diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs
index 140d9ced580..cd9b44c278e 100644
--- a/src/librustpkg/path_util.rs
+++ b/src/librustpkg/path_util.rs
@@ -73,12 +73,12 @@ pub fn normalize(p: ~Path) -> ~Path {
 mod test {
     use core::{os, rand};
     use core::path::Path;
-    use core::rand::RngUtil;
     use path_util::*;
+    use core::rand::RngUtil;
 
     // Helper function to create a directory name that doesn't exist
     pub fn mk_nonexistent(tmpdir: &Path, suffix: &str) -> Path {
-        let r = rand::Rng();
+        let r = rand::rng();
         for 1000.times {
             let p = tmpdir.push(r.gen_str(16) + suffix);
             if !os::path_exists(&p) {
diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs
index d1f6bf982a7..8bfa2013950 100644
--- a/src/libstd/bitv.rs
+++ b/src/libstd/bitv.rs
@@ -876,6 +876,7 @@ mod tests {
     use core::uint;
     use core::vec;
     use core::rand;
+    use core::rand::Rng;
 
     static bench_bits : uint = 1 << 14;
 
@@ -1424,9 +1425,9 @@ mod tests {
         assert!(a.capacity() == uint::bits);
     }
 
-    fn rng() -> @rand::Rng {
+    fn rng() -> rand::IsaacRng {
         let seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
-        rand::seeded_rng(seed)
+        rand::IsaacRng::new_seeded(seed)
     }
 
     #[bench]
diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs
index febaea637ef..db6efdf3f52 100644
--- a/src/libstd/sort.rs
+++ b/src/libstd/sort.rs
@@ -902,12 +902,8 @@ mod tests {
 #[cfg(test)]
 mod test_tim_sort {
     use core::prelude::*;
-
     use sort::tim_sort;
-
     use core::rand::RngUtil;
-    use core::rand;
-    use core::vec;
 
     struct CVal {
         val: float,
@@ -915,8 +911,8 @@ mod test_tim_sort {
 
     impl Ord for CVal {
         fn lt(&self, other: &CVal) -> bool {
-            let rng = rand::Rng();
-            if rng.gen_float() > 0.995 { fail!(~"It's happening!!!"); }
+            let rng = rand::rng();
+            if rng.gen::<float>() > 0.995 { fail!(~"It's happening!!!"); }
             (*self).val < other.val
         }
         fn le(&self, other: &CVal) -> bool { (*self).val <= other.val }
@@ -964,10 +960,9 @@ mod test_tim_sort {
     #[should_fail]
     #[cfg(unix)]
     fn crash_test() {
-        let rng = rand::Rng();
+        let rng = rand::rng();
         let mut arr = do vec::from_fn(1000) |_i| {
-            let randVal = rng.gen_float();
-            CVal { val: randVal }
+            CVal { val: rng.gen() }
         };
 
         tim_sort(arr);
@@ -985,10 +980,9 @@ mod test_tim_sort {
 
     #[test]
     fn test_bad_Ord_impl() {
-        let rng = rand::Rng();
+        let rng = rand::rng();
         let mut arr = do vec::from_fn(500) |_i| {
-            let randVal = rng.gen_uint();
-            DVal { val: randVal }
+            DVal { val: rng.gen() }
         };
 
         tim_sort(arr);
@@ -998,14 +992,8 @@ mod test_tim_sort {
 #[cfg(test)]
 mod big_tests {
     use core::prelude::*;
-
     use sort::*;
-
     use core::rand::RngUtil;
-    use core::rand;
-    use core::task;
-    use core::uint;
-    use core::vec;
 
     #[test]
     fn test_unique() {
@@ -1045,14 +1033,13 @@ mod big_tests {
             }
         }
 
-        let rng = rand::Rng();
+        let rng = rand::rng();
 
         for uint::range(lo, hi) |i| {
             let n = 1 << i;
-            let arr = do vec::from_fn(n) |_i| {
-                rng.gen_float()
+            let mut arr: ~[float] = do vec::from_fn(n) |_i| {
+                rng.gen()
             };
-            let mut arr = arr;
 
             tim_sort(arr); // *sort
             isSorted(arr);
@@ -1076,7 +1063,7 @@ mod big_tests {
                 let size = arr.len();
                 let mut idx = 1;
                 while idx <= 10 {
-                    arr[size-idx] = rng.gen_float();
+                    arr[size-idx] = rng.gen();
                     idx += 1;
                 }
             }
@@ -1085,7 +1072,7 @@ mod big_tests {
 
             for (n/100).times {
                 let idx = rng.gen_uint_range(0, n);
-                arr[idx] = rng.gen_float();
+                arr[idx] = rng.gen();
             }
             tim_sort(arr);
             isSorted(arr);
@@ -1117,12 +1104,12 @@ mod big_tests {
             }
         }
 
-        let rng = rand::Rng();
+        let rng = rand::rng();
 
         for uint::range(lo, hi) |i| {
             let n = 1 << i;
-            let arr = do vec::from_fn(n) |_i| {
-                @rng.gen_float()
+            let arr: ~[@float] = do vec::from_fn(n) |_i| {
+                @rng.gen()
             };
             let mut arr = arr;
 
@@ -1148,7 +1135,7 @@ mod big_tests {
                 let size = arr.len();
                 let mut idx = 1;
                 while idx <= 10 {
-                    arr[size-idx] = @rng.gen_float();
+                    arr[size-idx] = @rng.gen();
                     idx += 1;
                 }
             }
@@ -1157,7 +1144,7 @@ mod big_tests {
 
             for (n/100).times {
                 let idx = rng.gen_uint_range(0, n);
-                arr[idx] = @rng.gen_float();
+                arr[idx] = @rng.gen();
             }
             tim_sort(arr);
             isSorted(arr);
diff --git a/src/libstd/tempfile.rs b/src/libstd/tempfile.rs
index 895ccbc820b..c9bcb3b8952 100644
--- a/src/libstd/tempfile.rs
+++ b/src/libstd/tempfile.rs
@@ -10,13 +10,11 @@
 
 //! Temporary files and directories
 
-use core::os;
 use core::prelude::*;
 use core::rand::RngUtil;
-use core::rand;
 
 pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option<Path> {
-    let r = rand::Rng();
+    let r = rand::rng();
     for 1000.times {
         let p = tmpdir.push(r.gen_str(16) + suffix);
         if os::make_dir(&p, 0x1c0) { // 700
diff --git a/src/libstd/test.rs b/src/libstd/test.rs
index addc1da6394..f82cc25e0f6 100644
--- a/src/libstd/test.rs
+++ b/src/libstd/test.rs
@@ -19,20 +19,9 @@ use getopts;
 use sort;
 use term;
 
-use core::cmp::Eq;
-
 use core::to_str::ToStr;
-use core::either::Either;
-use core::either;
-use core::io::WriterUtil;
-use core::io;
 use core::comm::{stream, SharedChan};
-use core::option;
 use core::prelude::*;
-use core::result;
-use core::str;
-use core::task;
-use core::vec;
 
 pub mod rustrt {
     use core::libc::size_t;
@@ -608,12 +597,8 @@ pub mod bench {
     use time::precise_time_ns;
     use test::{BenchHarness, BenchSamples};
     use stats::Stats;
-
-    use core::num;
+    use core::prelude::*;
     use core::rand::RngUtil;
-    use core::rand;
-    use core::u64;
-    use core::vec;
 
     pub impl BenchHarness {
 
@@ -705,7 +690,7 @@ pub mod bench {
         // not met, it may run as long as the Go algorithm.
         pub fn auto_bench(&mut self, f: &fn(&mut BenchHarness)) -> ~[f64] {
 
-            let rng = rand::Rng();
+            let rng = rand::rng();
             let mut magnitude = 10;
             let mut prev_madp = 0.0;
 
diff --git a/src/libstd/timer.rs b/src/libstd/timer.rs
index e862fe6077c..1e48ce5aa6f 100644
--- a/src/libstd/timer.rs
+++ b/src/libstd/timer.rs
@@ -175,11 +175,7 @@ mod test {
 
     use timer::*;
     use uv;
-
-    use core::iter;
     use core::rand::RngUtil;
-    use core::rand;
-    use core::task;
     use core::pipes::{stream, SharedChan};
 
     #[test]
@@ -220,7 +216,7 @@ mod test {
                 let hl_loop_clone = hl_loop.clone();
                 do task::spawn {
                     use core::rand::*;
-                    let rng = Rng();
+                    let rng = rng();
                     for iter::repeat(times) {
                         sleep(&hl_loop_clone, rng.next() as uint % maxms);
                     }
@@ -277,7 +273,7 @@ mod test {
         let hl_loop = uv::global_loop::get();
 
         for iter::repeat(times as uint) {
-            let expected = rand::Rng().gen_str(16u);
+            let expected = rand::rng().gen_str(16u);
             let (test_po, test_ch) = stream::<~str>();
             let hl_loop_clone = hl_loop.clone();
             do task::spawn() {
diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs
index ac887c7fdc4..020f4daefd9 100644
--- a/src/libstd/treemap.rs
+++ b/src/libstd/treemap.rs
@@ -698,7 +698,6 @@ mod test_treemap {
     use core::iterator::*;
     use super::*;
     use core::rand::RngUtil;
-    use core::rand;
 
     #[test]
     fn find_empty() {
@@ -835,12 +834,12 @@ mod test_treemap {
         check_equal(ctrl, &map);
         assert!(map.find(&5).is_none());
 
-        let rng = rand::seeded_rng(&[42]);
+        let rng = rand::IsaacRng::new_seeded(&[42]);
 
         for 3.times {
             for 90.times {
-                let k = rng.gen_int();
-                let v = rng.gen_int();
+                let k = rng.gen();
+                let v = rng.gen();
                 if !ctrl.contains(&(k, v)) {
                     assert!(map.insert(k, v));
                     ctrl.push((k, v));
diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs
index b75aa3c909b..e216215ace7 100644
--- a/src/test/bench/core-map.rs
+++ b/src/test/bench/core-map.rs
@@ -15,6 +15,7 @@ use std::time;
 use std::treemap::TreeMap;
 use core::hashmap::{HashMap, HashSet};
 use core::trie::TrieMap;
+use core::rand::Rng;
 
 fn timed(label: &str, f: &fn()) {
     let start = time::precise_time_s();
@@ -102,7 +103,7 @@ fn main() {
     let mut rand = vec::with_capacity(n_keys);
 
     {
-        let rng = core::rand::seeded_rng([1, 1, 1, 1, 1, 1, 1]);
+        let rng = core::rand::IsaacRng::new_seeded([1, 1, 1, 1, 1, 1, 1]);
         let mut set = HashSet::new();
         while set.len() != n_keys {
             let next = rng.next() as uint;
diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs
index 5f8f13896fb..b3e3d295c0f 100644
--- a/src/test/bench/core-set.rs
+++ b/src/test/bench/core-set.rs
@@ -12,7 +12,6 @@ extern mod std;
 use core::hashmap::HashSet;
 use std::bitv::BitvSet;
 use std::treemap::TreeSet;
-use core::io::WriterUtil;
 
 struct Results {
     sequential_ints: float,
@@ -32,7 +31,7 @@ fn timed(result: &mut float, op: &fn()) {
 }
 
 pub impl Results {
-    fn bench_int<T:Set<uint>>(&mut self, rng: @rand::Rng, num_keys: uint,
+    fn bench_int<T:Set<uint>, R: rand::Rng>(&mut self, rng: &R, num_keys: uint,
                                rand_cap: uint, f: &fn() -> T) {
         {
             let mut set = f();
@@ -70,8 +69,8 @@ pub impl Results {
         }
     }
 
-    fn bench_str<T:Set<~str>>(&mut self, rng: @rand::Rng, num_keys: uint,
-                               f: &fn() -> T) {
+    fn bench_str<T:Set<~str>, R: rand::Rng>(&mut self, rng: &R, num_keys: uint,
+                                            f: &fn() -> T) {
         {
             let mut set = f();
             do timed(&mut self.sequential_strings) {
@@ -156,25 +155,25 @@ fn main() {
     let max = 200000;
 
     {
-        let rng = rand::seeded_rng(seed);
+        let rng = rand::IsaacRng::new_seeded(seed);
         let mut results = empty_results();
-        results.bench_int(rng, num_keys, max, || HashSet::new::<uint>());
-        results.bench_str(rng, num_keys, || HashSet::new::<~str>());
+        results.bench_int(&rng, num_keys, max, || HashSet::new::<uint>());
+        results.bench_str(&rng, num_keys, || HashSet::new::<~str>());
         write_results("core::hashmap::HashSet", &results);
     }
 
     {
-        let rng = rand::seeded_rng(seed);
+        let rng = rand::IsaacRng::new_seeded(seed);
         let mut results = empty_results();
-        results.bench_int(rng, num_keys, max, || TreeSet::new::<uint>());
-        results.bench_str(rng, num_keys, || TreeSet::new::<~str>());
+        results.bench_int(&rng, num_keys, max, || TreeSet::new::<uint>());
+        results.bench_str(&rng, num_keys, || TreeSet::new::<~str>());
         write_results("std::treemap::TreeSet", &results);
     }
 
     {
-        let rng = rand::seeded_rng(seed);
+        let rng = rand::IsaacRng::new_seeded(seed);
         let mut results = empty_results();
-        results.bench_int(rng, num_keys, max, || BitvSet::new());
+        results.bench_int(&rng, num_keys, max, || BitvSet::new());
         write_results("std::bitv::BitvSet", &results);
     }
 }
diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs
index 0a68d29ac56..1af3538a021 100644
--- a/src/test/bench/core-std.rs
+++ b/src/test/bench/core-std.rs
@@ -13,8 +13,6 @@
 extern mod std;
 
 use std::time::precise_time_s;
-
-use core::io::{Reader, ReaderUtil};
 use core::rand::RngUtil;
 
 macro_rules! bench (
@@ -71,13 +69,13 @@ fn read_line() {
 }
 
 fn vec_plus() {
-    let r = rand::Rng();
+    let r = rand::rng();
 
     let mut v = ~[];
     let mut i = 0;
     while i < 1500 {
         let rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
-        if r.gen_bool() {
+        if r.gen() {
             v += rv;
         }
         else {
@@ -88,13 +86,13 @@ fn vec_plus() {
 }
 
 fn vec_append() {
-    let r = rand::Rng();
+    let r = rand::rng();
 
     let mut v = ~[];
     let mut i = 0;
     while i < 1500 {
         let rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
-        if r.gen_bool() {
+        if r.gen() {
             v = vec::append(v, rv);
         }
         else {
@@ -105,12 +103,12 @@ fn vec_append() {
 }
 
 fn vec_push_all() {
-    let r = rand::Rng();
+    let r = rand::rng();
 
     let mut v = ~[];
     for uint::range(0, 1500) |i| {
         let mut rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
-        if r.gen_bool() {
+        if r.gen() {
             v.push_all(rv);
         }
         else {
diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs
index 396ea081362..bd3de4a1b8a 100644
--- a/src/test/bench/graph500-bfs.rs
+++ b/src/test/bench/graph500-bfs.rs
@@ -25,7 +25,6 @@ use std::time;
 use std::deque::Deque;
 use std::par;
 use core::hashmap::{HashMap, HashSet};
-use core::io::WriterUtil;
 use core::int::abs;
 use core::rand::RngUtil;
 
@@ -34,9 +33,9 @@ type graph = ~[~[node_id]];
 type bfs_result = ~[node_id];
 
 fn make_edges(scale: uint, edgefactor: uint) -> ~[(node_id, node_id)] {
-    let r = rand::xorshift();
+    let r = rand::XorShiftRng::new();
 
-    fn choose_edge(i: node_id, j: node_id, scale: uint, r: @rand::Rng)
+    fn choose_edge<R: rand::Rng>(i: node_id, j: node_id, scale: uint, r: &R)
         -> (node_id, node_id) {
 
         let A = 0.57;
@@ -51,7 +50,7 @@ fn make_edges(scale: uint, edgefactor: uint) -> ~[(node_id, node_id)] {
             let j = j * 2i64;
             let scale = scale - 1u;
 
-            let x = r.gen_float();
+            let x = r.gen::<float>();
 
             if x < A {
                 choose_edge(i, j, scale, r)
@@ -75,7 +74,7 @@ fn make_edges(scale: uint, edgefactor: uint) -> ~[(node_id, node_id)] {
     }
 
     do vec::from_fn((1u << scale) * edgefactor) |_i| {
-        choose_edge(0i64, 0i64, scale, r)
+        choose_edge(0i64, 0i64, scale, &r)
     }
 }
 
@@ -105,7 +104,7 @@ fn make_graph(N: uint, edges: ~[(node_id, node_id)]) -> graph {
 
 fn gen_search_keys(graph: &[~[node_id]], n: uint) -> ~[node_id] {
     let mut keys = HashSet::new();
-    let r = rand::Rng();
+    let r = rand::rng();
 
     while keys.len() < n {
         let k = r.gen_uint_range(0u, graph.len());
diff --git a/src/test/bench/noise.rs b/src/test/bench/noise.rs
index 4397dcd5247..0da3a2e5d68 100644
--- a/src/test/bench/noise.rs
+++ b/src/test/bench/noise.rs
@@ -13,8 +13,8 @@ fn lerp(a: f32, b: f32, v: f32) -> f32 { a * (1.0 - v) + b * v }
 #[inline(always)]
 fn smooth(v: f32) -> f32 { v * v * (3.0 - 2.0 * v) }
 
-fn random_gradient(r: @Rng) -> Vec2 {
-    let v = r.gen_float() * float::consts::pi * 2.0;
+fn random_gradient<R:Rng>(r: &R) -> Vec2 {
+    let v = 2.0 * float::consts::pi * r.gen();
     Vec2 {
         x: float::cos(v) as f32,
         y: float::sin(v) as f32,
@@ -33,9 +33,9 @@ struct Noise2DContext {
 
 pub impl Noise2DContext {
     fn new() -> Noise2DContext {
-        let r = rand::Rng();
+        let r = rand::rng();
         let mut rgradients = [ Vec2 { x: 0.0, y: 0.0 }, ..256 ];
-        for int::range(0, 256) |i| { rgradients[i] = random_gradient(r); }
+        for int::range(0, 256) |i| { rgradients[i] = random_gradient(&r); }
         let mut permutations = [ 0, ..256 ];
         for int::range(0, 256) |i| { permutations[i] = i; }
         r.shuffle_mut(permutations);
diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs
index 8c371150e1e..0fcf8341ac8 100644
--- a/src/test/bench/shootout-fasta.rs
+++ b/src/test/bench/shootout-fasta.rs
@@ -16,7 +16,7 @@
  * http://shootout.alioth.debian.org/
  */
 extern mod std;
-use core::io::WriterUtil;
+use core::rand::Rng;
 
 fn LINE_LENGTH() -> uint { return 60u; }
 
@@ -63,7 +63,7 @@ fn make_random_fasta(wr: @io::Writer,
                      genelist: ~[AminoAcids],
                      n: int) {
     wr.write_line(~">" + id + ~" " + desc);
-    let rng = @mut MyRandom {last: rand::Rng().next()};
+    let rng = @mut MyRandom {last: rand::rng().next()};
     let mut op: ~str = ~"";
     for uint::range(0u, n as uint) |_i| {
         str::push_char(&mut op, select_random(myrandom_next(rng, 100u32),
diff --git a/src/test/run-pass/morestack6.rs b/src/test/run-pass/morestack6.rs
index 7e0b4b47846..1f908936aef 100644
--- a/src/test/run-pass/morestack6.rs
+++ b/src/test/run-pass/morestack6.rs
@@ -54,6 +54,7 @@ fn runtest2(f: extern fn(), frame_backoff: u32, last_stk: *u8) -> u32 {
 }
 
 pub fn main() {
+    use core::rand::Rng;
     let fns = ~[
         calllink01,
         calllink02,
@@ -61,7 +62,7 @@ pub fn main() {
         calllink09,
         calllink10
     ];
-    let rng = rand::Rng();
+    let rng = rand::rng();
     for fns.each |f| {
         let f = *f;
         let sz = rng.next() % 256u32 + 256u32;