about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorZiad Hatahet <hatahet@gmail.com>2013-10-23 10:09:06 -0700
committerZiad Hatahet <hatahet@gmail.com>2013-10-23 10:09:06 -0700
commit7d69837bd263f334aa9dea4235698c006f7b1ce8 (patch)
treeb43315adfc734b0ab480b40674721c99902f3eb2 /src/libstd
parent60245b9290388671edac86d6db1619f60a9ccb68 (diff)
parenta4ec8af4c549bd806522826b756e18fbf0b5c47b (diff)
downloadrust-7d69837bd263f334aa9dea4235698c006f7b1ce8.tar.gz
rust-7d69837bd263f334aa9dea4235698c006f7b1ce8.zip
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/fmt/mod.rs1
-rw-r--r--src/libstd/io.rs12
-rw-r--r--src/libstd/iter.rs4
-rw-r--r--src/libstd/rand/distributions.rs522
-rw-r--r--src/libstd/rand/isaac.rs83
-rw-r--r--src/libstd/rand/mod.rs347
-rw-r--r--src/libstd/rand/os.rs16
-rw-r--r--src/libstd/rand/range.rs235
-rw-r--r--src/libstd/reflect.rs2
-rw-r--r--src/libstd/repr.rs8
-rw-r--r--src/libstd/rt/borrowck.rs4
-rw-r--r--src/libstd/rt/comm.rs10
-rw-r--r--src/libstd/rt/context.rs24
-rw-r--r--src/libstd/rt/crate_map.rs6
-rw-r--r--src/libstd/rt/io/file.rs4
-rw-r--r--src/libstd/rt/io/flate.rs4
-rw-r--r--src/libstd/rt/io/mock.rs6
-rw-r--r--src/libstd/rt/io/mod.rs4
-rw-r--r--src/libstd/rt/kill.rs8
-rw-r--r--src/libstd/rt/local_heap.rs4
-rw-r--r--src/libstd/rt/rc.rs2
-rw-r--r--src/libstd/rt/rtio.rs2
-rw-r--r--src/libstd/rt/sched.rs14
-rw-r--r--src/libstd/rt/stack.rs4
-rw-r--r--src/libstd/rt/task.rs4
-rw-r--r--src/libstd/rt/thread.rs6
-rw-r--r--src/libstd/rt/tube.rs2
-rw-r--r--src/libstd/rt/uv/addrinfo.rs2
-rw-r--r--src/libstd/rt/uv/file.rs2
-rw-r--r--src/libstd/rt/uv/mod.rs2
-rw-r--r--src/libstd/rt/uv/uvio.rs46
-rw-r--r--src/libstd/rt/uv/uvll.rs64
-rw-r--r--src/libstd/run.rs2
-rw-r--r--src/libstd/str.rs1
-rw-r--r--src/libstd/task/mod.rs18
-rw-r--r--src/libstd/task/spawn.rs6
-rw-r--r--src/libstd/unstable/intrinsics.rs8
-rw-r--r--src/libstd/unstable/raw.rs2
-rw-r--r--src/libstd/unstable/sync.rs4
39 files changed, 1043 insertions, 452 deletions
diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs
index e7fa81fc87a..9d5c9c1a5cd 100644
--- a/src/libstd/fmt/mod.rs
+++ b/src/libstd/fmt/mod.rs
@@ -490,7 +490,6 @@ pub struct Formatter<'self> {
 
     /// Output buffer.
     buf: &'self mut io::Writer,
-
     priv curarg: vec::VecIterator<'self, Argument<'self>>,
     priv args: &'self [Argument<'self>],
 }
diff --git a/src/libstd/io.rs b/src/libstd/io.rs
index 94a6b7cfea8..4e55c5fe60e 100644
--- a/src/libstd/io.rs
+++ b/src/libstd/io.rs
@@ -1009,7 +1009,7 @@ impl<R:Reader,C> Reader for Wrapper<R, C> {
 }
 
 pub struct FILERes {
-    f: *libc::FILE,
+    priv f: *libc::FILE,
 }
 
 impl FILERes {
@@ -1282,7 +1282,7 @@ impl Writer for fd_t {
 }
 
 pub struct FdRes {
-    fd: fd_t,
+    priv fd: fd_t,
 }
 
 impl FdRes {
@@ -1792,7 +1792,7 @@ pub mod fsync {
 
     // Artifacts that need to fsync on destruction
     pub struct Res<t> {
-        arg: Arg<t>,
+        priv arg: Arg<t>,
     }
 
     impl <t> Res<t> {
@@ -1815,9 +1815,9 @@ pub mod fsync {
     }
 
     pub struct Arg<t> {
-        val: t,
-        opt_level: Option<Level>,
-        fsync_fn: extern "Rust" fn(f: &t, Level) -> int,
+        priv val: t,
+        priv opt_level: Option<Level>,
+        priv fsync_fn: extern "Rust" fn(f: &t, Level) -> int,
     }
 
     // fsync file after executing blk
diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs
index 01af3d93157..771be3b2a13 100644
--- a/src/libstd/iter.rs
+++ b/src/libstd/iter.rs
@@ -1790,9 +1790,9 @@ impl<'self, A, St> Iterator<A> for Unfold<'self, A, St> {
 #[deriving(Clone)]
 pub struct Counter<A> {
     /// The current state the counter is at (next value to be yielded)
-    state: A,
+    priv state: A,
     /// The amount that this iterator is stepping by
-    step: A
+    priv step: A
 }
 
 /// Creates a new counter with the specified start/step
diff --git a/src/libstd/rand/distributions.rs b/src/libstd/rand/distributions.rs
index 0902100dca6..e7bcf8ce5d3 100644
--- a/src/libstd/rand/distributions.rs
+++ b/src/libstd/rand/distributions.rs
@@ -8,38 +8,226 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Sampling from random distributions
+/*!
+Sampling from random distributions.
 
-// Some implementations use the Ziggurat method
-// https://en.wikipedia.org/wiki/Ziggurat_algorithm
-//
-// The version used here is ZIGNOR [Doornik 2005, "An Improved
-// Ziggurat Method to Generate Normal Random Samples"] which is slower
-// (about double, it generates an extra random number) than the
-// canonical version [Marsaglia & Tsang 2000, "The Ziggurat Method for
-// Generating Random Variables"], but more robust. If one wanted, one
-// could implement VIZIGNOR the ZIGNOR paper for more speed.
+This is a generalization of `Rand` to allow parameters to control the
+exact properties of the generated values, e.g. the mean and standard
+deviation of a normal distribution. The `Sample` trait is the most
+general, and allows for generating values that change some state
+internally. The `IndependentSample` trait is for generating values
+that do not need to record state.
+
+*/
 
+use iter::range;
+use option::{Some, None};
 use num;
 use rand::{Rng,Rand};
+use clone::Clone;
+
+pub use self::range::Range;
+
+pub mod range;
+
+/// Types that can be used to create a random instance of `Support`.
+pub trait Sample<Support> {
+    /// Generate a random value of `Support`, using `rng` as the
+    /// source of randomness.
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> Support;
+}
+
+/// `Sample`s that do not require keeping track of state.
+///
+/// Since no state is recored, each sample is (statistically)
+/// independent of all others, assuming the `Rng` used has this
+/// property.
+// XXX maybe having this separate is overkill (the only reason is to
+// take &self rather than &mut self)? or maybe this should be the
+// trait called `Sample` and the other should be `DependentSample`.
+pub trait IndependentSample<Support>: Sample<Support> {
+    /// Generate a random value.
+    fn ind_sample<R: Rng>(&self, &mut R) -> Support;
+}
+
+/// A wrapper for generating types that implement `Rand` via the
+/// `Sample` & `IndependentSample` traits.
+pub struct RandSample<Sup>;
+
+impl<Sup: Rand> Sample<Sup> for RandSample<Sup> {
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) }
+}
+
+impl<Sup: Rand> IndependentSample<Sup> for RandSample<Sup> {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> Sup {
+        rng.gen()
+    }
+}
+
+/// A value with a particular weight for use with `WeightedChoice`.
+pub struct Weighted<T> {
+    /// The numerical weight of this item
+    weight: uint,
+    /// The actual item which is being weighted
+    item: T,
+}
+
+/// A distribution that selects from a finite collection of weighted items.
+///
+/// Each item has an associated weight that influences how likely it
+/// is to be chosen: higher weight is more likely.
+///
+/// The `Clone` restriction is a limitation of the `Sample` and
+/// `IndepedentSample` traits. Note that `&T` is (cheaply) `Clone` for
+/// all `T`, as is `uint`, so one can store references or indices into
+/// another vector.
+///
+/// # Example
+///
+/// ```rust
+/// use std::rand;
+/// use std::rand::distributions::{Weighted, WeightedChoice, IndepedentSample};
+///
+/// fn main() {
+///     let wc = WeightedChoice::new(~[Weighted { weight: 2, item: 'a' },
+///                                    Weighted { weight: 4, item: 'b' },
+///                                    Weighted { weight: 1, item: 'c' }]);
+///     let rng = rand::task_rng();
+///     for _ in range(0, 16) {
+///          // on average prints 'a' 4 times, 'b' 8 and 'c' twice.
+///          println!("{}", wc.ind_sample(rng));
+///     }
+/// }
+/// ```
+pub struct WeightedChoice<T> {
+    priv items: ~[Weighted<T>],
+    priv weight_range: Range<uint>
+}
+
+impl<T: Clone> WeightedChoice<T> {
+    /// Create a new `WeightedChoice`.
+    ///
+    /// Fails if:
+    /// - `v` is empty
+    /// - the total weight is 0
+    /// - the total weight is larger than a `uint` can contain.
+    pub fn new(mut items: ~[Weighted<T>]) -> WeightedChoice<T> {
+        // strictly speaking, this is subsumed by the total weight == 0 case
+        assert!(!items.is_empty(), "WeightedChoice::new called with no items");
+
+        let mut running_total = 0u;
+
+        // we convert the list from individual weights to cumulative
+        // weights so we can binary search. This *could* drop elements
+        // with weight == 0 as an optimisation.
+        for item in items.mut_iter() {
+            running_total = running_total.checked_add(&item.weight)
+                .expect("WeightedChoice::new called with a total weight larger \
+                        than a uint can contain");
+
+            item.weight = running_total;
+        }
+        assert!(running_total != 0, "WeightedChoice::new called with a total weight of 0");
+
+        WeightedChoice {
+            items: items,
+            // we're likely to be generating numbers in this range
+            // relatively often, so might as well cache it
+            weight_range: Range::new(0, running_total)
+        }
+    }
+}
+
+impl<T: Clone> Sample<T> for WeightedChoice<T> {
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> T { self.ind_sample(rng) }
+}
+
+impl<T: Clone> IndependentSample<T> for WeightedChoice<T> {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> T {
+        // we want to find the first element that has cumulative
+        // weight > sample_weight, which we do by binary since the
+        // cumulative weights of self.items are sorted.
+
+        // choose a weight in [0, total_weight)
+        let sample_weight = self.weight_range.ind_sample(rng);
+
+        // short circuit when it's the first item
+        if sample_weight < self.items[0].weight {
+            return self.items[0].item.clone();
+        }
+
+        let mut idx = 0;
+        let mut modifier = self.items.len();
+
+        // now we know that every possibility has an element to the
+        // left, so we can just search for the last element that has
+        // cumulative weight <= sample_weight, then the next one will
+        // be "it". (Note that this greatest element will never be the
+        // last element of the vector, since sample_weight is chosen
+        // in [0, total_weight) and the cumulative weight of the last
+        // one is exactly the total weight.)
+        while modifier > 1 {
+            let i = idx + modifier / 2;
+            if self.items[i].weight <= sample_weight {
+                // we're small, so look to the right, but allow this
+                // exact element still.
+                idx = i;
+                // we need the `/ 2` to round up otherwise we'll drop
+                // the trailing elements when `modifier` is odd.
+                modifier += 1;
+            } else {
+                // otherwise we're too big, so go left. (i.e. do
+                // nothing)
+            }
+            modifier /= 2;
+        }
+        return self.items[idx + 1].item.clone();
+    }
+}
 
 mod ziggurat_tables;
 
-// inlining should mean there is no performance penalty for this
-#[inline]
+/// Sample a random number using the Ziggurat method (specifically the
+/// ZIGNOR variant from Doornik 2005). Most of the arguments are
+/// directly from the paper:
+///
+/// * `rng`: source of randomness
+/// * `symmetric`: whether this is a symmetric distribution, or one-sided with P(x < 0) = 0.
+/// * `X`: the $x_i$ abscissae.
+/// * `F`: precomputed values of the PDF at the $x_i$, (i.e. $f(x_i)$)
+/// * `F_DIFF`: precomputed values of $f(x_i) - f(x_{i+1})$
+/// * `pdf`: the probability density function
+/// * `zero_case`: manual sampling from the tail when we chose the
+///    bottom box (i.e. i == 0)
+
+// the perf improvement (25-50%) is definitely worth the extra code
+// size from force-inlining.
+#[inline(always)]
 fn ziggurat<R:Rng>(rng: &mut R,
-                   center_u: bool,
+                   symmetric: bool,
                    X: ziggurat_tables::ZigTable,
                    F: ziggurat_tables::ZigTable,
                    F_DIFF: ziggurat_tables::ZigTable,
-                   pdf: &'static fn(f64) -> f64, // probability density function
+                   pdf: &'static fn(f64) -> f64,
                    zero_case: &'static fn(&mut R, f64) -> f64) -> f64 {
+    static SCALE: f64 = (1u64 << 53) as f64;
     loop {
-        let u = if center_u {2.0 * rng.gen() - 1.0} else {rng.gen()};
-        let i: uint = rng.gen::<uint>() & 0xff;
+        // reimplement the f64 generation as an optimisation suggested
+        // by the Doornik paper: we have a lot of precision-space
+        // (i.e. there are 11 bits of the 64 of a u64 to use after
+        // creating a f64), so we might as well reuse some to save
+        // generating a whole extra random number. (Seems to be 15%
+        // faster.)
+        let bits: u64 = rng.gen();
+        let i = (bits & 0xff) as uint;
+        let f = (bits >> 11) as f64 / SCALE;
+
+        // u is either U(-1, 1) or U(0, 1) depending on if this is a
+        // symmetric distribution or not.
+        let u = if symmetric {2.0 * f - 1.0} else {f};
         let x = u * X[i];
 
-        let test_x = if center_u {num::abs(x)} else {x};
+        let test_x = if symmetric {num::abs(x)} else {x};
 
         // algebraically equivalent to |u| < X[i+1]/X[i] (or u < X[i+1]/X[i])
         if test_x < X[i + 1] {
@@ -49,30 +237,25 @@ fn ziggurat<R:Rng>(rng: &mut R,
             return zero_case(rng, u);
         }
         // algebraically equivalent to f1 + DRanU()*(f0 - f1) < 1
-        if F[i+1] + F_DIFF[i+1] * rng.gen() < pdf(x) {
+        if F[i + 1] + F_DIFF[i + 1] * rng.gen() < pdf(x) {
             return x;
         }
     }
 }
 
-/// A wrapper around an `f64` to generate N(0, 1) random numbers (a.k.a.  a
-/// standard normal, or Gaussian). Multiplying the generated values by the
-/// desired standard deviation `sigma` then adding the desired mean `mu` will
-/// give N(mu, sigma^2) distributed random numbers.
+/// A wrapper around an `f64` to generate N(0, 1) random numbers
+/// (a.k.a.  a standard normal, or Gaussian).
 ///
-/// Note that this has to be unwrapped before use as an `f64` (using either
-/// `*` or `cast::transmute` is safe).
+/// See `Normal` for the general normal distribution. That this has to
+/// be unwrapped before use as an `f64` (using either `*` or
+/// `cast::transmute` is safe).
 ///
-/// # Example
+/// Implemented via the ZIGNOR variant[1] of the Ziggurat method.
 ///
-/// ```
-/// use std::rand::distributions::StandardNormal;
-///
-/// fn main() {
-///     let normal = 2.0 + (*rand::random::<StandardNormal>()) * 3.0;
-///     println!("{} is from a N(2, 9) distribution", normal)
-/// }
-/// ```
+/// [1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to
+/// Generate Normal Random
+/// Samples*](http://www.doornik.com/research/ziggurat.pdf). Nuffield
+/// College, Oxford
 pub struct StandardNormal(f64);
 
 impl Rand for StandardNormal {
@@ -110,23 +293,62 @@ impl Rand for StandardNormal {
     }
 }
 
-/// A wrapper around an `f64` to generate Exp(1) random numbers. Dividing by
-/// the desired rate `lambda` will give Exp(lambda) distributed random
-/// numbers.
+/// The normal distribution `N(mean, std_dev**2)`.
 ///
-/// Note that this has to be unwrapped before use as an `f64` (using either
-/// `*` or `cast::transmute` is safe).
+/// This uses the ZIGNOR variant of the Ziggurat method, see
+/// `StandardNormal` for more details.
 ///
 /// # Example
 ///
 /// ```
-/// use std::rand::distributions::Exp1;
+/// use std::rand;
+/// use std::rand::distributions::{Normal, IndependentSample};
 ///
 /// fn main() {
-///     let exp2 = (*rand::random::<Exp1>()) * 0.5;
-///     println!("{} is from a Exp(2) distribution", exp2);
+///     let normal = Normal::new(2.0, 3.0);
+///     let v = normal.ind_sample(rand::task_rng());
+///     println!("{} is from a N(2, 9) distribution", v)
 /// }
 /// ```
+pub struct Normal {
+    priv mean: f64,
+    priv std_dev: f64
+}
+
+impl Normal {
+    /// Construct a new `Normal` distribution with the given mean and
+    /// standard deviation. Fails if `std_dev < 0`.
+    pub fn new(mean: f64, std_dev: f64) -> Normal {
+        assert!(std_dev >= 0.0, "Normal::new called with `std_dev` < 0");
+        Normal {
+            mean: mean,
+            std_dev: std_dev
+        }
+    }
+}
+impl Sample<f64> for Normal {
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
+}
+impl IndependentSample<f64> for Normal {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
+        self.mean + self.std_dev * (*rng.gen::<StandardNormal>())
+    }
+}
+
+/// A wrapper around an `f64` to generate Exp(1) random numbers.
+///
+/// See `Exp` for the general exponential distribution.Note that this
+ // has to be unwrapped before use as an `f64` (using either
+/// `*` or `cast::transmute` is safe).
+///
+/// Implemented via the ZIGNOR variant[1] of the Ziggurat method. The
+/// exact description in the paper was adjusted to use tables for the
+/// exponential distribution rather than normal.
+///
+/// [1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to
+/// Generate Normal Random
+/// Samples*](http://www.doornik.com/research/ziggurat.pdf). Nuffield
+/// College, Oxford
 pub struct Exp1(f64);
 
 // This could be done via `-rng.gen::<f64>().ln()` but that is slower.
@@ -148,3 +370,221 @@ impl Rand for Exp1 {
                       pdf, zero_case))
     }
 }
+
+/// The exponential distribution `Exp(lambda)`.
+///
+/// This distribution has density function: `f(x) = lambda *
+/// exp(-lambda * x)` for `x > 0`.
+///
+/// # Example
+///
+/// ```
+/// use std::rand;
+/// use std::rand::distributions::{Exp, IndependentSample};
+///
+/// fn main() {
+///     let exp = Exp::new(2.0);
+///     let v = exp.ind_sample(rand::task_rng());
+///     println!("{} is from a Exp(2) distribution", v);
+/// }
+/// ```
+pub struct Exp {
+    /// `lambda` stored as `1/lambda`, since this is what we scale by.
+    priv lambda_inverse: f64
+}
+
+impl Exp {
+    /// Construct a new `Exp` with the given shape parameter
+    /// `lambda`. Fails if `lambda <= 0`.
+    pub fn new(lambda: f64) -> Exp {
+        assert!(lambda > 0.0, "Exp::new called with `lambda` <= 0");
+        Exp { lambda_inverse: 1.0 / lambda }
+    }
+}
+
+impl Sample<f64> for Exp {
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
+}
+impl IndependentSample<f64> for Exp {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
+        (*rng.gen::<Exp1>()) * self.lambda_inverse
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use rand::*;
+    use super::*;
+    use iter::range;
+    use option::{Some, None};
+
+    struct ConstRand(uint);
+    impl Rand for ConstRand {
+        fn rand<R: Rng>(_: &mut R) -> ConstRand {
+            ConstRand(0)
+        }
+    }
+
+    // 0, 1, 2, 3, ...
+    struct CountingRng { i: u32 }
+    impl Rng for CountingRng {
+        fn next_u32(&mut self) -> u32 {
+            self.i += 1;
+            self.i - 1
+        }
+        fn next_u64(&mut self) -> u64 {
+            self.next_u32() as u64
+        }
+    }
+
+    #[test]
+    fn test_rand_sample() {
+        let mut rand_sample = RandSample::<ConstRand>;
+
+        assert_eq!(*rand_sample.sample(task_rng()), 0);
+        assert_eq!(*rand_sample.ind_sample(task_rng()), 0);
+    }
+
+    #[test]
+    fn test_normal() {
+        let mut norm = Normal::new(10.0, 10.0);
+        let rng = task_rng();
+        for _ in range(0, 1000) {
+            norm.sample(rng);
+            norm.ind_sample(rng);
+        }
+    }
+    #[test]
+    #[should_fail]
+    fn test_normal_invalid_sd() {
+        Normal::new(10.0, -1.0);
+    }
+
+    #[test]
+    fn test_exp() {
+        let mut exp = Exp::new(10.0);
+        let rng = task_rng();
+        for _ in range(0, 1000) {
+            assert!(exp.sample(rng) >= 0.0);
+            assert!(exp.ind_sample(rng) >= 0.0);
+        }
+    }
+    #[test]
+    #[should_fail]
+    fn test_exp_invalid_lambda_zero() {
+        Exp::new(0.0);
+    }
+    #[test]
+    #[should_fail]
+    fn test_exp_invalid_lambda_neg() {
+        Exp::new(-10.0);
+    }
+
+    #[test]
+    fn test_weighted_choice() {
+        // this makes assumptions about the internal implementation of
+        // WeightedChoice, specifically: it doesn't reorder the items,
+        // it doesn't do weird things to the RNG (so 0 maps to 0, 1 to
+        // 1, internally; modulo a modulo operation).
+
+        macro_rules! t (
+            ($items:expr, $expected:expr) => {{
+                let wc = WeightedChoice::new($items);
+                let expected = $expected;
+
+                let mut rng = CountingRng { i: 0 };
+
+                for &val in expected.iter() {
+                    assert_eq!(wc.ind_sample(&mut rng), val)
+                }
+            }}
+        );
+
+        t!(~[Weighted { weight: 1, item: 10}], ~[10]);
+
+        // skip some
+        t!(~[Weighted { weight: 0, item: 20},
+             Weighted { weight: 2, item: 21},
+             Weighted { weight: 0, item: 22},
+             Weighted { weight: 1, item: 23}],
+           ~[21,21, 23]);
+
+        // different weights
+        t!(~[Weighted { weight: 4, item: 30},
+             Weighted { weight: 3, item: 31}],
+           ~[30,30,30,30, 31,31,31]);
+
+        // check that we're binary searching
+        // correctly with some vectors of odd
+        // length.
+        t!(~[Weighted { weight: 1, item: 40},
+             Weighted { weight: 1, item: 41},
+             Weighted { weight: 1, item: 42},
+             Weighted { weight: 1, item: 43},
+             Weighted { weight: 1, item: 44}],
+           ~[40, 41, 42, 43, 44]);
+        t!(~[Weighted { weight: 1, item: 50},
+             Weighted { weight: 1, item: 51},
+             Weighted { weight: 1, item: 52},
+             Weighted { weight: 1, item: 53},
+             Weighted { weight: 1, item: 54},
+             Weighted { weight: 1, item: 55},
+             Weighted { weight: 1, item: 56}],
+           ~[50, 51, 52, 53, 54, 55, 56]);
+    }
+
+    #[test] #[should_fail]
+    fn test_weighted_choice_no_items() {
+        WeightedChoice::<int>::new(~[]);
+    }
+    #[test] #[should_fail]
+    fn test_weighted_choice_zero_weight() {
+        WeightedChoice::new(~[Weighted { weight: 0, item: 0},
+                              Weighted { weight: 0, item: 1}]);
+    }
+    #[test] #[should_fail]
+    fn test_weighted_choice_weight_overflows() {
+        let x = (-1) as uint / 2; // x + x + 2 is the overflow
+        WeightedChoice::new(~[Weighted { weight: x, item: 0 },
+                              Weighted { weight: 1, item: 1 },
+                              Weighted { weight: x, item: 2 },
+                              Weighted { weight: 1, item: 3 }]);
+    }
+}
+
+#[cfg(test)]
+mod bench {
+    use extra::test::BenchHarness;
+    use rand::*;
+    use super::*;
+    use iter::range;
+    use option::{Some, None};
+    use mem::size_of;
+
+    static N: u64 = 100;
+
+    #[bench]
+    fn rand_normal(bh: &mut BenchHarness) {
+        let mut rng = XorShiftRng::new();
+        let mut normal = Normal::new(-2.71828, 3.14159);
+
+        do bh.iter {
+            for _ in range(0, N) {
+                normal.sample(&mut rng);
+            }
+        }
+        bh.bytes = size_of::<f64>() as u64 * N;
+    }
+    #[bench]
+    fn rand_exp(bh: &mut BenchHarness) {
+        let mut rng = XorShiftRng::new();
+        let mut exp = Exp::new(2.71828 * 3.14159);
+
+        do bh.iter {
+            for _ in range(0, N) {
+                exp.sample(&mut rng);
+            }
+        }
+        bh.bytes = size_of::<f64>() as u64 * N;
+    }
+}
diff --git a/src/libstd/rand/isaac.rs b/src/libstd/rand/isaac.rs
index 0068b60cfa5..42254b211a1 100644
--- a/src/libstd/rand/isaac.rs
+++ b/src/libstd/rand/isaac.rs
@@ -10,18 +10,24 @@
 
 //! The ISAAC random number generator.
 
-use cast;
 use rand::{Rng, SeedableRng, OSRng};
 use iter::{Iterator, range, range_step, Repeat};
 use option::{None, Some};
+use vec::raw;
+use mem;
 
 static RAND_SIZE_LEN: u32 = 8;
 static RAND_SIZE: u32 = 1 << RAND_SIZE_LEN;
 
-/// A random number generator that uses the [ISAAC
-/// algorithm](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29).
+/// A random number generator that uses the ISAAC algorithm[1].
 ///
-/// The ISAAC algorithm is suitable for cryptographic purposes.
+/// The ISAAC algorithm is generally accepted as suitable for
+/// cryptographic purposes, but this implementation has not be
+/// verified as such. Prefer a generator like `OSRng` that defers to
+/// the operating system for cases that need high security.
+///
+/// [1]: Bob Jenkins, [*ISAAC: A fast cryptographic random number
+/// generator*](http://www.burtleburtle.net/bob/rand/isaacafa.html)
 pub struct IsaacRng {
     priv cnt: u32,
     priv rsl: [u32, .. RAND_SIZE],
@@ -42,9 +48,12 @@ impl IsaacRng {
     pub fn new() -> IsaacRng {
         let mut rng = EMPTY;
 
-        {
-            let bytes = unsafe {cast::transmute::<&mut [u32], &mut [u8]>(rng.rsl)};
-            OSRng::new().fill_bytes(bytes);
+        unsafe {
+            let ptr = raw::to_mut_ptr(rng.rsl);
+
+            do raw::mut_buf_as_slice(ptr as *mut u8, mem::size_of_val(&rng.rsl)) |slice| {
+                OSRng::new().fill_bytes(slice);
+            }
         }
 
         rng.init(true);
@@ -212,11 +221,16 @@ impl<'self> SeedableRng<&'self [u32]> for IsaacRng {
 static RAND_SIZE_64_LEN: uint = 8;
 static RAND_SIZE_64: uint = 1 << RAND_SIZE_64_LEN;
 
-/// A random number generator that uses the 64-bit variant of the
-/// [ISAAC
-/// algorithm](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29).
+/// A random number generator that uses ISAAC-64[1], the 64-bit
+/// variant of the ISAAC algorithm.
+///
+/// The ISAAC algorithm is generally accepted as suitable for
+/// cryptographic purposes, but this implementation has not be
+/// verified as such. Prefer a generator like `OSRng` that defers to
+/// the operating system for cases that need high security.
 ///
-/// The ISAAC algorithm is suitable for cryptographic purposes.
+/// [1]: Bob Jenkins, [*ISAAC: A fast cryptographic random number
+/// generator*](http://www.burtleburtle.net/bob/rand/isaacafa.html)
 pub struct Isaac64Rng {
     priv cnt: uint,
     priv rsl: [u64, .. RAND_SIZE_64],
@@ -238,10 +252,15 @@ impl Isaac64Rng {
     /// seed.
     pub fn new() -> Isaac64Rng {
         let mut rng = EMPTY_64;
-        {
-            let bytes = unsafe {cast::transmute::<&mut [u64], &mut [u8]>(rng.rsl)};
-            OSRng::new().fill_bytes(bytes);
+
+        unsafe {
+            let ptr = raw::to_mut_ptr(rng.rsl);
+
+            do raw::mut_buf_as_slice(ptr as *mut u8, mem::size_of_val(&rng.rsl)) |slice| {
+                OSRng::new().fill_bytes(slice);
+            }
         }
+
         rng.init(true);
         rng
     }
@@ -434,14 +453,14 @@ mod test {
 
     #[test]
     fn test_rng_32_seeded() {
-        let seed = &[2, 32, 4, 32, 51];
+        let seed = &[1, 23, 456, 7890, 12345];
         let mut ra: IsaacRng = SeedableRng::from_seed(seed);
         let mut rb: IsaacRng = SeedableRng::from_seed(seed);
         assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
     }
     #[test]
     fn test_rng_64_seeded() {
-        let seed = &[2, 32, 4, 32, 51];
+        let seed = &[1, 23, 456, 7890, 12345];
         let mut ra: Isaac64Rng = SeedableRng::from_seed(seed);
         let mut rb: Isaac64Rng = SeedableRng::from_seed(seed);
         assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
@@ -472,46 +491,46 @@ mod test {
 
     #[test]
     fn test_rng_32_true_values() {
-        let seed = &[2, 32, 4, 32, 51];
+        let seed = &[1, 23, 456, 7890, 12345];
         let mut ra: IsaacRng = SeedableRng::from_seed(seed);
         // Regression test that isaac is actually using the above vector
         let v = vec::from_fn(10, |_| ra.next_u32());
         assert_eq!(v,
-                   ~[447462228, 2081944040, 3163797308, 2379916134, 2377489184,
-                     1132373754, 536342443, 2995223415, 1265094839, 345325140]);
+                   ~[2558573138, 873787463, 263499565, 2103644246, 3595684709,
+                     4203127393, 264982119, 2765226902, 2737944514, 3900253796]);
 
-        let seed = &[500, -4000, 123456, 9876543, 1, 1, 1, 1, 1];
+        let seed = &[12345, 67890, 54321, 9876];
         let mut rb: IsaacRng = SeedableRng::from_seed(seed);
         // skip forward to the 10000th number
         for _ in range(0, 10000) { rb.next_u32(); }
 
         let v = vec::from_fn(10, |_| rb.next_u32());
         assert_eq!(v,
-                   ~[612373032, 292987903, 1819311337, 3141271980, 422447569,
-                     310096395, 1083172510, 867909094, 2478664230, 2073577855]);
+                   ~[3676831399, 3183332890, 2834741178, 3854698763, 2717568474,
+                     1576568959, 3507990155, 179069555, 141456972, 2478885421]);
     }
     #[test]
     fn test_rng_64_true_values() {
-        let seed = &[2, 32, 4, 32, 51];
+        let seed = &[1, 23, 456, 7890, 12345];
         let mut ra: Isaac64Rng = SeedableRng::from_seed(seed);
         // Regression test that isaac is actually using the above vector
         let v = vec::from_fn(10, |_| ra.next_u64());
         assert_eq!(v,
-                   ~[15015576812873463115, 12461067598045625862, 14818626436142668771,
-                     5562406406765984441, 11813289907965514161, 13443797187798420053,
-                     6935026941854944442, 7750800609318664042, 14428747036317928637,
-                     14028894460301215947]);
+                   ~[547121783600835980, 14377643087320773276, 17351601304698403469,
+                     1238879483818134882, 11952566807690396487, 13970131091560099343,
+                     4469761996653280935, 15552757044682284409, 6860251611068737823,
+                     13722198873481261842]);
 
-        let seed = &[500, -4000, 123456, 9876543, 1, 1, 1, 1, 1];
+        let seed = &[12345, 67890, 54321, 9876];
         let mut rb: Isaac64Rng = SeedableRng::from_seed(seed);
         // skip forward to the 10000th number
         for _ in range(0, 10000) { rb.next_u64(); }
 
         let v = vec::from_fn(10, |_| rb.next_u64());
         assert_eq!(v,
-                   ~[13557216323596688637, 17060829581390442094, 4927582063811333743,
-                     2699639759356482270, 4819341314392384881, 6047100822963614452,
-                     11086255989965979163, 11901890363215659856, 5370800226050011580,
-                     16496463556025356451]);
+                   ~[18143823860592706164, 8491801882678285927, 2699425367717515619,
+                     17196852593171130876, 2606123525235546165, 15790932315217671084,
+                     596345674630742204, 9947027391921273664, 11788097613744130851,
+                     10391409374914919106]);
     }
 }
diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs
index f5c60417bac..a6efdfc66db 100644
--- a/src/libstd/rand/mod.rs
+++ b/src/libstd/rand/mod.rs
@@ -28,6 +28,23 @@ from an operating-system source of randomness, e.g. `/dev/urandom` on
 Unix systems, and will automatically reseed itself from this source
 after generating 32 KiB of random data.
 
+# Cryptographic security
+
+An application that requires random numbers for cryptographic purposes
+should prefer `OSRng`, which reads randomness from one of the source
+that the operating system provides (e.g. `/dev/urandom` on
+Unixes). The other random number generators provided by this module
+are either known to be insecure (`XorShiftRng`), or are not verified
+to be secure (`IsaacRng`, `Isaac64Rng` and `StdRng`).
+
+*Note*: on Linux, `/dev/random` is more secure than `/dev/urandom`,
+but it is a blocking RNG, and will wait until it has determined that
+it has collected enough entropy to fulfill a request for random
+data. It can be used with the `Rng` trait provided by this module by
+opening the file and passing it to `reader::ReaderRng`. Since it
+blocks, `/dev/random` should only be used to retrieve small amounts of
+randomness.
+
 # Examples
 
 ```rust
@@ -52,20 +69,21 @@ fn main () {
  ```
 */
 
-use mem::size_of;
-use unstable::raw::Slice;
 use cast;
+use cmp::Ord;
 use container::Container;
 use iter::{Iterator, range};
 use local_data;
 use prelude::*;
 use str;
-use u64;
 use vec;
 
 pub use self::isaac::{IsaacRng, Isaac64Rng};
 pub use self::os::OSRng;
 
+use self::distributions::{Range, IndependentSample};
+use self::distributions::range::SampleRange;
+
 pub mod distributions;
 pub mod isaac;
 pub mod os;
@@ -80,14 +98,6 @@ pub trait Rand {
     fn rand<R: Rng>(rng: &mut R) -> Self;
 }
 
-/// A value with a particular weight compared to other values
-pub struct Weighted<T> {
-    /// The numerical weight of this item
-    weight: uint,
-    /// The actual item which is being weighted
-    item: T,
-}
-
 /// A random number generator
 pub trait Rng {
     /// Return the next random u32. This rarely needs to be called
@@ -136,46 +146,26 @@ pub trait Rng {
     /// }
     /// ```
     fn fill_bytes(&mut self, dest: &mut [u8]) {
-        let mut slice: Slice<u64> = unsafe { cast::transmute_copy(&dest) };
-        slice.len /= size_of::<u64>();
-        let as_u64: &mut [u64] = unsafe { cast::transmute(slice) };
-        for dest in as_u64.mut_iter() {
-            *dest = self.next_u64();
-        }
-
-        // the above will have filled up the vector as much as
-        // possible in multiples of 8 bytes.
-        let mut remaining = dest.len() % 8;
-
-        // space for a u32
-        if remaining >= 4 {
-            let mut slice: Slice<u32> = unsafe { cast::transmute_copy(&dest) };
-            slice.len /= size_of::<u32>();
-            let as_u32: &mut [u32] = unsafe { cast::transmute(slice) };
-            as_u32[as_u32.len() - 1] = self.next_u32();
-            remaining -= 4;
-        }
-        // exactly filled
-        if remaining == 0 { return }
-
-        // now we know we've either got 1, 2 or 3 spots to go,
-        // i.e. exactly one u32 is enough.
-        let rand = self.next_u32();
-        let remaining_index = dest.len() - remaining;
-        match dest.mut_slice_from(remaining_index) {
-            [ref mut a] => {
-                *a = rand as u8;
-            }
-            [ref mut a, ref mut b] => {
-                *a = rand as u8;
-                *b = (rand >> 8) as u8;
-            }
-            [ref mut a, ref mut b, ref mut c] => {
-                *a = rand as u8;
-                *b = (rand >> 8) as u8;
-                *c = (rand >> 16) as u8;
+        // this could, in theory, be done by transmuting dest to a
+        // [u64], but this is (1) likely to be undefined behaviour for
+        // LLVM, (2) has to be very careful about alignment concerns,
+        // (3) adds more `unsafe` that needs to be checked, (4)
+        // probably doesn't give much performance gain if
+        // optimisations are on.
+        let mut count = 0;
+        let mut num = 0;
+        for byte in dest.mut_iter() {
+            if count == 0 {
+                // we could micro-optimise here by generating a u32 if
+                // we only need a few more bytes to fill the vector
+                // (i.e. at most 4).
+                num = self.next_u64();
+                count = 8;
             }
-            _ => fail!("Rng.fill_bytes: the impossible occurred: remaining != 1, 2 or 3")
+
+            *byte = (num & 0xff) as u8;
+            num >>= 8;
+            count -= 1;
         }
     }
 
@@ -218,14 +208,14 @@ pub trait Rng {
         vec::from_fn(len, |_| self.gen())
     }
 
-    /// Generate a random primitive integer in the range [`low`,
-    /// `high`). Fails if `low >= high`.
+    /// Generate a random value in the range [`low`, `high`). Fails if
+    /// `low >= high`.
     ///
-    /// This gives a uniform distribution (assuming this RNG is itself
-    /// uniform), even for edge cases like `gen_integer_range(0u8,
-    /// 170)`, which a naive modulo operation would return numbers
-    /// less than 85 with double the probability to those greater than
-    /// 85.
+    /// This is a convenience wrapper around
+    /// `distributions::Range`. If this function will be called
+    /// repeatedly with the same arguments, one should use `Range`, as
+    /// that will amortize the computations that allow for perfect
+    /// uniformity, as they only happen on initialization.
     ///
     /// # Example
     ///
@@ -235,22 +225,15 @@ pub trait Rng {
     ///
     /// fn main() {
     ///    let mut rng = rand::task_rng();
-    ///    let n: uint = rng.gen_integer_range(0u, 10);
+    ///    let n: uint = rng.gen_range(0u, 10);
     ///    println!("{}", n);
-    ///    let m: int = rng.gen_integer_range(-40, 400);
+    ///    let m: float = rng.gen_range(-40.0, 1.3e5);
     ///    println!("{}", m);
     /// }
     /// ```
-    fn gen_integer_range<T: Rand + Int>(&mut self, low: T, high: T) -> T {
-        assert!(low < high, "RNG.gen_integer_range called with low >= high");
-        let range = (high - low).to_u64().unwrap();
-        let accept_zone = u64::max_value - u64::max_value % range;
-        loop {
-            let rand = self.gen::<u64>();
-            if rand < accept_zone {
-                return low + NumCast::from(rand % range).unwrap();
-            }
-        }
+    fn gen_range<T: Ord + SampleRange>(&mut self, low: T, high: T) -> T {
+        assert!(low < high, "Rng.gen_range called with low >= high");
+        Range::new(low, high).ind_sample(self)
     }
 
     /// Return a bool with a 1 in n chance of true
@@ -267,7 +250,7 @@ pub trait Rng {
     /// }
     /// ```
     fn gen_weighted_bool(&mut self, n: uint) -> bool {
-        n == 0 || self.gen_integer_range(0, n) == 0
+        n == 0 || self.gen_range(0, n) == 0
     }
 
     /// Return a random string of the specified length composed of
@@ -317,93 +300,8 @@ pub trait Rng {
         if values.is_empty() {
             None
         } else {
-            Some(&values[self.gen_integer_range(0u, values.len())])
-        }
-    }
-
-    /// Choose an item respecting the relative weights, failing if the sum of
-    /// the weights is 0
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::rand;
-    /// use std::rand::Rng;
-    ///
-    /// fn main() {
-    ///     let mut rng = rand::rng();
-    ///     let x = [rand::Weighted {weight: 4, item: 'a'},
-    ///              rand::Weighted {weight: 2, item: 'b'},
-    ///              rand::Weighted {weight: 2, item: 'c'}];
-    ///     println!("{}", rng.choose_weighted(x));
-    /// }
-    /// ```
-    fn choose_weighted<T:Clone>(&mut self, v: &[Weighted<T>]) -> T {
-        self.choose_weighted_option(v).expect("Rng.choose_weighted: total weight is 0")
-    }
-
-    /// Choose Some(item) respecting the relative weights, returning none if
-    /// the sum of the weights is 0
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::rand;
-    /// use std::rand::Rng;
-    ///
-    /// fn main() {
-    ///     let mut rng = rand::rng();
-    ///     let x = [rand::Weighted {weight: 4, item: 'a'},
-    ///              rand::Weighted {weight: 2, item: 'b'},
-    ///              rand::Weighted {weight: 2, item: 'c'}];
-    ///     println!("{:?}", rng.choose_weighted_option(x));
-    /// }
-    /// ```
-    fn choose_weighted_option<T:Clone>(&mut self, v: &[Weighted<T>])
-                                       -> Option<T> {
-        let mut total = 0u;
-        for item in v.iter() {
-            total += item.weight;
-        }
-        if total == 0u {
-            return None;
-        }
-        let chosen = self.gen_integer_range(0u, total);
-        let mut so_far = 0u;
-        for item in v.iter() {
-            so_far += item.weight;
-            if so_far > chosen {
-                return Some(item.item.clone());
-            }
+            Some(&values[self.gen_range(0u, values.len())])
         }
-        unreachable!();
-    }
-
-    /// Return a vec containing copies of the items, in order, where
-    /// the weight of the item determines how many copies there are
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::rand;
-    /// use std::rand::Rng;
-    ///
-    /// fn main() {
-    ///     let mut rng = rand::rng();
-    ///     let x = [rand::Weighted {weight: 4, item: 'a'},
-    ///              rand::Weighted {weight: 2, item: 'b'},
-    ///              rand::Weighted {weight: 2, item: 'c'}];
-    ///     println!("{}", rng.weighted_vec(x));
-    /// }
-    /// ```
-    fn weighted_vec<T:Clone>(&mut self, v: &[Weighted<T>]) -> ~[T] {
-        let mut r = ~[];
-        for item in v.iter() {
-            for _ in range(0u, item.weight) {
-                r.push(item.item.clone());
-            }
-        }
-        r
     }
 
     /// Shuffle a vec
@@ -447,7 +345,7 @@ pub trait Rng {
             // invariant: elements with index >= i have been locked in place.
             i -= 1u;
             // lock element i in place.
-            values.swap(i, self.gen_integer_range(0u, i + 1u));
+            values.swap(i, self.gen_range(0u, i + 1u));
         }
     }
 
@@ -473,7 +371,7 @@ pub trait Rng {
                 continue
             }
 
-            let k = self.gen_integer_range(0, i + 1);
+            let k = self.gen_range(0, i + 1);
             if k < reservoir.len() {
                 reservoir[k] = elem
             }
@@ -520,8 +418,8 @@ pub trait SeedableRng<Seed>: Rng {
 
 /// Create a random number generator with a default algorithm and seed.
 ///
-/// It returns the cryptographically-safest `Rng` algorithm currently
-/// available in Rust. If you require a specifically seeded `Rng` for
+/// It returns the strongest `Rng` algorithm currently implemented in
+/// pure Rust. If you require a specifically seeded `Rng` for
 /// consistency over time you should pick one algorithm and create the
 /// `Rng` yourself.
 ///
@@ -596,12 +494,16 @@ pub fn weak_rng() -> XorShiftRng {
     XorShiftRng::new()
 }
 
-/// An [Xorshift random number
-/// generator](http://en.wikipedia.org/wiki/Xorshift).
+/// An Xorshift[1] random number
+/// generator.
 ///
 /// The Xorshift algorithm is not suitable for cryptographic purposes
 /// but is very fast. If you do not know for sure that it fits your
-/// requirements, use a more secure one such as `IsaacRng`.
+/// requirements, use a more secure one such as `IsaacRng` or `OSRng`.
+///
+/// [1]: Marsaglia, George (July 2003). ["Xorshift
+/// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
+/// Statistical Software*. Vol. 8 (Issue 14).
 pub struct XorShiftRng {
     priv x: u32,
     priv y: u32,
@@ -749,47 +651,68 @@ pub fn random<T: Rand>() -> T {
 mod test {
     use iter::{Iterator, range};
     use option::{Option, Some};
+    use vec;
     use super::*;
 
+    struct ConstRng { i: u64 }
+    impl Rng for ConstRng {
+        fn next_u32(&mut self) -> u32 { self.i as u32 }
+        fn next_u64(&mut self) -> u64 { self.i }
+
+        // no fill_bytes on purpose
+    }
+
     #[test]
     fn test_fill_bytes_default() {
-        let mut r = weak_rng();
-
-        let mut v = [0u8, .. 100];
-        r.fill_bytes(v);
+        let mut r = ConstRng { i: 0x11_22_33_44_55_66_77_88 };
+
+        // check every remainder mod 8, both in small and big vectors.
+        let lengths = [0, 1, 2, 3, 4, 5, 6, 7,
+                       80, 81, 82, 83, 84, 85, 86, 87];
+        for &n in lengths.iter() {
+            let mut v = vec::from_elem(n, 0u8);
+            r.fill_bytes(v);
+
+            // use this to get nicer error messages.
+            for (i, &byte) in v.iter().enumerate() {
+                if byte == 0 {
+                    fail!("byte {} of {} is zero", i, n)
+                }
+            }
+        }
     }
 
     #[test]
-    fn test_gen_integer_range() {
+    fn test_gen_range() {
         let mut r = rng();
         for _ in range(0, 1000) {
-            let a = r.gen_integer_range(-3i, 42);
+            let a = r.gen_range(-3i, 42);
             assert!(a >= -3 && a < 42);
-            assert_eq!(r.gen_integer_range(0, 1), 0);
-            assert_eq!(r.gen_integer_range(-12, -11), -12);
+            assert_eq!(r.gen_range(0, 1), 0);
+            assert_eq!(r.gen_range(-12, -11), -12);
         }
 
         for _ in range(0, 1000) {
-            let a = r.gen_integer_range(10, 42);
+            let a = r.gen_range(10, 42);
             assert!(a >= 10 && a < 42);
-            assert_eq!(r.gen_integer_range(0, 1), 0);
-            assert_eq!(r.gen_integer_range(3_000_000u, 3_000_001), 3_000_000);
+            assert_eq!(r.gen_range(0, 1), 0);
+            assert_eq!(r.gen_range(3_000_000u, 3_000_001), 3_000_000);
         }
 
     }
 
     #[test]
     #[should_fail]
-    fn test_gen_integer_range_fail_int() {
+    fn test_gen_range_fail_int() {
         let mut r = rng();
-        r.gen_integer_range(5i, -2);
+        r.gen_range(5i, -2);
     }
 
     #[test]
     #[should_fail]
-    fn test_gen_integer_range_fail_uint() {
+    fn test_gen_range_fail_uint() {
         let mut r = rng();
-        r.gen_integer_range(5u, 2u);
+        r.gen_range(5u, 2u);
     }
 
     #[test]
@@ -844,44 +767,6 @@ mod test {
     }
 
     #[test]
-    fn test_choose_weighted() {
-        let mut r = rng();
-        assert!(r.choose_weighted([
-            Weighted { weight: 1u, item: 42 },
-        ]) == 42);
-        assert!(r.choose_weighted([
-            Weighted { weight: 0u, item: 42 },
-            Weighted { weight: 1u, item: 43 },
-        ]) == 43);
-    }
-
-    #[test]
-    fn test_choose_weighted_option() {
-        let mut r = rng();
-        assert!(r.choose_weighted_option([
-            Weighted { weight: 1u, item: 42 },
-        ]) == Some(42));
-        assert!(r.choose_weighted_option([
-            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 test_weighted_vec() {
-        let mut r = rng();
-        let empty: ~[int] = ~[];
-        assert_eq!(r.weighted_vec([]), empty);
-        assert!(r.weighted_vec([
-            Weighted { weight: 0u, item: 3u },
-            Weighted { weight: 1u, item: 2u },
-            Weighted { weight: 2u, item: 1u },
-        ]) == ~[2u, 1u, 1u]);
-    }
-
-    #[test]
     fn test_shuffle() {
         let mut r = rng();
         let empty: ~[int] = ~[];
@@ -894,7 +779,7 @@ mod test {
         let mut r = task_rng();
         r.gen::<int>();
         assert_eq!(r.shuffle(~[1, 1, 1]), ~[1, 1, 1]);
-        assert_eq!(r.gen_integer_range(0u, 1u), 0u);
+        assert_eq!(r.gen_range(0u, 1u), 0u);
     }
 
     #[test]
@@ -953,41 +838,53 @@ mod bench {
     use extra::test::BenchHarness;
     use rand::*;
     use mem::size_of;
+    use iter::range;
+    use option::{Some, None};
+
+    static N: u64 = 100;
 
     #[bench]
     fn rand_xorshift(bh: &mut BenchHarness) {
         let mut rng = XorShiftRng::new();
         do bh.iter {
-            rng.gen::<uint>();
+            for _ in range(0, N) {
+                rng.gen::<uint>();
+            }
         }
-        bh.bytes = size_of::<uint>() as u64;
+        bh.bytes = size_of::<uint>() as u64 * N;
     }
 
     #[bench]
     fn rand_isaac(bh: &mut BenchHarness) {
         let mut rng = IsaacRng::new();
         do bh.iter {
-            rng.gen::<uint>();
+            for _ in range(0, N) {
+                rng.gen::<uint>();
+            }
         }
-        bh.bytes = size_of::<uint>() as u64;
+        bh.bytes = size_of::<uint>() as u64 * N;
     }
 
     #[bench]
     fn rand_isaac64(bh: &mut BenchHarness) {
         let mut rng = Isaac64Rng::new();
         do bh.iter {
-            rng.gen::<uint>();
+            for _ in range(0, N) {
+                rng.gen::<uint>();
+            }
         }
-        bh.bytes = size_of::<uint>() as u64;
+        bh.bytes = size_of::<uint>() as u64 * N;
     }
 
     #[bench]
     fn rand_std(bh: &mut BenchHarness) {
         let mut rng = StdRng::new();
         do bh.iter {
-            rng.gen::<uint>();
+            for _ in range(0, N) {
+                rng.gen::<uint>();
+            }
         }
-        bh.bytes = size_of::<uint>() as u64;
+        bh.bytes = size_of::<uint>() as u64 * N;
     }
 
     #[bench]
diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs
index 4c8cf06c55e..5ed8d6b10d1 100644
--- a/src/libstd/rand/os.rs
+++ b/src/libstd/rand/os.rs
@@ -30,8 +30,12 @@ type HCRYPTPROV = c_long;
 // assume they work when we call them.
 
 /// A random number generator that retrieves randomness straight from
-/// the operating system. On Unix-like systems this reads from
-/// `/dev/urandom`, on Windows this uses `CryptGenRandom`.
+/// the operating system. Platform sources:
+///
+/// - Unix-like systems (Linux, Android, Mac OSX): read directly from
+///   `/dev/urandom`.
+/// - Windows: calls `CryptGenRandom`, using the default cryptographic
+///   service provider with the `PROV_RSA_FULL` type.
 ///
 /// This does not block.
 #[cfg(unix)]
@@ -39,8 +43,12 @@ pub struct OSRng {
     priv inner: ReaderRng<file::FileStream>
 }
 /// A random number generator that retrieves randomness straight from
-/// the operating system. On Unix-like systems this reads from
-/// `/dev/urandom`, on Windows this uses `CryptGenRandom`.
+/// the operating system. Platform sources:
+///
+/// - Unix-like systems (Linux, Android, Mac OSX): read directly from
+///   `/dev/urandom`.
+/// - Windows: calls `CryptGenRandom`, using the default cryptographic
+///   service provider with the `PROV_RSA_FULL` type.
 ///
 /// This does not block.
 #[cfg(windows)]
diff --git a/src/libstd/rand/range.rs b/src/libstd/rand/range.rs
new file mode 100644
index 00000000000..1b805a0b8f7
--- /dev/null
+++ b/src/libstd/rand/range.rs
@@ -0,0 +1,235 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Generating numbers between two others.
+
+// this is surprisingly complicated to be both generic & correct
+
+use cmp::Ord;
+use num::Bounded;
+use rand::Rng;
+use rand::distributions::{Sample, IndependentSample};
+
+/// Sample values uniformly between two bounds.
+///
+/// This gives a uniform distribution (assuming the RNG used to sample
+/// it is itself uniform & the `SampleRange` implementation for the
+/// given type is correct), even for edge cases like `low = 0u8`,
+/// `high = 170u8`, for which a naive modulo operation would return
+/// numbers less than 85 with double the probability to those greater
+/// than 85.
+///
+/// Types should attempt to sample in `[low, high)`, i.e., not
+/// including `high`, but this may be very difficult. All the
+/// primitive integer types satisfy this property, and the float types
+/// normally satisfy it, but rounding may mean `high` can occur.
+///
+/// # Example
+///
+/// ```rust
+/// use std::rand;
+/// use std::rand::distributions::{IndependentSample, Range};
+///
+/// fn main() {
+///     let between = Range::new(10u, 10000u);
+///     let rng = rand::task_rng();
+///     let mut sum = 0;
+///     for _ in range(0, 1000) {
+///         sum += between.ind_sample(rng);
+///     }
+///     println!("{}", sum);
+/// }
+/// ```
+pub struct Range<X> {
+    priv low: X,
+    priv range: X,
+    priv accept_zone: X
+}
+
+impl<X: SampleRange + Ord> Range<X> {
+    /// Create a new `Range` instance that samples uniformly from
+    /// `[low, high)`. Fails if `low >= high`.
+    pub fn new(low: X, high: X) -> Range<X> {
+        assert!(low < high, "Range::new called with `low >= high`");
+        SampleRange::construct_range(low, high)
+    }
+}
+
+impl<Sup: SampleRange> Sample<Sup> for Range<Sup> {
+    #[inline]
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) }
+}
+impl<Sup: SampleRange> IndependentSample<Sup> for Range<Sup> {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> Sup {
+        SampleRange::sample_range(self, rng)
+    }
+}
+
+/// The helper trait for types that have a sensible way to sample
+/// uniformly between two values. This should not be used directly,
+/// and is only to facilitate `Range`.
+pub trait SampleRange {
+    /// Construct the `Range` object that `sample_range`
+    /// requires. This should not ever be called directly, only via
+    /// `Range::new`, which will check that `low < high`, so this
+    /// function doesn't have to repeat the check.
+    fn construct_range(low: Self, high: Self) -> Range<Self>;
+
+    /// Sample a value from the given `Range` with the given `Rng` as
+    /// a source of randomness.
+    fn sample_range<R: Rng>(r: &Range<Self>, rng: &mut R) -> Self;
+}
+
+macro_rules! integer_impl {
+    ($ty:ty, $unsigned:ty) => {
+        impl SampleRange for $ty {
+            // we play free and fast with unsigned vs signed here
+            // (when $ty is signed), but that's fine, since the
+            // contract of this macro is for $ty and $unsigned to be
+            // "bit-equal", so casting between them is a no-op & a
+            // bijection.
+
+            fn construct_range(low: $ty, high: $ty) -> Range<$ty> {
+                let range = high as $unsigned - low as $unsigned;
+                let unsigned_max: $unsigned = Bounded::max_value();
+
+                // this is the largest number that fits into $unsigned
+                // that `range` divides evenly, so, if we've sampled
+                // `n` uniformly from this region, then `n % range` is
+                // uniform in [0, range)
+                let zone = unsigned_max - unsigned_max % range;
+
+                Range {
+                    low: low,
+                    range: range as $ty,
+                    accept_zone: zone as $ty
+                }
+            }
+            #[inline]
+            fn sample_range<R: Rng>(r: &Range<$ty>, rng: &mut R) -> $ty {
+                loop {
+                    // rejection sample
+                    let v = rng.gen::<$unsigned>();
+                    // until we find something that fits into the
+                    // region which r.range evenly divides (this will
+                    // be uniformly distributed)
+                    if v < r.accept_zone as $unsigned {
+                        // and return it, with some adjustments
+                        return r.low + (v % r.range as $unsigned) as $ty;
+                    }
+                }
+            }
+        }
+    }
+}
+
+integer_impl! { i8, u8 }
+integer_impl! { i16, u16 }
+integer_impl! { i32, u32 }
+integer_impl! { i64, u64 }
+integer_impl! { int, uint }
+integer_impl! { u8, u8 }
+integer_impl! { u16, u16 }
+integer_impl! { u32, u32 }
+integer_impl! { u64, u64 }
+integer_impl! { uint, uint }
+
+macro_rules! float_impl {
+    ($ty:ty) => {
+        impl SampleRange for $ty {
+            fn construct_range(low: $ty, high: $ty) -> Range<$ty> {
+                Range {
+                    low: low,
+                    range: high - low,
+                    accept_zone: 0.0 // unused
+                }
+            }
+            fn sample_range<R: Rng>(r: &Range<$ty>, rng: &mut R) -> $ty {
+                r.low + r.range * rng.gen()
+            }
+        }
+    }
+}
+
+float_impl! { f32 }
+float_impl! { f64 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use rand::*;
+    use num::Bounded;
+    use iter::range;
+    use option::{Some, None};
+    use vec::ImmutableVector;
+
+    #[should_fail]
+    #[test]
+    fn test_range_bad_limits_equal() {
+        Range::new(10, 10);
+    }
+    #[should_fail]
+    #[test]
+    fn test_range_bad_limits_flipped() {
+        Range::new(10, 5);
+    }
+
+    #[test]
+    fn test_integers() {
+        let rng = task_rng();
+        macro_rules! t (
+            ($($ty:ty),*) => {{
+                $(
+                   let v: &[($ty, $ty)] = [(0, 10),
+                                           (10, 127),
+                                           (Bounded::min_value(), Bounded::max_value())];
+                   for &(low, high) in v.iter() {
+                        let mut sampler: Range<$ty> = Range::new(low, high);
+                        for _ in range(0, 1000) {
+                            let v = sampler.sample(rng);
+                            assert!(low <= v && v < high);
+                            let v = sampler.ind_sample(rng);
+                            assert!(low <= v && v < high);
+                        }
+                    }
+                 )*
+            }}
+        );
+        t!(i8, i16, i32, i64, int,
+           u8, u16, u32, u64, uint)
+    }
+
+    #[test]
+    fn test_floats() {
+        let rng = task_rng();
+        macro_rules! t (
+            ($($ty:ty),*) => {{
+                $(
+                   let v: &[($ty, $ty)] = [(0.0, 100.0),
+                                           (-1e35, -1e25),
+                                           (1e-35, 1e-25),
+                                           (-1e35, 1e35)];
+                   for &(low, high) in v.iter() {
+                        let mut sampler: Range<$ty> = Range::new(low, high);
+                        for _ in range(0, 1000) {
+                            let v = sampler.sample(rng);
+                            assert!(low <= v && v < high);
+                            let v = sampler.ind_sample(rng);
+                            assert!(low <= v && v < high);
+                        }
+                    }
+                 )*
+            }}
+        );
+
+        t!(f32, f64)
+    }
+
+}
diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs
index 1cd76727716..d63b14f982d 100644
--- a/src/libstd/reflect.rs
+++ b/src/libstd/reflect.rs
@@ -41,7 +41,7 @@ pub fn align(size: uint, align: uint) -> uint {
 
 /// Adaptor to wrap around visitors implementing MovePtr.
 pub struct MovePtrAdaptor<V> {
-    inner: V
+    priv inner: V
 }
 pub fn MovePtrAdaptor<V:TyVisitor + MovePtr>(v: V) -> MovePtrAdaptor<V> {
     MovePtrAdaptor { inner: v }
diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs
index 4feb1ca1910..d03621eb60d 100644
--- a/src/libstd/repr.rs
+++ b/src/libstd/repr.rs
@@ -98,10 +98,10 @@ enum VariantState {
 }
 
 pub struct ReprVisitor<'self> {
-    ptr: *c_void,
-    ptr_stk: ~[*c_void],
-    var_stk: ~[VariantState],
-    writer: &'self mut io::Writer
+    priv ptr: *c_void,
+    priv ptr_stk: ~[*c_void],
+    priv var_stk: ~[VariantState],
+    priv writer: &'self mut io::Writer
 }
 
 pub fn ReprVisitor<'a>(ptr: *c_void,
diff --git a/src/libstd/rt/borrowck.rs b/src/libstd/rt/borrowck.rs
index 3c2000c522c..4426a3eafe1 100644
--- a/src/libstd/rt/borrowck.rs
+++ b/src/libstd/rt/borrowck.rs
@@ -29,9 +29,9 @@ static ALL_BITS: uint = FROZEN_BIT | MUT_BIT;
 
 #[deriving(Eq)]
 pub struct BorrowRecord {
-    box: *mut raw::Box<()>,
+    priv box: *mut raw::Box<()>,
     file: *c_char,
-    line: size_t
+    priv line: size_t
 }
 
 fn try_take_task_borrow_list() -> Option<~[BorrowRecord]> {
diff --git a/src/libstd/rt/comm.rs b/src/libstd/rt/comm.rs
index 4eae8bdc9a8..6319fdead17 100644
--- a/src/libstd/rt/comm.rs
+++ b/src/libstd/rt/comm.rs
@@ -48,14 +48,14 @@ struct Packet<T> {
 
 // A one-shot channel.
 pub struct ChanOne<T> {
-    void_packet: *mut Void,
-    suppress_finalize: bool
+    priv void_packet: *mut Void,
+    priv suppress_finalize: bool
 }
 
 /// A one-shot port.
 pub struct PortOne<T> {
-    void_packet: *mut Void,
-    suppress_finalize: bool
+    priv void_packet: *mut Void,
+    priv suppress_finalize: bool
 }
 
 pub fn oneshot<T: Send>() -> (PortOne<T>, ChanOne<T>) {
@@ -1117,7 +1117,7 @@ mod test {
             let total = stress_factor() + 10;
             let mut rng = rand::rng();
             do total.times {
-                let msgs = rng.gen_integer_range(0u, 10);
+                let msgs = rng.gen_range(0u, 10);
                 let pipe_clone = pipe.clone();
                 let end_chan_clone = end_chan.clone();
                 do spawntask_random {
diff --git a/src/libstd/rt/context.rs b/src/libstd/rt/context.rs
index 7f7545ca230..b86dbfd6fb0 100644
--- a/src/libstd/rt/context.rs
+++ b/src/libstd/rt/context.rs
@@ -25,11 +25,11 @@ pub static RED_ZONE: uint = 20 * 1024;
 // then misalign the regs again.
 pub struct Context {
     /// The context entry point, saved here for later destruction
-    start: Option<~~fn()>,
+    priv start: Option<~~fn()>,
     /// Hold the registers while the task or scheduler is suspended
-    regs: ~Registers,
+    priv regs: ~Registers,
     /// Lower bound and upper bound for the stack
-    stack_bounds: Option<(uint, uint)>,
+    priv stack_bounds: Option<(uint, uint)>,
 }
 
 impl Context {
@@ -391,36 +391,32 @@ pub unsafe fn record_sp_limit(limit: uint) {
 /// As with the setter, this function does not have a __morestack header and can
 /// therefore be called in a "we're out of stack" situation.
 #[inline(always)]
-// NOTE: after the next snapshot, can remove the initialization before inline
-//       assembly due to an improvement in how it's handled, then this specific
-//       allow directive should get removed.
-#[allow(dead_assignment)]
 pub unsafe fn get_sp_limit() -> uint {
     return target_get_sp_limit();
 
     // x86-64
     #[cfg(target_arch = "x86_64", target_os = "macos")] #[inline(always)]
     unsafe fn target_get_sp_limit() -> uint {
-        let mut limit: uint = 0;
+        let limit;
         asm!("movq $$0x60+90*8, %rsi
               movq %gs:(%rsi), $0" : "=r"(limit) :: "rsi" : "volatile");
         return limit;
     }
     #[cfg(target_arch = "x86_64", target_os = "linux")] #[inline(always)]
     unsafe fn target_get_sp_limit() -> uint {
-        let mut limit: uint = 0;
+        let limit;
         asm!("movq %fs:112, $0" : "=r"(limit) ::: "volatile");
         return limit;
     }
     #[cfg(target_arch = "x86_64", target_os = "win32")] #[inline(always)]
     unsafe fn target_get_sp_limit() -> uint {
-        let mut limit: uint = 0;
+        let limit;
         asm!("movq %gs:0x28, $0" : "=r"(limit) ::: "volatile");
         return limit;
     }
     #[cfg(target_arch = "x86_64", target_os = "freebsd")] #[inline(always)]
     unsafe fn target_get_sp_limit() -> uint {
-        let mut limit: uint = 0;
+        let limit;
         asm!("movq %fs:24, $0" : "=r"(limit) ::: "volatile");
         return limit;
     }
@@ -428,7 +424,7 @@ pub unsafe fn get_sp_limit() -> uint {
     // x86
     #[cfg(target_arch = "x86", target_os = "macos")] #[inline(always)]
     unsafe fn target_get_sp_limit() -> uint {
-        let mut limit: uint = 0;
+        let limit;
         asm!("movl $$0x48+90*4, %eax
               movl %gs:(%eax), $0" : "=r"(limit) :: "eax" : "volatile");
         return limit;
@@ -436,13 +432,13 @@ pub unsafe fn get_sp_limit() -> uint {
     #[cfg(target_arch = "x86", target_os = "linux")]
     #[cfg(target_arch = "x86", target_os = "freebsd")] #[inline(always)]
     unsafe fn target_get_sp_limit() -> uint {
-        let mut limit: uint = 0;
+        let limit;
         asm!("movl %gs:48, $0" : "=r"(limit) ::: "volatile");
         return limit;
     }
     #[cfg(target_arch = "x86", target_os = "win32")] #[inline(always)]
     unsafe fn target_get_sp_limit() -> uint {
-        let mut limit: uint = 0;
+        let limit;
         asm!("movl %fs:0x14, $0" : "=r"(limit) ::: "volatile");
         return limit;
     }
diff --git a/src/libstd/rt/crate_map.rs b/src/libstd/rt/crate_map.rs
index d33e1af90f8..dd71426938d 100644
--- a/src/libstd/rt/crate_map.rs
+++ b/src/libstd/rt/crate_map.rs
@@ -26,9 +26,9 @@ pub struct ModEntry<'self> {
 }
 
 pub struct CrateMap<'self> {
-    version: i32,
-    entries: &'self [ModEntry<'self>],
-    children: &'self [&'self CrateMap<'self>]
+     priv version: i32,
+     priv entries: &'self [ModEntry<'self>],
+     priv children: &'self [&'self CrateMap<'self>]
 }
 
 #[cfg(not(windows))]
diff --git a/src/libstd/rt/io/file.rs b/src/libstd/rt/io/file.rs
index e25b03be361..a43bcd8142e 100644
--- a/src/libstd/rt/io/file.rs
+++ b/src/libstd/rt/io/file.rs
@@ -362,8 +362,8 @@ impl Seek for FileWriter {
 /// For this reason, it is best to use the access-constrained wrappers that are
 /// exposed via `FileInfo.open_reader()` and `FileInfo.open_writer()`.
 pub struct FileStream {
-    fd: ~RtioFileStream,
-    last_nread: int,
+    priv fd: ~RtioFileStream,
+    priv last_nread: int,
 }
 
 /// a `std::rt::io::Reader` trait impl for file I/O.
diff --git a/src/libstd/rt/io/flate.rs b/src/libstd/rt/io/flate.rs
index 7c72ce6ba89..8a5aa171eb8 100644
--- a/src/libstd/rt/io/flate.rs
+++ b/src/libstd/rt/io/flate.rs
@@ -17,7 +17,7 @@ use super::*;
 
 /// A Writer decorator that compresses using the 'deflate' scheme
 pub struct DeflateWriter<W> {
-    inner_writer: W
+    priv inner_writer: W
 }
 
 impl<W: Writer> DeflateWriter<W> {
@@ -56,7 +56,7 @@ impl<W: Writer> Decorator<W> for DeflateWriter<W> {
 
 /// A Reader decorator that decompresses using the 'deflate' scheme
 pub struct InflateReader<R> {
-    inner_reader: R
+    priv inner_reader: R
 }
 
 impl<R: Reader> InflateReader<R> {
diff --git a/src/libstd/rt/io/mock.rs b/src/libstd/rt/io/mock.rs
index c46e1372c64..44709c7b7b6 100644
--- a/src/libstd/rt/io/mock.rs
+++ b/src/libstd/rt/io/mock.rs
@@ -13,7 +13,7 @@ use rt::io::{Reader, Writer};
 
 pub struct MockReader {
     read: ~fn(buf: &mut [u8]) -> Option<uint>,
-    eof: ~fn() -> bool
+    priv eof: ~fn() -> bool
 }
 
 impl MockReader {
@@ -31,8 +31,8 @@ impl Reader for MockReader {
 }
 
 pub struct MockWriter {
-    write: ~fn(buf: &[u8]),
-    flush: ~fn()
+    priv write: ~fn(buf: &[u8]),
+    priv flush: ~fn()
 }
 
 impl MockWriter {
diff --git a/src/libstd/rt/io/mod.rs b/src/libstd/rt/io/mod.rs
index 97d44da765a..a80c1aab398 100644
--- a/src/libstd/rt/io/mod.rs
+++ b/src/libstd/rt/io/mod.rs
@@ -12,8 +12,8 @@
 
 This module defines the Rust interface for synchronous I/O.
 It models byte-oriented input and output with the Reader and Writer traits.
-Types that implement both `Reader` and `Writer` and called 'streams',
-and automatically implement trait `Stream`.
+Types that implement both `Reader` and `Writer` are called 'streams',
+and automatically implement the `Stream` trait.
 Implementations are provided for common I/O streams like
 file, TCP, UDP, Unix domain sockets.
 Readers and Writers may be composed to add capabilities like string
diff --git a/src/libstd/rt/kill.rs b/src/libstd/rt/kill.rs
index 8029e3f6431..19f17ca966d 100644
--- a/src/libstd/rt/kill.rs
+++ b/src/libstd/rt/kill.rs
@@ -219,17 +219,17 @@ pub struct Death {
     // might kill it. This is optional so we can take it by-value at exit time.
     kill_handle:     Option<KillHandle>,
     // Handle to a watching parent, if we have one, for exit code propagation.
-    watching_parent: Option<KillHandle>,
+    priv watching_parent: Option<KillHandle>,
     // Action to be done with the exit code. If set, also makes the task wait
     // until all its watched children exit before collecting the status.
     on_exit:         Option<~fn(bool)>,
     // nesting level counter for task::unkillable calls (0 == killable).
-    unkillable:      int,
+    priv unkillable:      int,
     // nesting level counter for unstable::atomically calls (0 == can deschedule).
-    wont_sleep:      int,
+    priv wont_sleep:      int,
     // A "spare" handle to the kill flag inside the kill handle. Used during
     // blocking/waking as an optimization to avoid two xadds on the refcount.
-    spare_kill_flag: Option<KillFlagHandle>,
+    priv spare_kill_flag: Option<KillFlagHandle>,
 }
 
 impl Drop for KillFlag {
diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs
index 262da9f3b8e..14df292343e 100644
--- a/src/libstd/rt/local_heap.rs
+++ b/src/libstd/rt/local_heap.rs
@@ -32,8 +32,8 @@ pub type OpaqueBox = c_void;
 pub type TypeDesc = c_void;
 
 pub struct LocalHeap {
-    memory_region: *MemoryRegion,
-    boxed_region: *BoxedRegion
+    priv memory_region: *MemoryRegion,
+    priv boxed_region: *BoxedRegion
 }
 
 impl LocalHeap {
diff --git a/src/libstd/rt/rc.rs b/src/libstd/rt/rc.rs
index 2ba00c3a2fb..2699dab6d38 100644
--- a/src/libstd/rt/rc.rs
+++ b/src/libstd/rt/rc.rs
@@ -24,7 +24,7 @@ use libc::c_void;
 use cast;
 
 pub struct RC<T> {
-    p: *c_void // ~(uint, T)
+    priv p: *c_void // ~(uint, T)
 }
 
 impl<T> RC<T> {
diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs
index ca521c792dc..501def8b060 100644
--- a/src/libstd/rt/rtio.rs
+++ b/src/libstd/rt/rtio.rs
@@ -66,7 +66,7 @@ pub struct FileOpenConfig {
     /// Flags for file access mode (as per open(2))
     flags: int,
     /// File creation mode, ignored unless O_CREAT is passed as part of flags
-    mode: int
+    priv mode: int
 }
 
 pub trait IoFactory {
diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs
index 336d2518e43..ee163bab3c0 100644
--- a/src/libstd/rt/sched.rs
+++ b/src/libstd/rt/sched.rs
@@ -66,26 +66,26 @@ pub struct Scheduler {
     event_loop: ~EventLoopObject,
     /// The scheduler runs on a special task. When it is not running
     /// it is stored here instead of the work queue.
-    sched_task: Option<~Task>,
+    priv sched_task: Option<~Task>,
     /// An action performed after a context switch on behalf of the
     /// code running before the context switch
-    cleanup_job: Option<CleanupJob>,
+    priv cleanup_job: Option<CleanupJob>,
     /// Should this scheduler run any task, or only pinned tasks?
     run_anything: bool,
     /// If the scheduler shouldn't run some tasks, a friend to send
     /// them to.
-    friend_handle: Option<SchedHandle>,
+    priv friend_handle: Option<SchedHandle>,
     /// A fast XorShift rng for scheduler use
     rng: XorShiftRng,
     /// A toggleable idle callback
-    idle_callback: Option<~PausibleIdleCallback>,
+    priv idle_callback: Option<~PausibleIdleCallback>,
     /// A countdown that starts at a random value and is decremented
     /// every time a yield check is performed. When it hits 0 a task
     /// will yield.
-    yield_check_count: uint,
+    priv yield_check_count: uint,
     /// A flag to tell the scheduler loop it needs to do some stealing
     /// in order to introduce randomness as part of a yield
-    steal_for_yield: bool
+    priv steal_for_yield: bool
 }
 
 /// An indication of how hard to work on a given operation, the difference
@@ -431,7 +431,7 @@ impl Scheduler {
     fn try_steals(&mut self) -> Option<~Task> {
         let work_queues = &mut self.work_queues;
         let len = work_queues.len();
-        let start_index = self.rng.gen_integer_range(0, len);
+        let start_index = self.rng.gen_range(0, len);
         for index in range(0, len).map(|i| (i + start_index) % len) {
             match work_queues[index].steal() {
                 Some(task) => {
diff --git a/src/libstd/rt/stack.rs b/src/libstd/rt/stack.rs
index fddee5882b9..55bd4b0732a 100644
--- a/src/libstd/rt/stack.rs
+++ b/src/libstd/rt/stack.rs
@@ -15,8 +15,8 @@ use ops::Drop;
 use libc::{c_uint, uintptr_t};
 
 pub struct StackSegment {
-    buf: ~[u8],
-    valgrind_id: c_uint
+    priv buf: ~[u8],
+    priv valgrind_id: c_uint
 }
 
 impl StackSegment {
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index a6f9e11e40e..c4f352501a0 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -44,7 +44,7 @@ use send_str::SendStr;
 
 pub struct Task {
     heap: LocalHeap,
-    gc: GarbageCollector,
+    priv gc: GarbageCollector,
     storage: LocalStorage,
     logger: StdErrLogger,
     unwinder: Unwinder,
@@ -69,7 +69,7 @@ pub struct Coroutine {
     /// The segment of stack on which the task is currently running or
     /// if the task is blocked, on which the task will resume
     /// execution.
-    current_stack_segment: StackSegment,
+    priv current_stack_segment: StackSegment,
     /// Always valid if the task is alive and not running.
     saved_context: Context
 }
diff --git a/src/libstd/rt/thread.rs b/src/libstd/rt/thread.rs
index e774b81da35..949d73ecc4f 100644
--- a/src/libstd/rt/thread.rs
+++ b/src/libstd/rt/thread.rs
@@ -18,9 +18,9 @@ use uint;
 type raw_thread = libc::c_void;
 
 pub struct Thread {
-    main: ~fn(),
-    raw_thread: *raw_thread,
-    joined: bool,
+    priv main: ~fn(),
+    priv raw_thread: *raw_thread,
+    priv joined: bool
 }
 
 impl Thread {
diff --git a/src/libstd/rt/tube.rs b/src/libstd/rt/tube.rs
index b8e535e4c7d..16fd3fa38ea 100644
--- a/src/libstd/rt/tube.rs
+++ b/src/libstd/rt/tube.rs
@@ -28,7 +28,7 @@ struct TubeState<T> {
 }
 
 pub struct Tube<T> {
-    p: RC<TubeState<T>>
+    priv p: RC<TubeState<T>>
 }
 
 impl<T> Tube<T> {
diff --git a/src/libstd/rt/uv/addrinfo.rs b/src/libstd/rt/uv/addrinfo.rs
index 83a7e64b139..f2abcd3aca7 100644
--- a/src/libstd/rt/uv/addrinfo.rs
+++ b/src/libstd/rt/uv/addrinfo.rs
@@ -25,7 +25,7 @@ type GetAddrInfoCallback = ~fn(GetAddrInfoRequest, &UvAddrInfo, Option<UvError>)
 pub struct GetAddrInfoRequest(*uvll::uv_getaddrinfo_t);
 
 pub struct RequestData {
-    getaddrinfo_cb: Option<GetAddrInfoCallback>,
+    priv getaddrinfo_cb: Option<GetAddrInfoCallback>,
 }
 
 impl GetAddrInfoRequest {
diff --git a/src/libstd/rt/uv/file.rs b/src/libstd/rt/uv/file.rs
index 3a6d858df79..5d64ca4d755 100644
--- a/src/libstd/rt/uv/file.rs
+++ b/src/libstd/rt/uv/file.rs
@@ -25,7 +25,7 @@ pub struct FsRequest(*uvll::uv_fs_t);
 impl Request for FsRequest {}
 
 pub struct RequestData {
-    complete_cb: Option<FsCallback>
+    priv complete_cb: Option<FsCallback>
 }
 
 impl FsRequest {
diff --git a/src/libstd/rt/uv/mod.rs b/src/libstd/rt/uv/mod.rs
index 67926b35a62..3a6a3acbc53 100644
--- a/src/libstd/rt/uv/mod.rs
+++ b/src/libstd/rt/uv/mod.rs
@@ -80,7 +80,7 @@ pub mod pipe;
 /// with dtors may not be destructured, but tuple structs can,
 /// but the results are not correct.
 pub struct Loop {
-    handle: *uvll::uv_loop_t
+    priv handle: *uvll::uv_loop_t
 }
 
 /// The trait implemented by uv 'watchers' (handles). Watchers are
diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs
index c7e51b3485d..8dd0f8a6b10 100644
--- a/src/libstd/rt/uv/uvio.rs
+++ b/src/libstd/rt/uv/uvio.rs
@@ -180,7 +180,7 @@ fn socket_name<T, U: Watcher + NativeHandle<*T>>(sk: SocketNameKind,
 
 // Obviously an Event Loop is always home.
 pub struct UvEventLoop {
-    uvio: UvIoFactory
+    priv uvio: UvIoFactory
 }
 
 impl UvEventLoop {
@@ -240,9 +240,9 @@ impl EventLoop for UvEventLoop {
 }
 
 pub struct UvPausibleIdleCallback {
-    watcher: IdleWatcher,
-    idle_flag: bool,
-    closed: bool
+    priv watcher: IdleWatcher,
+    priv idle_flag: bool,
+    priv closed: bool
 }
 
 impl UvPausibleIdleCallback {
@@ -294,10 +294,10 @@ fn test_callback_run_once() {
 // The entire point of async is to call into a loop from other threads so it does not need to home.
 pub struct UvRemoteCallback {
     // The uv async handle for triggering the callback
-    async: AsyncWatcher,
+    priv async: AsyncWatcher,
     // A flag to tell the callback to exit, set from the dtor. This is
     // almost never contested - only in rare races with the dtor.
-    exit_flag: Exclusive<bool>
+    priv exit_flag: Exclusive<bool>
 }
 
 impl UvRemoteCallback {
@@ -804,8 +804,8 @@ impl IoFactory for UvIoFactory {
 }
 
 pub struct UvTcpListener {
-    watcher : TcpWatcher,
-    home: SchedHandle,
+    priv watcher : TcpWatcher,
+    priv home: SchedHandle,
 }
 
 impl HomingIO for UvTcpListener {
@@ -866,8 +866,8 @@ impl RtioTcpListener for UvTcpListener {
 }
 
 pub struct UvTcpAcceptor {
-    listener: UvTcpListener,
-    incoming: Tube<Result<~RtioTcpStreamObject, IoError>>,
+    priv listener: UvTcpListener,
+    priv incoming: Tube<Result<~RtioTcpStreamObject, IoError>>,
 }
 
 impl HomingIO for UvTcpAcceptor {
@@ -991,7 +991,7 @@ fn write_stream(mut watcher: StreamWatcher,
 
 pub struct UvUnboundPipe {
     pipe: Pipe,
-    home: SchedHandle,
+    priv home: SchedHandle,
 }
 
 impl HomingIO for UvUnboundPipe {
@@ -1043,8 +1043,8 @@ impl RtioPipe for UvPipeStream {
 }
 
 pub struct UvTcpStream {
-    watcher: TcpWatcher,
-    home: SchedHandle,
+    priv watcher: TcpWatcher,
+    priv home: SchedHandle,
 }
 
 impl HomingIO for UvTcpStream {
@@ -1143,8 +1143,8 @@ impl RtioTcpStream for UvTcpStream {
 }
 
 pub struct UvUdpSocket {
-    watcher: UdpWatcher,
-    home: SchedHandle,
+    priv watcher: UdpWatcher,
+    priv home: SchedHandle,
 }
 
 impl HomingIO for UvUdpSocket {
@@ -1353,8 +1353,8 @@ impl RtioUdpSocket for UvUdpSocket {
 }
 
 pub struct UvTimer {
-    watcher: timer::TimerWatcher,
-    home: SchedHandle,
+    priv watcher: timer::TimerWatcher,
+    priv home: SchedHandle,
 }
 
 impl HomingIO for UvTimer {
@@ -1400,10 +1400,10 @@ impl RtioTimer for UvTimer {
 }
 
 pub struct UvFileStream {
-    loop_: Loop,
-    fd: c_int,
-    close_on_drop: bool,
-    home: SchedHandle
+    priv loop_: Loop,
+    priv fd: c_int,
+    priv close_on_drop: bool,
+    priv home: SchedHandle
 }
 
 impl HomingIO for UvFileStream {
@@ -1533,11 +1533,11 @@ impl RtioFileStream for UvFileStream {
 }
 
 pub struct UvProcess {
-    process: process::Process,
+    priv process: process::Process,
 
     // Sadly, this structure must be created before we return it, so in that
     // brief interim the `home` is None.
-    home: Option<SchedHandle>,
+    priv home: Option<SchedHandle>,
 
     // All None until the process exits (exit_error may stay None)
     priv exit_status: Option<int>,
diff --git a/src/libstd/rt/uv/uvll.rs b/src/libstd/rt/uv/uvll.rs
index a80d5cbc1fb..96c5dd068d0 100644
--- a/src/libstd/rt/uv/uvll.rs
+++ b/src/libstd/rt/uv/uvll.rs
@@ -134,26 +134,26 @@ pub type uv_pipe_t = c_void;
 
 pub struct uv_timespec_t {
     tv_sec: libc::c_long,
-    tv_nsec: libc::c_long
+    priv tv_nsec: libc::c_long
 }
 
 pub struct uv_stat_t {
-    st_dev: libc::uint64_t,
+    priv st_dev: libc::uint64_t,
     st_mode: libc::uint64_t,
-    st_nlink: libc::uint64_t,
-    st_uid: libc::uint64_t,
-    st_gid: libc::uint64_t,
-    st_rdev: libc::uint64_t,
-    st_ino: libc::uint64_t,
+    priv st_nlink: libc::uint64_t,
+    priv st_uid: libc::uint64_t,
+    priv st_gid: libc::uint64_t,
+    priv st_rdev: libc::uint64_t,
+    priv st_ino: libc::uint64_t,
     st_size: libc::uint64_t,
-    st_blksize: libc::uint64_t,
-    st_blocks: libc::uint64_t,
-    st_flags: libc::uint64_t,
-    st_gen: libc::uint64_t,
+    priv st_blksize: libc::uint64_t,
+    priv st_blocks: libc::uint64_t,
+    priv st_flags: libc::uint64_t,
+    priv st_gen: libc::uint64_t,
     st_atim: uv_timespec_t,
     st_mtim: uv_timespec_t,
     st_ctim: uv_timespec_t,
-    st_birthtim: uv_timespec_t
+    priv st_birthtim: uv_timespec_t
 }
 
 impl uv_stat_t {
@@ -231,37 +231,37 @@ pub type socklen_t = c_int;
 #[cfg(target_os = "android")]
 #[cfg(target_os = "linux")]
 pub struct addrinfo {
-    ai_flags: c_int,
-    ai_family: c_int,
-    ai_socktype: c_int,
-    ai_protocol: c_int,
-    ai_addrlen: socklen_t,
+    priv ai_flags: c_int,
+    priv ai_family: c_int,
+    priv ai_socktype: c_int,
+    priv ai_protocol: c_int,
+    priv ai_addrlen: socklen_t,
     ai_addr: *sockaddr,
-    ai_canonname: *char,
+    priv ai_canonname: *char,
     ai_next: *addrinfo
 }
 
 #[cfg(target_os = "macos")]
 #[cfg(target_os = "freebsd")]
 pub struct addrinfo {
-    ai_flags: c_int,
-    ai_family: c_int,
-    ai_socktype: c_int,
-    ai_protocol: c_int,
-    ai_addrlen: socklen_t,
-    ai_canonname: *char,
+    priv ai_flags: c_int,
+    priv ai_family: c_int,
+    priv ai_socktype: c_int,
+    priv ai_protocol: c_int,
+    priv ai_addrlen: socklen_t,
+    priv ai_canonname: *char,
     ai_addr: *sockaddr,
     ai_next: *addrinfo
 }
 
 #[cfg(windows)]
 pub struct addrinfo {
-    ai_flags: c_int,
-    ai_family: c_int,
-    ai_socktype: c_int,
-    ai_protocol: c_int,
-    ai_addrlen: size_t,
-    ai_canonname: *char,
+    priv ai_flags: c_int,
+    priv ai_family: c_int,
+    priv ai_socktype: c_int,
+    priv ai_protocol: c_int,
+    priv ai_addrlen: size_t,
+    priv ai_canonname: *char,
     ai_addr: *sockaddr,
     ai_next: *addrinfo
 }
@@ -960,8 +960,8 @@ pub unsafe fn freeaddrinfo(ai: *addrinfo) {
 }
 
 pub struct uv_err_data {
-    err_name: ~str,
-    err_msg: ~str,
+    priv err_name: ~str,
+    priv err_msg: ~str,
 }
 
 extern {
diff --git a/src/libstd/run.rs b/src/libstd/run.rs
index 36e73a6dd51..c4cb8be2061 100644
--- a/src/libstd/run.rs
+++ b/src/libstd/run.rs
@@ -34,7 +34,6 @@ pub struct Process {
 
 /// Options that can be given when starting a Process.
 pub struct ProcessOptions<'self> {
-
     /**
      * If this is None then the new process will have the same initial
      * environment as the parent process.
@@ -99,7 +98,6 @@ impl <'self> ProcessOptions<'self> {
 
 /// The output of a finished process.
 pub struct ProcessOutput {
-
     /// The status (exit code) of the process.
     status: int,
 
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index 883934124a6..f134788942c 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -998,7 +998,6 @@ pub fn utf8_char_width(b: u8) -> uint {
 pub struct CharRange {
     /// Current `char`
     ch: char,
-
     /// Index of the first byte of the next `char`
     next: uint
 }
diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs
index 970a62b676f..30c99c62885 100644
--- a/src/libstd/task/mod.rs
+++ b/src/libstd/task/mod.rs
@@ -108,7 +108,7 @@ pub enum SchedMode {
  *
  */
 pub struct SchedOpts {
-    mode: SchedMode,
+    priv mode: SchedMode,
 }
 
 /**
@@ -144,11 +144,11 @@ pub struct SchedOpts {
  *           scheduler other tasks will be impeded or even blocked indefinitely.
  */
 pub struct TaskOpts {
-    linked: bool,
-    supervised: bool,
-    watched: bool,
-    indestructible: bool,
-    notify_chan: Option<Chan<TaskResult>>,
+    priv linked: bool,
+    priv supervised: bool,
+    priv watched: bool,
+    priv indestructible: bool,
+    priv notify_chan: Option<Chan<TaskResult>>,
     name: Option<SendStr>,
     sched: SchedOpts,
     stack_size: Option<uint>
@@ -170,9 +170,9 @@ pub struct TaskOpts {
 // FIXME (#3724): Replace the 'consumed' bit with move mode on self
 pub struct TaskBuilder {
     opts: TaskOpts,
-    gen_body: Option<~fn(v: ~fn()) -> ~fn()>,
-    can_not_copy: Option<util::NonCopyable>,
-    consumed: bool,
+    priv gen_body: Option<~fn(v: ~fn()) -> ~fn()>,
+    priv can_not_copy: Option<util::NonCopyable>,
+    priv consumed: bool,
 }
 
 /**
diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs
index 7cf0f04c7e9..dec13eded39 100644
--- a/src/libstd/task/spawn.rs
+++ b/src/libstd/task/spawn.rs
@@ -308,10 +308,10 @@ fn each_ancestor(list:        &mut AncestorList,
 // One of these per task.
 pub struct Taskgroup {
     // List of tasks with whose fates this one's is intertwined.
-    tasks:      TaskGroupArc, // 'none' means the group has failed.
+    priv tasks:      TaskGroupArc, // 'none' means the group has failed.
     // Lists of tasks who will kill us if they fail, but whom we won't kill.
-    ancestors:  AncestorList,
-    notifier:   Option<AutoNotify>,
+    priv ancestors:  AncestorList,
+    priv notifier:   Option<AutoNotify>,
 }
 
 impl Drop for Taskgroup {
diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs
index 68fdfd73013..ee44bf4d996 100644
--- a/src/libstd/unstable/intrinsics.rs
+++ b/src/libstd/unstable/intrinsics.rs
@@ -49,23 +49,23 @@ pub struct TyDesc {
     align: uint,
 
     // Called on a copy of a value of type `T` *after* memcpy
-    take_glue: GlueFn,
+    priv take_glue: GlueFn,
 
     // Called when a value of type `T` is no longer needed
     drop_glue: GlueFn,
 
     // Called by drop glue when a value of type `T` can be freed
-    free_glue: GlueFn,
+    priv free_glue: GlueFn,
 
     // Called by reflection visitor to visit a value of type `T`
-    visit_glue: GlueFn,
+    priv visit_glue: GlueFn,
 
     // If T represents a box pointer (`@U` or `~U`), then
     // `borrow_offset` is the amount that the pointer must be adjusted
     // to find the payload.  This is always derivable from the type
     // `U`, but in the case of `@Trait` or `~Trait` objects, the type
     // `U` is unknown.
-    borrow_offset: uint,
+    priv borrow_offset: uint,
 
     // Name corresponding to the type
     name: &'static str
diff --git a/src/libstd/unstable/raw.rs b/src/libstd/unstable/raw.rs
index ac0e83df7ef..b5d7cc47fdc 100644
--- a/src/libstd/unstable/raw.rs
+++ b/src/libstd/unstable/raw.rs
@@ -15,7 +15,7 @@ use unstable::intrinsics::TyDesc;
 pub struct Box<T> {
     ref_count: uint,
     type_desc: *TyDesc,
-    prev: *Box<T>,
+    priv prev: *Box<T>,
     next: *Box<T>,
     data: T
 }
diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs
index 4c6ad469d8c..9d15dd031e0 100644
--- a/src/libstd/unstable/sync.rs
+++ b/src/libstd/unstable/sync.rs
@@ -304,7 +304,7 @@ pub unsafe fn atomically<U>(f: &fn() -> U) -> U {
 type rust_little_lock = *libc::c_void;
 
 pub struct LittleLock {
-    l: rust_little_lock,
+    priv l: rust_little_lock,
 }
 
 impl Drop for LittleLock {
@@ -353,7 +353,7 @@ struct ExData<T> {
  * need to block or deschedule while accessing shared state, use extra::sync::RWArc.
  */
 pub struct Exclusive<T> {
-    x: UnsafeArc<ExData<T>>
+    priv x: UnsafeArc<ExData<T>>
 }
 
 impl<T:Send> Clone for Exclusive<T> {