Merge pull request #134 from tomprince/nonblocking-note

Add a note about `OsRng` blocking in early init.
diff --git a/.travis.yml b/.travis.yml
index 2c5dbd6..73058dc 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,8 +9,10 @@
   - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
 script:
   - cargo build --verbose
+  - ([ $TRAVIS_RUST_VERSION != nightly ] || cargo build --verbose --features nightly)
   - cargo test --verbose
-  - cargo doc --no-deps
+  - ([ $TRAVIS_RUST_VERSION != nightly ] || cargo test --verbose --features nightly)
+  - ([ $TRAVIS_RUST_VERSION != nightly ] || cargo doc --no-deps --features nightly)
 after_success:
   - travis-cargo --only nightly doc-upload
 env:
diff --git a/Cargo.toml b/Cargo.toml
index b4320d0..393ec45 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,6 +12,11 @@
 Random number generators and other randomness functionality.
 """
 keywords = ["random", "rng"]
+categories = ["algorithms"]
+
+[features]
+i128_support = []
+nightly = ["i128_support"]
 
 [dependencies]
 libc = "0.2"
diff --git a/appveyor.yml b/appveyor.yml
index 4a61042..9085347 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -15,3 +15,4 @@
 
 test_script:
   - cargo test --verbose --target %TARGET%
+  - cargo test --verbose --target %TARGET% --features nightly
diff --git a/src/chacha.rs b/src/chacha.rs
index a347ec5..1acec5e 100644
--- a/src/chacha.rs
+++ b/src/chacha.rs
@@ -26,7 +26,7 @@
 ///
 /// [1]: D. J. Bernstein, [*ChaCha, a variant of
 /// Salsa20*](http://cr.yp.to/chacha.html)
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
 pub struct ChaChaRng {
     buffer:  [w32; STATE_WORDS], // Internal buffer of output
     state:   [w32; STATE_WORDS], // Initial state
diff --git a/src/distributions/exponential.rs b/src/distributions/exponential.rs
index 1be1f8d..c3c924c 100644
--- a/src/distributions/exponential.rs
+++ b/src/distributions/exponential.rs
@@ -34,7 +34,7 @@
 /// let Exp1(x) = rand::random();
 /// println!("{}", x);
 /// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 pub struct Exp1(pub f64);
 
 // This could be done via `-rng.gen::<f64>().ln()` but that is slower.
@@ -71,7 +71,7 @@
 /// let v = exp.ind_sample(&mut rand::thread_rng());
 /// println!("{} is from a Exp(2) distribution", v);
 /// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 pub struct Exp {
     /// `lambda` stored as `1/lambda`, since this is what we scale by.
     lambda_inverse: f64
diff --git a/src/distributions/gamma.rs b/src/distributions/gamma.rs
index 7ecbc03..1cff4dd 100644
--- a/src/distributions/gamma.rs
+++ b/src/distributions/gamma.rs
@@ -49,12 +49,12 @@
 /// for Generating Gamma Variables" *ACM Trans. Math. Softw.* 26, 3
 /// (September 2000),
 /// 363-372. DOI:[10.1145/358407.358414](http://doi.acm.org/10.1145/358407.358414)
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 pub struct Gamma {
     repr: GammaRepr,
 }
 
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 enum GammaRepr {
     Large(GammaLargeShape),
     One(Exp),
@@ -75,7 +75,7 @@
 ///
 /// See `Gamma` for sampling from a Gamma distribution with general
 /// shape parameters.
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 struct GammaSmallShape {
     inv_shape: f64,
     large_shape: GammaLargeShape
@@ -85,7 +85,7 @@
 ///
 /// See `Gamma` for sampling from a Gamma distribution with general
 /// shape parameters.
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 struct GammaLargeShape {
     scale: f64,
     c: f64,
@@ -195,12 +195,12 @@
 /// let v = chi.ind_sample(&mut rand::thread_rng());
 /// println!("{} is from a χ²(11) distribution", v)
 /// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 pub struct ChiSquared {
     repr: ChiSquaredRepr,
 }
 
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 enum ChiSquaredRepr {
     // k == 1, Gamma(alpha, ..) is particularly slow for alpha < 1,
     // e.g. when alpha = 1/2 as it would be for this case, so special-
@@ -253,7 +253,7 @@
 /// let v = f.ind_sample(&mut rand::thread_rng());
 /// println!("{} is from an F(2, 32) distribution", v)
 /// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 pub struct FisherF {
     numer: ChiSquared,
     denom: ChiSquared,
@@ -297,7 +297,7 @@
 /// let v = t.ind_sample(&mut rand::thread_rng());
 /// println!("{} is from a t(11) distribution", v)
 /// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 pub struct StudentT {
     chi: ChiSquared,
     dof: f64
diff --git a/src/distributions/mod.rs b/src/distributions/mod.rs
index 50f9d95..f128b75 100644
--- a/src/distributions/mod.rs
+++ b/src/distributions/mod.rs
@@ -53,6 +53,7 @@
 
 /// A wrapper for generating types that implement `Rand` via the
 /// `Sample` & `IndependentSample` traits.
+#[derive(Debug)]
 pub struct RandSample<Sup> {
     _marker: marker::PhantomData<fn() -> Sup>,
 }
@@ -79,8 +80,7 @@
 }
 
 /// A value with a particular weight for use with `WeightedChoice`.
-#[derive(Copy)]
-#[derive(Clone)]
+#[derive(Copy, Clone, Debug)]
 pub struct Weighted<T> {
     /// The numerical weight of this item
     pub weight: u32,
@@ -113,6 +113,7 @@
 ///      println!("{}", wc.ind_sample(&mut rng));
 /// }
 /// ```
+#[derive(Debug)]
 pub struct WeightedChoice<'a, T:'a> {
     items: &'a mut [Weighted<T>],
     weight_range: Range<u32>
diff --git a/src/distributions/normal.rs b/src/distributions/normal.rs
index 42872fa..280613d 100644
--- a/src/distributions/normal.rs
+++ b/src/distributions/normal.rs
@@ -33,7 +33,7 @@
 /// let StandardNormal(x) = rand::random();
 /// println!("{}", x);
 /// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 pub struct StandardNormal(pub f64);
 
 impl Rand for StandardNormal {
@@ -88,7 +88,7 @@
 /// let v = normal.ind_sample(&mut rand::thread_rng());
 /// println!("{} is from a N(2, 9) distribution", v)
 /// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 pub struct Normal {
     mean: f64,
     std_dev: f64,
@@ -136,7 +136,7 @@
 /// let v = log_normal.ind_sample(&mut rand::thread_rng());
 /// println!("{} is from an ln N(2, 9) distribution", v)
 /// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 pub struct LogNormal {
     norm: Normal
 }
diff --git a/src/distributions/range.rs b/src/distributions/range.rs
index 3a3f3e7..7206941 100644
--- a/src/distributions/range.rs
+++ b/src/distributions/range.rs
@@ -46,7 +46,7 @@
 ///     println!("{}", sum);
 /// }
 /// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 pub struct Range<X> {
     low: X,
     range: X,
diff --git a/src/isaac.rs b/src/isaac.rs
index 42de352..b70a8e6 100644
--- a/src/isaac.rs
+++ b/src/isaac.rs
@@ -15,6 +15,7 @@
 use std::slice;
 use std::iter::repeat;
 use std::num::Wrapping as w;
+use std::fmt;
 
 use {Rng, SeedableRng, Rand, w32, w64};
 
@@ -260,6 +261,12 @@
     }
 }
 
+impl fmt::Debug for IsaacRng {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "IsaacRng {{}}")
+    }
+}
+
 const RAND_SIZE_64_LEN: usize = 8;
 const RAND_SIZE_64: usize = 1 << RAND_SIZE_64_LEN;
 
@@ -503,6 +510,11 @@
     }
 }
 
+impl fmt::Debug for Isaac64Rng {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "Isaac64Rng {{}}")
+    }
+}
 
 #[cfg(test)]
 mod test {
diff --git a/src/lib.rs b/src/lib.rs
index 472e4ec..fd0fbf0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -241,8 +241,13 @@
        html_favicon_url = "https://www.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/rand/")]
 
+#![deny(missing_debug_implementations)]
+
+#![cfg_attr(feature = "i128_support", feature(i128_type))]
+
 #[cfg(test)] #[macro_use] extern crate log;
 
+
 use std::cell::RefCell;
 use std::marker;
 use std::mem;
@@ -289,7 +294,7 @@
     ///
     /// This rarely needs to be called directly, prefer `r.gen()` to
     /// `r.next_u32()`.
-    // FIXME #7771: Should be implemented in terms of next_u64
+    // FIXME #rust-lang/rfcs#628: Should be implemented in terms of next_u64
     fn next_u32(&mut self) -> u32;
 
     /// Return the next random u64.
@@ -604,6 +609,7 @@
 ///
 /// [`gen_iter`]: trait.Rng.html#method.gen_iter
 /// [`Rng`]: trait.Rng.html
+#[derive(Debug)]
 pub struct Generator<'a, T, R:'a> {
     rng: &'a mut R,
     _marker: marker::PhantomData<fn() -> T>,
@@ -623,6 +629,7 @@
 ///
 /// [`gen_ascii_chars`]: trait.Rng.html#method.gen_ascii_chars
 /// [`Rng`]: trait.Rng.html
+#[derive(Debug)]
 pub struct AsciiGenerator<'a, R:'a> {
     rng: &'a mut R,
 }
@@ -682,7 +689,7 @@
 /// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
 /// Statistical Software*. Vol. 8 (Issue 14).
 #[allow(missing_copy_implementations)]
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 pub struct XorShiftRng {
     x: w32,
     y: w32,
@@ -772,6 +779,7 @@
 /// let Open01(val) = random::<Open01<f32>>();
 /// println!("f32 from (0,1): {}", val);
 /// ```
+#[derive(Debug)]
 pub struct Open01<F>(pub F);
 
 /// A wrapper for generating floating point numbers uniformly in the
@@ -789,11 +797,12 @@
 /// let Closed01(val) = random::<Closed01<f32>>();
 /// println!("f32 from [0,1]: {}", val);
 /// ```
+#[derive(Debug)]
 pub struct Closed01<F>(pub F);
 
 /// The standard RNG. This is designed to be efficient on the current
 /// platform.
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
 pub struct StdRng {
     rng: IsaacWordRng,
 }
@@ -856,6 +865,7 @@
 }
 
 /// Controls how the thread-local RNG is reseeded.
+#[derive(Debug)]
 struct ThreadRngReseeder;
 
 impl reseeding::Reseeder<StdRng> for ThreadRngReseeder {
@@ -870,7 +880,7 @@
 type ThreadRngInner = reseeding::ReseedingRng<StdRng, ThreadRngReseeder>;
 
 /// The thread-local RNG.
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 pub struct ThreadRng {
     rng: Rc<RefCell<ThreadRngInner>>,
 }
diff --git a/src/os.rs b/src/os.rs
index 8ee3606..970cfd7 100644
--- a/src/os.rs
+++ b/src/os.rs
@@ -11,7 +11,7 @@
 //! Interfaces to the operating system provided random number
 //! generators.
 
-use std::{io, mem};
+use std::{io, mem, fmt};
 use Rng;
 
 /// A random number generator that retrieves randomness straight from
@@ -47,6 +47,12 @@
     fn fill_bytes(&mut self, v: &mut [u8]) { self.0.fill_bytes(v) }
 }
 
+impl fmt::Debug for OsRng {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "OsRng {{}}")
+    }
+}
+
 fn next_u32(mut fill_buf: &mut FnMut(&mut [u8])) -> u32 {
     let mut buf: [u8; 4] = [0; 4];
     fill_buf(&mut buf);
@@ -218,6 +224,7 @@
     use Rng;
     use self::libc::{c_int, size_t};
 
+    #[derive(Debug)]
     pub struct OsRng;
 
     enum SecRandom {}
@@ -264,6 +271,7 @@
 
     use super::{next_u32, next_u64};
 
+    #[derive(Debug)]
     pub struct OsRng;
 
     impl OsRng {
@@ -307,6 +315,7 @@
 
     use super::{next_u32, next_u64};
 
+    #[derive(Debug)]
     pub struct OsRng;
 
     impl OsRng {
@@ -344,6 +353,7 @@
     use Rng;
     use read::ReadRng;
 
+    #[derive(Debug)]
     pub struct OsRng {
         inner: ReadRng<File>,
     }
@@ -401,6 +411,7 @@
         fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) -> BOOL;
     }
 
+    #[derive(Debug)]
     pub struct OsRng {
         hcryptprov: HCRYPTPROV
     }
@@ -468,6 +479,7 @@
 
     use super::{next_u32, next_u64};
 
+    #[derive(Debug)]
     pub struct OsRng(extern fn(dest: *mut libc::c_void,
                                bytes: libc::size_t,
                                read: *mut libc::size_t) -> libc::c_int);
diff --git a/src/rand_impls.rs b/src/rand_impls.rs
index 5a7e3de..a9cf5d9 100644
--- a/src/rand_impls.rs
+++ b/src/rand_impls.rs
@@ -54,6 +54,14 @@
     }
 }
 
+#[cfg(feature = "i128_support")]
+impl Rand for i128 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> i128 {
+        rng.gen::<u128>() as i128
+    }
+}
+
 impl Rand for usize {
     #[inline]
     fn rand<R: Rng>(rng: &mut R) -> usize {
@@ -93,6 +101,15 @@
     }
 }
 
+#[cfg(feature = "i128_support")]
+impl Rand for u128 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> u128 {
+        ((rng.next_u64() as u128) << 64) | (rng.next_u64() as u128)
+    }
+}
+
+
 macro_rules! float_impls {
     ($mod_name:ident, $ty:ty, $mantissa_bits:expr, $method_name:ident) => {
         mod $mod_name {
diff --git a/src/read.rs b/src/read.rs
index 9e420bc..c7351b7 100644
--- a/src/read.rs
+++ b/src/read.rs
@@ -30,6 +30,7 @@
 /// let mut rng = read::ReadRng::new(&data[..]);
 /// println!("{:x}", rng.gen::<u32>());
 /// ```
+#[derive(Debug)]
 pub struct ReadRng<R> {
     reader: R
 }
diff --git a/src/reseeding.rs b/src/reseeding.rs
index 39e464d..2fba9f4 100644
--- a/src/reseeding.rs
+++ b/src/reseeding.rs
@@ -21,6 +21,7 @@
 
 /// A wrapper around any RNG which reseeds the underlying RNG after it
 /// has generated a certain number of random bytes.
+#[derive(Debug)]
 pub struct ReseedingRng<R, Rsdr> {
     rng: R,
     generation_threshold: u64,
@@ -132,7 +133,7 @@
 
 /// Reseed an RNG using a `Default` instance. This reseeds by
 /// replacing the RNG with the result of a `Default::default` call.
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 pub struct ReseedWithDefault;
 
 impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {