about summary refs log tree commit diff
diff options
context:
space:
mode:
authorHuon Wilson <dbau.pp+github@gmail.com>2013-04-24 00:00:43 +1000
committerHuon Wilson <dbau.pp+github@gmail.com>2013-04-24 22:34:10 +1000
commit6c0a7c7b7d304157f31189bf34f50ef4027e1d66 (patch)
tree231628b0d02fbc5dc74cf71ca0a04ce422820243
parent706096b31960143fb1eb957a882f170ae4a8b4e9 (diff)
downloadrust-6c0a7c7b7d304157f31189bf34f50ef4027e1d66.tar.gz
rust-6c0a7c7b7d304157f31189bf34f50ef4027e1d66.zip
libcore: remove @Rng from rand, and use traits instead.
Also, rename RandRes -> IsaacRng, and make the constructors static
methods.
-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.rs324
-rw-r--r--src/libcore/unstable/at_exit.rs2
-rw-r--r--src/librustpkg/path_util.rs2
-rw-r--r--src/libstd/bitv.rs5
-rw-r--r--src/libstd/sort.rs10
-rw-r--r--src/libstd/tempfile.rs2
-rw-r--r--src/libstd/test.rs2
-rw-r--r--src/libstd/timer.rs4
-rw-r--r--src/libstd/treemap.rs2
-rw-r--r--src/test/bench/core-map.rs2
-rw-r--r--src/test/bench/core-set.rs14
-rw-r--r--src/test/bench/core-std.rs6
-rw-r--r--src/test/bench/graph500-bfs.rs8
-rw-r--r--src/test/bench/noise.rs6
-rw-r--r--src/test/bench/shootout-fasta.rs2
-rw-r--r--src/test/run-pass/morestack6.rs3
19 files changed, 205 insertions, 195 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..3233207b8bd 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_u64(), (*r).gen_u64(),
                                       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..86509c81eb3 100644
--- a/src/libcore/rand.rs
+++ b/src/libcore/rand.rs
@@ -22,95 +22,95 @@ use libc::size_t;
 
 /// 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 {
+    fn rand<R: Rng>(rng: &R) -> int {
         rng.gen_int()
     }
 }
 
 impl Rand for i8 {
-    fn rand(rng: @rand::Rng) -> i8 {
+    fn rand<R: Rng>(rng: &R) -> i8 {
         rng.gen_i8()
     }
 }
 
 impl Rand for i16 {
-    fn rand(rng: @rand::Rng) -> i16 {
+    fn rand<R: Rng>(rng: &R) -> i16 {
         rng.gen_i16()
     }
 }
 
 impl Rand for i32 {
-    fn rand(rng: @rand::Rng) -> i32 {
+    fn rand<R: Rng>(rng: &R) -> i32 {
         rng.gen_i32()
     }
 }
 
 impl Rand for i64 {
-    fn rand(rng: @rand::Rng) -> i64 {
+    fn rand<R: Rng>(rng: &R) -> i64 {
         rng.gen_i64()
     }
 }
 
 impl Rand for uint {
-    fn rand(rng: @rand::Rng) -> uint {
+    fn rand<R: Rng>(rng: &R) -> uint {
         rng.gen_uint()
     }
 }
 
 impl Rand for u8 {
-    fn rand(rng: @rand::Rng) -> u8 {
+    fn rand<R: Rng>(rng: &R) -> u8 {
         rng.gen_u8()
     }
 }
 
 impl Rand for u16 {
-    fn rand(rng: @rand::Rng) -> u16 {
+    fn rand<R: Rng>(rng: &R) -> u16 {
         rng.gen_u16()
     }
 }
 
 impl Rand for u32 {
-    fn rand(rng: @rand::Rng) -> u32 {
+    fn rand<R: Rng>(rng: &R) -> u32 {
         rng.gen_u32()
     }
 }
 
 impl Rand for u64 {
-    fn rand(rng: @rand::Rng) -> u64 {
+    fn rand<R: Rng>(rng: &R) -> u64 {
         rng.gen_u64()
     }
 }
 
 impl Rand for float {
-    fn rand(rng: @rand::Rng) -> float {
+    fn rand<R: Rng>(rng: &R) -> float {
         rng.gen_float()
     }
 }
 
 impl Rand for f32 {
-    fn rand(rng: @rand::Rng) -> f32 {
+    fn rand<R: Rng>(rng: &R) -> f32 {
         rng.gen_f32()
     }
 }
 
 impl Rand for f64 {
-    fn rand(rng: @rand::Rng) -> f64 {
+    fn rand<R: Rng>(rng: &R) -> f64 {
         rng.gen_f64()
     }
 }
 
 impl Rand for char {
-    fn rand(rng: @rand::Rng) -> char {
+    fn rand<R: Rng>(rng: &R) -> char {
         rng.gen_char()
     }
 }
 
 impl Rand for bool {
-    fn rand(rng: @rand::Rng) -> bool {
+    fn rand<R: Rng>(rng: &R) -> bool {
         rng.gen_bool()
     }
 }
@@ -123,10 +123,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 +137,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 +150,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> {
+    fn rand<R: Rng>(rng: &R) -> Option<T> {
         if rng.gen_bool() {
-            Some(Rand::rand(rng))
+            Some(rng.gen())
         } else {
             None
         }
@@ -160,11 +160,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 +173,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 +187,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
@@ -195,9 +195,10 @@ pub struct Weighted<T> {
     weight: uint,
     item: T,
 }
-
+// this should be in gen_f64, but it causes an ICE there.
+static scale : f64 = (u32::max_value as f64) + 1.0f64;
 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
@@ -209,7 +210,7 @@ pub trait RngUtil {
      * use core::rand::RngUtil;
      *
      * fn main() {
-     *     rng = rand::Rng();
+     *     rng = rand::rng();
      *     println(fmt!("%d",rng.gen_int()));
      * }
      * ~~~
@@ -249,7 +250,7 @@ pub trait RngUtil {
      * use core::rand::RngUtil;
      *
      * fn main() {
-     *     rng = rand::Rng();
+     *     rng = rand::rng();
      *     println(fmt!("%f",rng.gen_float()));
      * }
      * ~~~
@@ -275,7 +276,7 @@ pub trait RngUtil {
      * use core::rand::RngUtil;
      *
      * fn main() {
-     *     rng = rand::Rng();
+     *     rng = rand::rng();
      *     println(fmt!("%b",rng.gen_bool()));
      * }
      * ~~~
@@ -291,7 +292,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 +308,7 @@ pub trait RngUtil {
      * use core::rand::RngUtil;
      *
      * fn main() {
-     *     rng = rand::Rng();
+     *     rng = rand::rng();
      *     println(rng.gen_str(8));
      * }
      * ~~~
@@ -323,13 +324,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 +340,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 +359,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 +379,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 +399,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 +418,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 +434,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,10 +447,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)
+    fn gen<T: Rand>(&self) -> T {
+        Rand::rand(self)
     }
 
     /// Return a random int
@@ -536,7 +536,7 @@ impl RngUtil for @Rng {
         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;
     }
 
@@ -605,7 +605,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 +667,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 +686,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 +733,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,38 +753,46 @@ 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().
  */
-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
     }
 }
 
@@ -792,36 +801,35 @@ pub fn task_rng() -> @Rng {
  * generator.
  */
 pub fn random<T: Rand>() -> T {
-    task_rng().gen()
+    (*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 +838,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 +849,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 +865,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();
+    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 +896,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();
-        assert!(r.shuffle(~[1, 1, 1]) == ~[1, 1, 1]);
-        assert!(r.gen_uint_range(0u, 1u) == 0u);
+    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/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..b35b9face2a 100644
--- a/src/librustpkg/path_util.rs
+++ b/src/librustpkg/path_util.rs
@@ -78,7 +78,7 @@ mod test {
 
     // 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..5f4d507568a 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::RandRes {
         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..be32fb25657 100644
--- a/src/libstd/sort.rs
+++ b/src/libstd/sort.rs
@@ -915,7 +915,7 @@ mod test_tim_sort {
 
     impl Ord for CVal {
         fn lt(&self, other: &CVal) -> bool {
-            let rng = rand::Rng();
+            let rng = rand::rng();
             if rng.gen_float() > 0.995 { fail!(~"It's happening!!!"); }
             (*self).val < other.val
         }
@@ -964,7 +964,7 @@ 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 }
@@ -985,7 +985,7 @@ 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 }
@@ -1045,7 +1045,7 @@ mod big_tests {
             }
         }
 
-        let rng = rand::Rng();
+        let rng = rand::rng();
 
         for uint::range(lo, hi) |i| {
             let n = 1 << i;
@@ -1117,7 +1117,7 @@ mod big_tests {
             }
         }
 
-        let rng = rand::Rng();
+        let rng = rand::rng();
 
         for uint::range(lo, hi) |i| {
             let n = 1 << i;
diff --git a/src/libstd/tempfile.rs b/src/libstd/tempfile.rs
index 895ccbc820b..b92e652b7af 100644
--- a/src/libstd/tempfile.rs
+++ b/src/libstd/tempfile.rs
@@ -16,7 +16,7 @@ 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..113d66b3020 100644
--- a/src/libstd/test.rs
+++ b/src/libstd/test.rs
@@ -705,7 +705,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..f0daf407073 100644
--- a/src/libstd/timer.rs
+++ b/src/libstd/timer.rs
@@ -220,7 +220,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 +277,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..dbb01b6ce39 100644
--- a/src/libstd/treemap.rs
+++ b/src/libstd/treemap.rs
@@ -835,7 +835,7 @@ 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 {
diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs
index b75aa3c909b..0c53ccd46e8 100644
--- a/src/test/bench/core-map.rs
+++ b/src/test/bench/core-map.rs
@@ -102,7 +102,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..2ed3f668684 100644
--- a/src/test/bench/core-set.rs
+++ b/src/test/bench/core-set.rs
@@ -32,7 +32,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>>(&mut self, rng: &rand::Rng, num_keys: uint,
                                rand_cap: uint, f: &fn() -> T) {
         {
             let mut set = f();
@@ -70,7 +70,7 @@ pub impl Results {
         }
     }
 
-    fn bench_str<T:Set<~str>>(&mut self, rng: @rand::Rng, num_keys: uint,
+    fn bench_str<T:Set<~str>>(&mut self, rng: &rand::Rng, num_keys: uint,
                                f: &fn() -> T) {
         {
             let mut set = f();
@@ -156,15 +156,15 @@ 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>());
@@ -172,7 +172,7 @@ fn main() {
     }
 
     {
-        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());
         write_results("std::bitv::BitvSet", &results);
diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs
index 0a68d29ac56..8438759b5c8 100644
--- a/src/test/bench/core-std.rs
+++ b/src/test/bench/core-std.rs
@@ -71,7 +71,7 @@ fn read_line() {
 }
 
 fn vec_plus() {
-    let r = rand::Rng();
+    let r = rand::rng();
 
     let mut v = ~[];
     let mut i = 0;
@@ -88,7 +88,7 @@ fn vec_plus() {
 }
 
 fn vec_append() {
-    let r = rand::Rng();
+    let r = rand::rng();
 
     let mut v = ~[];
     let mut i = 0;
@@ -105,7 +105,7 @@ fn vec_append() {
 }
 
 fn vec_push_all() {
-    let r = rand::Rng();
+    let r = rand::rng();
 
     let mut v = ~[];
     for uint::range(0, 1500) |i| {
diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs
index 396ea081362..e84d8abf979 100644
--- a/src/test/bench/graph500-bfs.rs
+++ b/src/test/bench/graph500-bfs.rs
@@ -34,9 +34,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;
@@ -75,7 +75,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 +105,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..e032274482a 100644
--- a/src/test/bench/noise.rs
+++ b/src/test/bench/noise.rs
@@ -13,7 +13,7 @@ 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 {
+fn random_gradient(r: &Rng) -> Vec2 {
     let v = r.gen_float() * float::consts::pi * 2.0;
     Vec2 {
         x: float::cos(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..83e1a958d3c 100644
--- a/src/test/bench/shootout-fasta.rs
+++ b/src/test/bench/shootout-fasta.rs
@@ -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;