Merge pull request #823 from dhardy/master

Bump versions + Edition 2018 + Pcg64
diff --git a/.travis.yml b/.travis.yml
index 4baf810..c89a989 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -268,7 +268,7 @@
 
 script:
   - cargo test --tests --no-default-features
-  - cargo test --no-default-features --features getrandom
+  - cargo test --tests --no-default-features --features getrandom
   # TODO: add simd_support feature:
   - cargo test --features=serde1,log
   - cargo test --examples
diff --git a/Cargo.toml b/Cargo.toml
index 8ce6f3c..46d9d96 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "rand"
-version = "0.7.0-pre.0"
+version = "0.7.0-pre.1"
 authors = ["The Rand Project Developers", "The Rust Project Developers"]
 license = "MIT/Apache-2.0"
 readme = "README.md"
@@ -55,7 +55,7 @@
 
 [dependencies]
 rand_core = { path = "rand_core", version = "0.5" }
-rand_pcg = { path = "rand_pcg", version = "0.1", optional = true }
+rand_pcg = { path = "rand_pcg", version = "0.2", optional = true }
 # Do not depend on 'getrandom_package' directly; use the 'getrandom' feature!
 getrandom_package = { version = "0.1.1", package = "getrandom", optional = true }
 log = { version = "0.4", optional = true }
@@ -76,42 +76,18 @@
 [target.'cfg(not(target_os = "emscripten"))'.dependencies]
 rand_chacha = { path = "rand_chacha", version = "0.2" }
 [target.'cfg(target_os = "emscripten")'.dependencies]
-rand_hc = { path = "rand_hc", version = "0.1" }
+rand_hc = { path = "rand_hc", version = "0.2" }
 
 [dev-dependencies]
-rand_pcg = { path = "rand_pcg", version = "0.1" }
+rand_pcg = { path = "rand_pcg", version = "0.2" }
 # Only for benches:
-rand_hc = { path = "rand_hc", version = "0.1" }
-rand_xoshiro = { path = "rand_xoshiro", version = "0.2" }
-rand_isaac = { path = "rand_isaac", version = "0.1" }
-rand_xorshift = { path = "rand_xorshift", version = "0.1" }
-rand_distr = { path = "rand_distr", version = "0.2" }
+rand_hc = { path = "rand_hc", version = "0.2" }
+rand_xoshiro = { path = "rand_xoshiro", version = "0.3" }
+rand_isaac = { path = "rand_isaac", version = "0.2" }
+rand_xorshift = { path = "rand_xorshift", version = "0.2" }
 
 [build-dependencies]
 autocfg = "0.1"
 
-[[bench]]
-name = "distributions"
-path = "benches/distributions.rs"
-required-features = ["small_rng"]
-
-[[bench]]
-name = "generators"
-path = "benches/generators.rs"
-required-features = ["small_rng"]
-
-[[bench]]
-name = "misc"
-path = "benches/misc.rs"
-required-features = ["small_rng"]
-
-[[bench]]
-name = "seq"
-path = "benches/seq.rs"
-required-features = ["small_rng"]
-
 [package.metadata.docs.rs]
 all-features = true
-
-[patch.crates-io]
-rand_core = { path = "rand_core", version = "0.5" }
diff --git a/benches/generators.rs b/benches/generators.rs
index 2def704..0e83401 100644
--- a/benches/generators.rs
+++ b/benches/generators.rs
@@ -30,7 +30,7 @@
 use rand_isaac::{IsaacRng, Isaac64Rng};
 use rand_chacha::{ChaCha20Core, ChaCha8Rng, ChaCha12Rng, ChaCha20Rng};
 use rand_hc::{Hc128Rng};
-use rand_pcg::{Lcg64Xsh32, Mcg128Xsl64};
+use rand_pcg::{Pcg32, Pcg64, Pcg64Mcg};
 use rand_xorshift::XorShiftRng;
 use rand_xoshiro::{Xoshiro256StarStar, Xoshiro256Plus, Xoshiro128StarStar,
     Xoshiro128Plus, Xoroshiro128StarStar, Xoroshiro128Plus, SplitMix64,
@@ -63,8 +63,9 @@
 gen_bytes!(gen_bytes_xoroshiro64starstar, Xoroshiro64StarStar::from_entropy());
 gen_bytes!(gen_bytes_xoroshiro64star, Xoroshiro64Star::from_entropy());
 gen_bytes!(gen_bytes_splitmix64, SplitMix64::from_entropy());
-gen_bytes!(gen_bytes_lcg64_xsh32, Lcg64Xsh32::from_entropy());
-gen_bytes!(gen_bytes_mcg128_xsh64, Mcg128Xsl64::from_entropy());
+gen_bytes!(gen_bytes_pcg32, Pcg32::from_entropy());
+gen_bytes!(gen_bytes_pcg64, Pcg64::from_entropy());
+gen_bytes!(gen_bytes_pcg64mcg, Pcg64Mcg::from_entropy());
 gen_bytes!(gen_bytes_chacha8, ChaCha8Rng::from_entropy());
 gen_bytes!(gen_bytes_chacha12, ChaCha12Rng::from_entropy());
 gen_bytes!(gen_bytes_chacha20, ChaCha20Rng::from_entropy());
@@ -72,6 +73,7 @@
 gen_bytes!(gen_bytes_isaac, IsaacRng::from_entropy());
 gen_bytes!(gen_bytes_isaac64, Isaac64Rng::from_entropy());
 gen_bytes!(gen_bytes_std, StdRng::from_entropy());
+#[cfg(feature="small_rng")]
 gen_bytes!(gen_bytes_small, SmallRng::from_entropy());
 gen_bytes!(gen_bytes_os, OsRng);
 
@@ -102,8 +104,9 @@
 gen_uint!(gen_u32_xoroshiro64starstar, u32, Xoroshiro64StarStar::from_entropy());
 gen_uint!(gen_u32_xoroshiro64star, u32, Xoroshiro64Star::from_entropy());
 gen_uint!(gen_u32_splitmix64, u32, SplitMix64::from_entropy());
-gen_uint!(gen_u32_lcg64_xsh32, u32, Lcg64Xsh32::from_entropy());
-gen_uint!(gen_u32_mcg128_xsh64, u32, Mcg128Xsl64::from_entropy());
+gen_uint!(gen_u32_pcg32, u32, Pcg32::from_entropy());
+gen_uint!(gen_u32_pcg64, u32, Pcg64::from_entropy());
+gen_uint!(gen_u32_pcg64mcg, u32, Pcg64Mcg::from_entropy());
 gen_uint!(gen_u32_chacha8, u32, ChaCha8Rng::from_entropy());
 gen_uint!(gen_u32_chacha12, u32, ChaCha12Rng::from_entropy());
 gen_uint!(gen_u32_chacha20, u32, ChaCha20Rng::from_entropy());
@@ -111,6 +114,7 @@
 gen_uint!(gen_u32_isaac, u32, IsaacRng::from_entropy());
 gen_uint!(gen_u32_isaac64, u32, Isaac64Rng::from_entropy());
 gen_uint!(gen_u32_std, u32, StdRng::from_entropy());
+#[cfg(feature="small_rng")]
 gen_uint!(gen_u32_small, u32, SmallRng::from_entropy());
 gen_uint!(gen_u32_os, u32, OsRng);
 
@@ -124,8 +128,9 @@
 gen_uint!(gen_u64_xoroshiro64starstar, u64, Xoroshiro64StarStar::from_entropy());
 gen_uint!(gen_u64_xoroshiro64star, u64, Xoroshiro64Star::from_entropy());
 gen_uint!(gen_u64_splitmix64, u64, SplitMix64::from_entropy());
-gen_uint!(gen_u64_lcg64_xsh32, u64, Lcg64Xsh32::from_entropy());
-gen_uint!(gen_u64_mcg128_xsh64, u64, Mcg128Xsl64::from_entropy());
+gen_uint!(gen_u64_pcg32, u64, Pcg32::from_entropy());
+gen_uint!(gen_u64_pcg64, u64, Pcg64::from_entropy());
+gen_uint!(gen_u64_pcg64mcg, u64, Pcg64Mcg::from_entropy());
 gen_uint!(gen_u64_chacha8, u64, ChaCha8Rng::from_entropy());
 gen_uint!(gen_u64_chacha12, u64, ChaCha12Rng::from_entropy());
 gen_uint!(gen_u64_chacha20, u64, ChaCha20Rng::from_entropy());
@@ -133,6 +138,7 @@
 gen_uint!(gen_u64_isaac, u64, IsaacRng::from_entropy());
 gen_uint!(gen_u64_isaac64, u64, Isaac64Rng::from_entropy());
 gen_uint!(gen_u64_std, u64, StdRng::from_entropy());
+#[cfg(feature="small_rng")]
 gen_uint!(gen_u64_small, u64, SmallRng::from_entropy());
 gen_uint!(gen_u64_os, u64, OsRng);
 
@@ -159,8 +165,9 @@
 init_gen!(init_xoroshiro64starstar, Xoroshiro64StarStar);
 init_gen!(init_xoroshiro64star, Xoroshiro64Star);
 init_gen!(init_splitmix64, SplitMix64);
-init_gen!(init_lcg64_xsh32, Lcg64Xsh32);
-init_gen!(init_mcg128_xsh64, Mcg128Xsl64);
+init_gen!(init_pcg32, Pcg32);
+init_gen!(init_pcg64, Pcg64);
+init_gen!(init_pcg64mcg, Pcg64Mcg);
 init_gen!(init_hc128, Hc128Rng);
 init_gen!(init_isaac, IsaacRng);
 init_gen!(init_isaac64, Isaac64Rng);
diff --git a/benches/misc.rs b/benches/misc.rs
index 2b6c9ff..99e43b9 100644
--- a/benches/misc.rs
+++ b/benches/misc.rs
@@ -10,6 +10,7 @@
 
 extern crate test;
 extern crate rand;
+extern crate rand_pcg;
 
 const RAND_BENCH_N: u64 = 1000;
 
@@ -17,10 +18,11 @@
 
 use rand::prelude::*;
 use rand::distributions::{Distribution, Standard, Bernoulli};
+use rand_pcg::{Pcg32, Pcg64Mcg};
 
 #[bench]
 fn misc_gen_bool_const(b: &mut Bencher) {
-    let mut rng = StdRng::from_rng(&mut thread_rng()).unwrap();
+    let mut rng = Pcg32::from_rng(&mut thread_rng()).unwrap();
     b.iter(|| {
         let mut accum = true;
         for _ in 0..::RAND_BENCH_N {
@@ -32,7 +34,7 @@
 
 #[bench]
 fn misc_gen_bool_var(b: &mut Bencher) {
-    let mut rng = StdRng::from_rng(&mut thread_rng()).unwrap();
+    let mut rng = Pcg32::from_rng(&mut thread_rng()).unwrap();
     b.iter(|| {
         let mut accum = true;
         let mut p = 0.18;
@@ -46,7 +48,7 @@
 
 #[bench]
 fn misc_gen_ratio_const(b: &mut Bencher) {
-    let mut rng = StdRng::from_rng(&mut thread_rng()).unwrap();
+    let mut rng = Pcg32::from_rng(&mut thread_rng()).unwrap();
     b.iter(|| {
         let mut accum = true;
         for _ in 0..::RAND_BENCH_N {
@@ -58,7 +60,7 @@
 
 #[bench]
 fn misc_gen_ratio_var(b: &mut Bencher) {
-    let mut rng = StdRng::from_rng(&mut thread_rng()).unwrap();
+    let mut rng = Pcg32::from_rng(&mut thread_rng()).unwrap();
     b.iter(|| {
         let mut accum = true;
         for i in 2..(::RAND_BENCH_N as u32 + 2) {
@@ -70,7 +72,7 @@
 
 #[bench]
 fn misc_bernoulli_const(b: &mut Bencher) {
-    let mut rng = StdRng::from_rng(&mut thread_rng()).unwrap();
+    let mut rng = Pcg32::from_rng(&mut thread_rng()).unwrap();
     b.iter(|| {
         let d = rand::distributions::Bernoulli::new(0.18).unwrap();
         let mut accum = true;
@@ -83,7 +85,7 @@
 
 #[bench]
 fn misc_bernoulli_var(b: &mut Bencher) {
-    let mut rng = StdRng::from_rng(&mut thread_rng()).unwrap();
+    let mut rng = Pcg32::from_rng(&mut thread_rng()).unwrap();
     b.iter(|| {
         let mut accum = true;
         let mut p = 0.18;
@@ -99,7 +101,7 @@
 #[bench]
 fn gen_1k_iter_repeat(b: &mut Bencher) {
     use std::iter;
-    let mut rng = SmallRng::from_rng(&mut thread_rng()).unwrap();
+    let mut rng = Pcg64Mcg::from_rng(&mut thread_rng()).unwrap();
     b.iter(|| {
         let v: Vec<u64> = iter::repeat(()).map(|()| rng.gen()).take(128).collect();
         v
@@ -109,7 +111,7 @@
 
 #[bench]
 fn gen_1k_sample_iter(b: &mut Bencher) {
-    let mut rng = SmallRng::from_rng(&mut thread_rng()).unwrap();
+    let mut rng = Pcg64Mcg::from_rng(&mut thread_rng()).unwrap();
     b.iter(|| {
         let v: Vec<u64> = Standard.sample_iter(&mut rng).take(128).collect();
         v
@@ -119,7 +121,7 @@
 
 #[bench]
 fn gen_1k_gen_array(b: &mut Bencher) {
-    let mut rng = SmallRng::from_rng(&mut thread_rng()).unwrap();
+    let mut rng = Pcg64Mcg::from_rng(&mut thread_rng()).unwrap();
     b.iter(|| {
         // max supported array length is 32!
         let v: [[u64; 32]; 4] = rng.gen();
@@ -130,7 +132,7 @@
 
 #[bench]
 fn gen_1k_fill(b: &mut Bencher) {
-    let mut rng = SmallRng::from_rng(&mut thread_rng()).unwrap();
+    let mut rng = Pcg64Mcg::from_rng(&mut thread_rng()).unwrap();
     let mut buf = [0u64; 128];
     b.iter(|| {
         rng.fill(&mut buf[..]);
diff --git a/benches/seq.rs b/benches/seq.rs
index 0ca3398..e426ffb 100644
--- a/benches/seq.rs
+++ b/benches/seq.rs
@@ -11,6 +11,7 @@
 
 extern crate test;
 extern crate rand;
+extern crate rand_pcg;
 
 use test::Bencher;
 
@@ -18,6 +19,10 @@
 use rand::seq::*;
 use std::mem::size_of;
 
+// We force use of 32-bit RNG since seq code is optimised for use with 32-bit
+// generators on all platforms.
+use rand_pcg::Pcg32 as SmallRng;
+
 const RAND_BENCH_N: u64 = 1000;
 
 #[bench]
diff --git a/rand_distr/Cargo.toml b/rand_distr/Cargo.toml
index 568854c..874adbb 100644
--- a/rand_distr/Cargo.toml
+++ b/rand_distr/Cargo.toml
@@ -22,6 +22,6 @@
 rand = { path = "..", version = ">=0.5, <=0.7.0-pre.9" }
 
 [dev-dependencies]
-rand_pcg = { version = "0.1", path = "../rand_pcg" }
+rand_pcg = { version = "0.2", path = "../rand_pcg" }
 # Histogram implementation for testing uniformity
 average = "0.9.2"
diff --git a/benches/distributions.rs b/rand_distr/benches/distributions.rs
similarity index 82%
rename from benches/distributions.rs
rename to rand_distr/benches/distributions.rs
index af6ea00..893ac47 100644
--- a/benches/distributions.rs
+++ b/rand_distr/benches/distributions.rs
@@ -9,13 +9,10 @@
 #![feature(test)]
 
 extern crate test;
-extern crate rand;
-extern crate rand_distr;
 
 const RAND_BENCH_N: u64 = 1000;
 
 use std::mem::size_of;
-#[cfg(rustc_1_28)]
 use std::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128};
 use test::Bencher;
 use std::time::Duration;
@@ -23,22 +20,25 @@
 use rand::prelude::*;
 use rand_distr::{*, weighted::WeightedIndex};
 
+// At this time, distributions are optimised for 64-bit platforms.
+use rand_pcg::Pcg64Mcg;
+
 macro_rules! distr_int {
     ($fnn:ident, $ty:ty, $distr:expr) => {
         #[bench]
         fn $fnn(b: &mut Bencher) {
-            let mut rng = SmallRng::from_entropy();
+            let mut rng = Pcg64Mcg::from_entropy();
             let distr = $distr;
 
             b.iter(|| {
                 let mut accum = 0 as $ty;
-                for _ in 0..::RAND_BENCH_N {
+                for _ in 0..RAND_BENCH_N {
                     let x: $ty = distr.sample(&mut rng);
                     accum = accum.wrapping_add(x);
                 }
                 accum
             });
-            b.bytes = size_of::<$ty>() as u64 * ::RAND_BENCH_N;
+            b.bytes = size_of::<$ty>() as u64 * RAND_BENCH_N;
         }
     }
 }
@@ -47,18 +47,18 @@
     ($fnn:ident, $tynz:ty, $ty:ty, $distr:expr) => {
         #[bench]
         fn $fnn(b: &mut Bencher) {
-            let mut rng = SmallRng::from_entropy();
+            let mut rng = Pcg64Mcg::from_entropy();
             let distr = $distr;
 
             b.iter(|| {
                 let mut accum = 0 as $ty;
-                for _ in 0..::RAND_BENCH_N {
+                for _ in 0..RAND_BENCH_N {
                     let x: $tynz = distr.sample(&mut rng);
                     accum = accum.wrapping_add(x.get());
                 }
                 accum
             });
-            b.bytes = size_of::<$ty>() as u64 * ::RAND_BENCH_N;
+            b.bytes = size_of::<$ty>() as u64 * RAND_BENCH_N;
         }
     }
 }
@@ -67,18 +67,18 @@
     ($fnn:ident, $ty:ty, $distr:expr) => {
         #[bench]
         fn $fnn(b: &mut Bencher) {
-            let mut rng = SmallRng::from_entropy();
+            let mut rng = Pcg64Mcg::from_entropy();
             let distr = $distr;
 
             b.iter(|| {
                 let mut accum = 0.0;
-                for _ in 0..::RAND_BENCH_N {
+                for _ in 0..RAND_BENCH_N {
                     let x: $ty = distr.sample(&mut rng);
                     accum += x;
                 }
                 accum
             });
-            b.bytes = size_of::<$ty>() as u64 * ::RAND_BENCH_N;
+            b.bytes = size_of::<$ty>() as u64 * RAND_BENCH_N;
         }
     }
 }
@@ -87,18 +87,18 @@
     ($fnn:ident, $distr:expr) => {
         #[bench]
         fn $fnn(b: &mut Bencher) {
-            let mut rng = SmallRng::from_entropy();
+            let mut rng = Pcg64Mcg::from_entropy();
             let distr = $distr;
 
             b.iter(|| {
                 let mut accum = Duration::new(0, 0);
-                for _ in 0..::RAND_BENCH_N {
+                for _ in 0..RAND_BENCH_N {
                     let x: Duration = distr.sample(&mut rng);
                     accum = accum.checked_add(x).unwrap_or(Duration::new(u64::max_value(), 999_999_999));
                 }
                 accum
             });
-            b.bytes = size_of::<Duration>() as u64 * ::RAND_BENCH_N;
+            b.bytes = size_of::<Duration>() as u64 * RAND_BENCH_N;
         }
     }
 }
@@ -107,18 +107,18 @@
     ($fnn:ident, $ty:ty, $distr:expr) => {
         #[bench]
         fn $fnn(b: &mut Bencher) {
-            let mut rng = SmallRng::from_entropy();
+            let mut rng = Pcg64Mcg::from_entropy();
             let distr = $distr;
 
             b.iter(|| {
                 let mut accum = 0u32;
-                for _ in 0..::RAND_BENCH_N {
+                for _ in 0..RAND_BENCH_N {
                     let x: $ty = distr.sample(&mut rng);
                     accum = accum.wrapping_add(x as u32);
                 }
                 accum
             });
-            b.bytes = size_of::<$ty>() as u64 * ::RAND_BENCH_N;
+            b.bytes = size_of::<$ty>() as u64 * RAND_BENCH_N;
         }
     }
 }
@@ -127,18 +127,18 @@
     ($fnn:ident, $ty:ty, $distr:expr) => {
         #[bench]
         fn $fnn(b: &mut Bencher) {
-            let mut rng = SmallRng::from_entropy();
+            let mut rng = Pcg64Mcg::from_entropy();
             let distr = $distr;
 
             b.iter(|| {
                 let mut accum = 0u32;
-                for _ in 0..::RAND_BENCH_N {
+                for _ in 0..RAND_BENCH_N {
                     let x: $ty = distr.sample(&mut rng);
                     accum = accum.wrapping_add(x[0] as u32);
                 }
                 accum
             });
-            b.bytes = size_of::<$ty>() as u64 * ::RAND_BENCH_N;
+            b.bytes = size_of::<$ty>() as u64 * RAND_BENCH_N;
         }
     }
 }
@@ -183,11 +183,11 @@
 distr_int!(distr_standard_i32, i32, Standard);
 distr_int!(distr_standard_i64, i64, Standard);
 distr_int!(distr_standard_i128, i128, Standard);
-#[cfg(rustc_1_28)] distr_nz_int!(distr_standard_nz8, NonZeroU8, u8, Standard);
-#[cfg(rustc_1_28)] distr_nz_int!(distr_standard_nz16, NonZeroU16, u16, Standard);
-#[cfg(rustc_1_28)] distr_nz_int!(distr_standard_nz32, NonZeroU32, u32, Standard);
-#[cfg(rustc_1_28)] distr_nz_int!(distr_standard_nz64, NonZeroU64, u64, Standard);
-#[cfg(rustc_1_28)] distr_nz_int!(distr_standard_nz128, NonZeroU128, u128, Standard);
+distr_nz_int!(distr_standard_nz8, NonZeroU8, u8, Standard);
+distr_nz_int!(distr_standard_nz16, NonZeroU16, u16, Standard);
+distr_nz_int!(distr_standard_nz32, NonZeroU32, u32, Standard);
+distr_nz_int!(distr_standard_nz64, NonZeroU64, u64, Standard);
+distr_nz_int!(distr_standard_nz128, NonZeroU128, u128, Standard);
 
 distr!(distr_standard_bool, bool, Standard);
 distr!(distr_standard_alphanumeric, char, Alphanumeric);
@@ -231,19 +231,19 @@
     ($fnn:ident, $ty:ident, $low:expr, $high:expr) => {
         #[bench]
         fn $fnn(b: &mut Bencher) {
-            let mut rng = SmallRng::from_entropy();
+            let mut rng = Pcg64Mcg::from_entropy();
 
             b.iter(|| {
                 let mut high = $high;
                 let mut accum: $ty = 0;
-                for _ in 0..::RAND_BENCH_N {
+                for _ in 0..RAND_BENCH_N {
                     accum = accum.wrapping_add(rng.gen_range($low, high));
                     // force recalculation of range each time
                     high = high.wrapping_add(1) & std::$ty::MAX;
                 }
                 accum
             });
-            b.bytes = size_of::<$ty>() as u64 * ::RAND_BENCH_N;
+            b.bytes = size_of::<$ty>() as u64 * RAND_BENCH_N;
         }
     }
 }
@@ -259,13 +259,13 @@
     ($fnn:ident, $ty:ident, $low:expr, $high:expr) => {
         #[bench]
         fn $fnn(b: &mut Bencher) {
-            let mut rng = SmallRng::from_entropy();
+            let mut rng = Pcg64Mcg::from_entropy();
 
             b.iter(|| {
                 let mut high = $high;
                 let mut low = $low;
                 let mut accum: $ty = 0.0;
-                for _ in 0..::RAND_BENCH_N {
+                for _ in 0..RAND_BENCH_N {
                     accum += rng.gen_range(low, high);
                     // force recalculation of range each time
                     low += 0.9;
@@ -273,7 +273,7 @@
                 }
                 accum
             });
-            b.bytes = size_of::<$ty>() as u64 * ::RAND_BENCH_N;
+            b.bytes = size_of::<$ty>() as u64 * RAND_BENCH_N;
         }
     }
 }
@@ -283,25 +283,25 @@
 
 #[bench]
 fn dist_iter(b: &mut Bencher) {
-    let mut rng = SmallRng::from_entropy();
+    let mut rng = Pcg64Mcg::from_entropy();
     let distr = Normal::new(-2.71828, 3.14159).unwrap();
     let mut iter = distr.sample_iter(&mut rng);
 
     b.iter(|| {
         let mut accum = 0.0;
-        for _ in 0..::RAND_BENCH_N {
+        for _ in 0..RAND_BENCH_N {
             accum += iter.next().unwrap();
         }
         accum
     });
-    b.bytes = size_of::<f64>() as u64 * ::RAND_BENCH_N;
+    b.bytes = size_of::<f64>() as u64 * RAND_BENCH_N;
 }
 
 macro_rules! sample_binomial {
     ($name:ident, $n:expr, $p:expr) => {
         #[bench]
         fn $name(b: &mut Bencher) {
-            let mut rng = SmallRng::from_rng(&mut thread_rng()).unwrap();
+            let mut rng = Pcg64Mcg::from_rng(&mut thread_rng()).unwrap();
             let (n, p) = ($n, $p);
             b.iter(|| {
                 let d = Binomial::new(n, p).unwrap();
diff --git a/rand_hc/CHANGELOG.md b/rand_hc/CHANGELOG.md
index 2820275..a629d7d 100644
--- a/rand_hc/CHANGELOG.md
+++ b/rand_hc/CHANGELOG.md
@@ -4,7 +4,11 @@
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
-## [0.1.1] - 2019-06-06
+## [0.2.0] - 2019-06-12
+- Bump minor crate version since rand_core bump is a breaking change
+- Switch to Edition 2018
+
+## [0.1.1] - 2019-06-06 - yanked
 - Bump `rand_core` version
 - Adjust usage of `#[inline]`
 
diff --git a/rand_hc/Cargo.toml b/rand_hc/Cargo.toml
index 7b1eb80..e062935 100644
--- a/rand_hc/Cargo.toml
+++ b/rand_hc/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "rand_hc"
-version = "0.1.1"
+version = "0.2.0"
 authors = ["The Rand Project Developers"]
 license = "MIT/Apache-2.0"
 readme = "README.md"
@@ -12,6 +12,7 @@
 """
 keywords = ["random", "rng", "hc128"]
 categories = ["algorithms", "no-std"]
+edition = "2018"
 
 [badges]
 travis-ci = { repository = "rust-random/rand" }
diff --git a/rand_hc/src/lib.rs b/rand_hc/src/lib.rs
index 10466cf..c1ae665 100644
--- a/rand_hc/src/lib.rs
+++ b/rand_hc/src/lib.rs
@@ -18,8 +18,6 @@
 
 #![no_std]
 
-pub extern crate rand_core;
-
 mod hc128;
 
 pub use hc128::{Hc128Rng, Hc128Core};
diff --git a/rand_isaac/CHANGELOG.md b/rand_isaac/CHANGELOG.md
index 95de12a..0a5591f 100644
--- a/rand_isaac/CHANGELOG.md
+++ b/rand_isaac/CHANGELOG.md
@@ -4,7 +4,11 @@
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
-## [0.1.2] - 2019-06-06
+## [0.2.0] - 2019-06-12
+- Bump minor crate version since rand_core bump is a breaking change
+- Switch to Edition 2018
+
+## [0.1.2] - 2019-06-06 - yanked
 - Bump `rand_core` version
 - Remove deprecated code
 - Adjust usage of `#[inline]`
diff --git a/rand_isaac/Cargo.toml b/rand_isaac/Cargo.toml
index 63beeec..5e3bf12 100644
--- a/rand_isaac/Cargo.toml
+++ b/rand_isaac/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "rand_isaac"
-version = "0.1.2"
+version = "0.2.0"
 authors = ["The Rand Project Developers", "The Rust Project Developers"]
 license = "MIT/Apache-2.0"
 readme = "README.md"
@@ -12,18 +12,18 @@
 """
 keywords = ["random", "rng", "isaac"]
 categories = ["algorithms", "no-std"]
+edition = "2018"
 
 [badges]
 travis-ci = { repository = "rust-random/rand" }
 appveyor = { repository = "rust-random/rand" }
 
 [features]
-serde1 = ["serde", "serde_derive", "rand_core/serde1"]
+serde1 = ["serde", "rand_core/serde1"]
 
 [dependencies]
 rand_core = { path = "../rand_core", version = "0.5" }
-serde = { version = "1", optional = true }
-serde_derive = { version = "^1.0.38", optional = true }
+serde = { version = "1", features = ["derive"], optional = true }
 
 [dev-dependencies]
 # This is for testing serde, unfortunately we can't specify feature-gated dev
diff --git a/rand_isaac/src/isaac.rs b/rand_isaac/src/isaac.rs
index f857737..2caf61a 100644
--- a/rand_isaac/src/isaac.rs
+++ b/rand_isaac/src/isaac.rs
@@ -11,9 +11,10 @@
 
 use core::{fmt, slice};
 use core::num::Wrapping as w;
+#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
 use rand_core::{RngCore, SeedableRng, Error, le};
 use rand_core::block::{BlockRngCore, BlockRng};
-use isaac_array::IsaacArray;
+use crate::isaac_array::IsaacArray;
 
 #[allow(non_camel_case_types)]
 type w32 = w<u32>;
diff --git a/rand_isaac/src/isaac64.rs b/rand_isaac/src/isaac64.rs
index 902715e..7d4b88c 100644
--- a/rand_isaac/src/isaac64.rs
+++ b/rand_isaac/src/isaac64.rs
@@ -11,9 +11,10 @@
 
 use core::{fmt, slice};
 use core::num::Wrapping as w;
+#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
 use rand_core::{RngCore, SeedableRng, Error, le};
 use rand_core::block::{BlockRngCore, BlockRng64};
-use isaac_array::IsaacArray;
+use crate::isaac_array::IsaacArray;
 
 #[allow(non_camel_case_types)]
 type w64 = w<u64>;
diff --git a/rand_isaac/src/isaac_array.rs b/rand_isaac/src/isaac_array.rs
index 0fa6147..cbe4a59 100644
--- a/rand_isaac/src/isaac_array.rs
+++ b/rand_isaac/src/isaac_array.rs
@@ -13,7 +13,7 @@
 // implement `AsRef`, `Default`, `Serialize`, `Deserialize`, or any other
 // traits for that matter.
 
-#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
+#[cfg(feature="serde")] use serde::{Serialize, Deserialize};
 
 const RAND_SIZE_LEN: usize = 8;
 const RAND_SIZE: usize = 1 << RAND_SIZE_LEN;
@@ -21,10 +21,10 @@
 
 #[derive(Copy, Clone)]
 #[allow(missing_debug_implementations)]
-#[cfg_attr(feature="serde1", derive(Serialize, Deserialize))]
+#[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
 pub struct IsaacArray<T> {
-    #[cfg_attr(feature="serde1",serde(with="isaac_array_serde"))]
-    #[cfg_attr(feature="serde1", serde(bound(
+    #[cfg_attr(feature="serde",serde(with="isaac_array_serde"))]
+    #[cfg_attr(feature="serde", serde(bound(
         serialize = "T: Serialize",
         deserialize = "T: Deserialize<'de> + Copy + Default")))]
     inner: [T; RAND_SIZE]
@@ -66,7 +66,7 @@
 }
 
 
-#[cfg(feature="serde1")]
+#[cfg(feature="serde")]
 pub(super) mod isaac_array_serde {
     const RAND_SIZE_LEN: usize = 8;
     const RAND_SIZE: usize = 1 << RAND_SIZE_LEN;
diff --git a/rand_isaac/src/lib.rs b/rand_isaac/src/lib.rs
index 285d631..84cdf21 100644
--- a/rand_isaac/src/lib.rs
+++ b/rand_isaac/src/lib.rs
@@ -16,16 +16,7 @@
 #![deny(missing_debug_implementations)]
 #![doc(test(attr(allow(unused_variables), deny(warnings))))]
 
-#![cfg_attr(not(all(feature="serde1", test)), no_std)]
-
-pub extern crate rand_core;
-
-#[cfg(feature="serde1")] extern crate serde;
-#[cfg(feature="serde1")] #[macro_use] extern crate serde_derive;
-
-// To test serialization we need bincode and the standard library
-#[cfg(all(feature="serde1", test))] extern crate bincode;
-#[cfg(all(feature="serde1", test))] extern crate std as core;
+#![cfg_attr(not(all(feature="serde", test)), no_std)]
 
 pub mod isaac;
 pub mod isaac64;
diff --git a/rand_pcg/CHANGELOG.md b/rand_pcg/CHANGELOG.md
index 6957224..a9b82fd 100644
--- a/rand_pcg/CHANGELOG.md
+++ b/rand_pcg/CHANGELOG.md
@@ -4,6 +4,11 @@
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## [0.2.0] - 2019-06-12
+- Add `Lcg128Xsl64` aka `Pcg64`
+- Bump minor crate version since rand_core bump is a breaking change
+- Switch to Edition 2018
+
 ## [0.1.2] - 2019-02-23
 - require `bincode` 1.1.2 for i128 auto-detection
 - make `bincode` a dev-dependency again #663
diff --git a/rand_pcg/Cargo.toml b/rand_pcg/Cargo.toml
index 9c3d501..e77c2c6 100644
--- a/rand_pcg/Cargo.toml
+++ b/rand_pcg/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "rand_pcg"
-version = "0.1.2"
+version = "0.2.0"
 authors = ["The Rand Project Developers"]
 license = "MIT/Apache-2.0"
 readme = "README.md"
@@ -12,19 +12,18 @@
 """
 keywords = ["random", "rng", "pcg"]
 categories = ["algorithms", "no-std"]
-build = "build.rs"
+edition = "2018"
 
 [badges]
 travis-ci = { repository = "rust-random/rand" }
 appveyor = { repository = "rust-random/rand" }
 
 [features]
-serde1 = ["serde", "serde_derive"]
+serde1 = ["serde"]
 
 [dependencies]
 rand_core = { path = "../rand_core", version = "0.5" }
-serde = { version = "1", optional = true }
-serde_derive = { version = "^1.0.38", optional = true }
+serde = { version = "1", features = ["derive"], optional = true }
 
 [dev-dependencies]
 # This is for testing serde, unfortunately we can't specify feature-gated dev
diff --git a/rand_pcg/build.rs b/rand_pcg/build.rs
deleted file mode 100644
index 06e12a4..0000000
--- a/rand_pcg/build.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-extern crate autocfg;
-
-fn main() {
-    println!("cargo:rerun-if-changed=build.rs");
-    let ac = autocfg::new();
-    ac.emit_rustc_version(1, 26);
-}
diff --git a/rand_pcg/src/lib.rs b/rand_pcg/src/lib.rs
index 9648e85..9ebfb0b 100644
--- a/rand_pcg/src/lib.rs
+++ b/rand_pcg/src/lib.rs
@@ -17,11 +17,12 @@
 //! -   `Pcg32` aka `Lcg64Xsh32`, officially known as `pcg32`, a general
 //!     purpose RNG. This is a good choice on both 32-bit and 64-bit CPUs
 //!     (for 32-bit output).
-//! -   `Pcg64Mcg` aka `Mcg128Xsl64`, officially known as `mcg_xsl_rr_128_64`,
+//! -   `Pcg64` aka `Lcg128Xsl64`, officially known as `pcg64`, a general
+//!     purpose RNG. This is a good choice on 64-bit CPUs.
+//! -   `Pcg64Mcg` aka `Mcg128Xsl64`, officially known as `pcg64_fast`,
 //!     a general purpose RNG using 128-bit multiplications. This has poor
 //!     performance on 32-bit CPUs but is a good choice on 64-bit CPUs for
-//!     both 32-bit and 64-bit output. (Note: this RNG is only available using
-//!     Rust 1.26 or later.)
+//!     both 32-bit and 64-bit output.
 //!
 //! Both of these use 16 bytes of state and 128-bit seeds, and are considered
 //! value-stable (i.e. any change affecting the output given a fixed seed would
@@ -36,13 +37,11 @@
 
 #![no_std]
 
-pub extern crate rand_core;
-
-#[cfg(feature="serde1")] extern crate serde;
-#[cfg(feature="serde1")] #[macro_use] extern crate serde_derive;
-
 mod pcg64;
-#[cfg(all(rustc_1_26, not(target_os = "emscripten")))] mod pcg128;
+#[cfg(not(target_os = "emscripten"))] mod pcg128;
 
 pub use self::pcg64::{Pcg32, Lcg64Xsh32};
-#[cfg(all(rustc_1_26, not(target_os = "emscripten")))] pub use self::pcg128::{Pcg64Mcg, Mcg128Xsl64};
+#[cfg(not(target_os = "emscripten"))] pub use self::pcg128::{
+        Pcg64, Lcg128Xsl64,
+        Pcg64Mcg, Mcg128Xsl64,
+};
diff --git a/rand_pcg/src/pcg128.rs b/rand_pcg/src/pcg128.rs
index 9aff506..eb462f7 100644
--- a/rand_pcg/src/pcg128.rs
+++ b/rand_pcg/src/pcg128.rs
@@ -16,6 +16,107 @@
 use core::fmt;
 use core::mem::transmute;
 use rand_core::{RngCore, SeedableRng, Error, le};
+#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
+
+/// A PCG random number generator (XSL RR 128/64 (LCG) variant).
+///
+/// Permuted Congruential Generator with 128-bit state, internal Linear
+/// Congruential Generator, and 64-bit output via "xorshift low (bits),
+/// random rotation" output function.
+///
+/// This is a 128-bit LCG with explicitly chosen stream with the PCG-XSL-RR
+/// output function. This combination is the standard `pcg64`.
+///
+/// Despite the name, this implementation uses 32 bytes (256 bit) space
+/// comprising 128 bits of state and 128 bits stream selector. These are both
+/// set by `SeedableRng`, using a 256-bit seed.
+#[derive(Clone)]
+#[cfg_attr(feature="serde1", derive(Serialize,Deserialize))]
+pub struct Lcg128Xsl64 {
+    state: u128,
+    increment: u128,
+}
+
+/// `Lcg128Xsl64` is also officially known as `pcg64`.
+pub type Pcg64 = Lcg128Xsl64;
+
+impl Lcg128Xsl64 {
+    /// Construct an instance compatible with PCG seed and stream.
+    ///
+    /// Note that PCG specifies default values for both parameters:
+    ///
+    /// - `state = 0xcafef00dd15ea5e5`
+    /// - `stream = 0xa02bdbf7bb3c0a7ac28fa16a64abf96`
+    pub fn new(state: u128, stream: u128) -> Self {
+        // The increment must be odd, hence we discard one bit:
+        let increment = (stream << 1) | 1;
+        Lcg128Xsl64::from_state_incr(state, increment)
+    }
+
+    #[inline]
+    fn from_state_incr(state: u128, increment: u128) -> Self {
+        let mut pcg = Lcg128Xsl64 { state, increment };
+        // Move away from inital value:
+        pcg.state = pcg.state.wrapping_add(pcg.increment);
+        pcg.step();
+        pcg
+    }
+
+    #[inline]
+    fn step(&mut self) {
+        // prepare the LCG for the next round
+        self.state = self.state
+            .wrapping_mul(MULTIPLIER)
+            .wrapping_add(self.increment);
+    }
+}
+
+// Custom Debug implementation that does not expose the internal state
+impl fmt::Debug for Lcg128Xsl64 {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "Lcg128Xsl64 {{}}")
+    }
+}
+
+/// We use a single 255-bit seed to initialise the state and select a stream.
+/// One `seed` bit (lowest bit of `seed[8]`) is ignored.
+impl SeedableRng for Lcg128Xsl64 {
+    type Seed = [u8; 32];
+
+    fn from_seed(seed: Self::Seed) -> Self {
+        let mut seed_u64 = [0u64; 4];
+        le::read_u64_into(&seed, &mut seed_u64);
+        let state = (seed_u64[0] as u128) | ((seed_u64[1] as u128) << 64);
+        let incr = (seed_u64[2] as u128) | ((seed_u64[3] as u128) << 64);
+
+        // The increment must be odd, hence we discard one bit:
+        Lcg128Xsl64::from_state_incr(state, incr | 1)
+    }
+}
+
+impl RngCore for Lcg128Xsl64 {
+    #[inline]
+    fn next_u32(&mut self) -> u32 {
+        self.next_u64() as u32
+    }
+
+    #[inline]
+    fn next_u64(&mut self) -> u64 {
+        self.step();
+        output_xsl_rr(self.state)
+    }
+
+    #[inline]
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        fill_bytes_impl(self, dest)
+    }
+
+    #[inline]
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        Ok(self.fill_bytes(dest))
+    }
+}
+
 
 /// A PCG random number generator (XSL 128/64 (MCG) variant).
 ///
@@ -23,19 +124,18 @@
 /// Congruential Generator, and 64-bit output via "xorshift low (bits),
 /// random rotation" output function.
 ///
-/// This is a 128-bit MCG with the PCG-XSL-RR output function.
+/// This is a 128-bit MCG with the PCG-XSL-RR output function, also known as
+/// `pcg64_fast`.
 /// Note that compared to the standard `pcg64` (128-bit LCG with PCG-XSL-RR
 /// output function), this RNG is faster, also has a long cycle, and still has
 /// good performance on statistical tests.
-///
-/// Note: this RNG is only available using Rust 1.26 or later.
 #[derive(Clone)]
 #[cfg_attr(feature="serde1", derive(Serialize,Deserialize))]
 pub struct Mcg128Xsl64 {
     state: u128,
 }
 
-/// A friendly name for `Mcg128Xsl64`.
+/// A friendly name for `Mcg128Xsl64` (also known as `pcg64_fast`).
 pub type Pcg64Mcg = Mcg128Xsl64;
 
 impl Mcg128Xsl64 {
@@ -80,39 +180,13 @@
 
     #[inline]
     fn next_u64(&mut self) -> u64 {
-        // prepare the LCG for the next round
-        let state = self.state.wrapping_mul(MULTIPLIER);
-        self.state = state;
-
-        // Output function XSL RR ("xorshift low (bits), random rotation")
-        // Constants are for 128-bit state, 64-bit output
-        const XSHIFT: u32 = 64;     // (128 - 64 + 64) / 2
-        const ROTATE: u32 = 122;    // 128 - 6
-
-        let rot = (state >> ROTATE) as u32;
-        let xsl = ((state >> XSHIFT) as u64) ^ (state as u64);
-        xsl.rotate_right(rot)
+        self.state = self.state.wrapping_mul(MULTIPLIER);
+        output_xsl_rr(self.state)
     }
 
     #[inline]
     fn fill_bytes(&mut self, dest: &mut [u8]) {
-        // specialisation of impls::fill_bytes_via_next; approx 3x faster
-        let mut left = dest;
-        while left.len() >= 8 {
-            let (l, r) = {left}.split_at_mut(8);
-            left = r;
-            let chunk: [u8; 8] = unsafe {
-                transmute(self.next_u64().to_le())
-            };
-            l.copy_from_slice(&chunk);
-        }
-        let n = left.len();
-        if n > 0 {
-            let chunk: [u8; 8] = unsafe {
-                transmute(self.next_u64().to_le())
-            };
-            left.copy_from_slice(&chunk[..n]);
-        }
+        fill_bytes_impl(self, dest)
     }
 
     #[inline]
@@ -120,3 +194,35 @@
         Ok(self.fill_bytes(dest))
     }
 }
+
+#[inline(always)]
+fn output_xsl_rr(state: u128) -> u64 {
+    // Output function XSL RR ("xorshift low (bits), random rotation")
+    // Constants are for 128-bit state, 64-bit output
+    const XSHIFT: u32 = 64;     // (128 - 64 + 64) / 2
+    const ROTATE: u32 = 122;    // 128 - 6
+
+    let rot = (state >> ROTATE) as u32;
+    let xsl = ((state >> XSHIFT) as u64) ^ (state as u64);
+    xsl.rotate_right(rot)
+}
+
+#[inline(always)]
+fn fill_bytes_impl<R: RngCore + ?Sized>(rng: &mut R, dest: &mut [u8]) {
+    let mut left = dest;
+    while left.len() >= 8 {
+        let (l, r) = {left}.split_at_mut(8);
+        left = r;
+        let chunk: [u8; 8] = unsafe {
+            transmute(rng.next_u64().to_le())
+        };
+        l.copy_from_slice(&chunk);
+    }
+    let n = left.len();
+    if n > 0 {
+        let chunk: [u8; 8] = unsafe {
+            transmute(rng.next_u64().to_le())
+        };
+        left.copy_from_slice(&chunk[..n]);
+    }
+}
diff --git a/rand_pcg/src/pcg64.rs b/rand_pcg/src/pcg64.rs
index 9177ec2..dd14530 100644
--- a/rand_pcg/src/pcg64.rs
+++ b/rand_pcg/src/pcg64.rs
@@ -11,8 +11,8 @@
 //! PCG random number generators
 
 use core::fmt;
-use core::mem::transmute;
 use rand_core::{RngCore, SeedableRng, Error, le, impls};
+#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
 
 // This is the default multiplier used by PCG for 64-bit state.
 const MULTIPLIER: u64 = 6364136223846793005;
@@ -45,7 +45,8 @@
     /// Note that PCG specifies default values for both parameters:
     ///
     /// - `state = 0xcafef00dd15ea5e5`
-    /// - `stream = 721347520444481703`
+    /// - `stream = 0xa02bdbf7bb3c0a7`
+    // Note: stream is 1442695040888963407u64 >> 1
     pub fn new(state: u64, stream: u64) -> Self {
         // The increment must be odd, hence we discard one bit:
         let increment = (stream << 1) | 1;
@@ -115,23 +116,7 @@
 
     #[inline]
     fn fill_bytes(&mut self, dest: &mut [u8]) {
-        // specialisation of impls::fill_bytes_via_next; approx 40% faster
-        let mut left = dest;
-        while left.len() >= 4 {
-            let (l, r) = {left}.split_at_mut(4);
-            left = r;
-            let chunk: [u8; 4] = unsafe {
-                transmute(self.next_u32().to_le())
-            };
-            l.copy_from_slice(&chunk);
-        }
-        let n = left.len();
-        if n > 0 {
-            let chunk: [u8; 4] = unsafe {
-                transmute(self.next_u32().to_le())
-            };
-            left.copy_from_slice(&chunk[..n]);
-        }
+        impls::fill_bytes_via_next(self, dest)
     }
 
     #[inline]
diff --git a/rand_pcg/tests/lcg128xsl64.rs b/rand_pcg/tests/lcg128xsl64.rs
new file mode 100644
index 0000000..efc72ff
--- /dev/null
+++ b/rand_pcg/tests/lcg128xsl64.rs
@@ -0,0 +1,55 @@
+use rand_core::{RngCore, SeedableRng};
+use rand_pcg::{Lcg128Xsl64, Pcg64};
+
+#[test]
+fn test_lcg128xsl64_construction() {
+    // Test that various construction techniques produce a working RNG.
+    let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16,
+            17,18,19,20, 21,22,23,24, 25,26,27,28, 29,30,31,32];
+    let mut rng1 = Lcg128Xsl64::from_seed(seed);
+    assert_eq!(rng1.next_u64(), 8740028313290271629);
+
+    let mut rng2 = Lcg128Xsl64::from_rng(&mut rng1).unwrap();
+    assert_eq!(rng2.next_u64(), 1922280315005786345);
+
+    let mut rng3 = Lcg128Xsl64::seed_from_u64(0);
+    assert_eq!(rng3.next_u64(), 2354861276966075475);
+
+    // This is the same as Lcg128Xsl64, so we only have a single test:
+    let mut rng4 = Pcg64::seed_from_u64(0);
+    assert_eq!(rng4.next_u64(), 2354861276966075475);
+}
+
+#[test]
+fn test_lcg128xsl64_true_values() {
+    // Numbers copied from official test suite (C version).
+    let mut rng = Lcg128Xsl64::new(42, 54);
+
+    let mut results = [0u64; 6];
+    for i in results.iter_mut() { *i = rng.next_u64(); }
+    let expected: [u64; 6] = [0x86b1da1d72062b68, 0x1304aa46c9853d39,
+        0xa3670e9e0dd50358, 0xf9090e529a7dae00, 0xc85b9fd837996f2c, 0x606121f8e3919196];
+    assert_eq!(results, expected);
+}
+
+#[cfg(feature="serde1")]
+#[test]
+fn test_lcg128xsl64_serde() {
+    use bincode;
+    use std::io::{BufWriter, BufReader};
+
+    let mut rng = Lcg128Xsl64::seed_from_u64(0);
+
+    let buf: Vec<u8> = Vec::new();
+    let mut buf = BufWriter::new(buf);
+    bincode::serialize_into(&mut buf, &rng).expect("Could not serialize");
+
+    let buf = buf.into_inner().unwrap();
+    let mut read = BufReader::new(&buf[..]);
+    let mut deserialized: Lcg128Xsl64 = bincode::deserialize_from(&mut read)
+        .expect("Could not deserialize");
+
+    for _ in 0..16 {
+        assert_eq!(rng.next_u64(), deserialized.next_u64());
+    }
+}
diff --git a/rand_pcg/tests/lcg64xsh32.rs b/rand_pcg/tests/lcg64xsh32.rs
index 775b12c..e05bcc1 100644
--- a/rand_pcg/tests/lcg64xsh32.rs
+++ b/rand_pcg/tests/lcg64xsh32.rs
@@ -1,7 +1,3 @@
-extern crate rand_pcg;
-extern crate rand_core;
-#[cfg(all(feature="serde1", test))] extern crate bincode;
-
 use rand_core::{RngCore, SeedableRng};
 use rand_pcg::{Lcg64Xsh32, Pcg32};
 
diff --git a/rand_pcg/tests/mcg128xsl64.rs b/rand_pcg/tests/mcg128xsl64.rs
index 3279536..d58fa75 100644
--- a/rand_pcg/tests/mcg128xsl64.rs
+++ b/rand_pcg/tests/mcg128xsl64.rs
@@ -1,8 +1,3 @@
-#![cfg(rustc_1_26)]
-extern crate rand_pcg;
-extern crate rand_core;
-#[cfg(all(feature="serde1", test))] extern crate bincode;
-
 use rand_core::{RngCore, SeedableRng};
 use rand_pcg::{Mcg128Xsl64, Pcg64Mcg};
 
diff --git a/rand_xorshift/CHANGELOG.md b/rand_xorshift/CHANGELOG.md
index 78abf6b..ce3098a 100644
--- a/rand_xorshift/CHANGELOG.md
+++ b/rand_xorshift/CHANGELOG.md
@@ -4,7 +4,11 @@
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
-## [0.1.2] - 2019-06-06
+## [0.2.0] - 2019-06-12
+- Bump minor crate version since rand_core bump is a breaking change
+- Switch to Edition 2018
+
+## [0.1.2] - 2019-06-06 - yanked
 - Bump `rand_core` version
 - Make XorShiftRng::from_rng portable by enforcing Endianness (#815)
 
diff --git a/rand_xorshift/Cargo.toml b/rand_xorshift/Cargo.toml
index 86ad39d..c47bcc9 100644
--- a/rand_xorshift/Cargo.toml
+++ b/rand_xorshift/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "rand_xorshift"
-version = "0.1.2"
+version = "0.2.0"
 authors = ["The Rand Project Developers", "The Rust Project Developers"]
 license = "MIT/Apache-2.0"
 readme = "README.md"
@@ -12,18 +12,18 @@
 """
 keywords = ["random", "rng", "xorshift"]
 categories = ["algorithms", "no-std"]
+edition = "2018"
 
 [badges]
 travis-ci = { repository = "rust-random/rand" }
 appveyor = { repository = "rust-random/rand" }
 
 [features]
-serde1 = ["serde", "serde_derive"]
+serde1 = ["serde"]
 
 [dependencies]
 rand_core = { path = "../rand_core", version = "0.5" }
-serde = { version = "1", optional = true }
-serde_derive = { version = "^1.0.38", optional = true }
+serde = { version = "1", features = ["derive"], optional = true }
 
 [dev-dependencies]
 # This is for testing serde, unfortunately we can't specify feature-gated dev
diff --git a/rand_xorshift/src/lib.rs b/rand_xorshift/src/lib.rs
index f6301b1..769921f 100644
--- a/rand_xorshift/src/lib.rs
+++ b/rand_xorshift/src/lib.rs
@@ -17,14 +17,10 @@
 
 #![no_std]
 
-pub extern crate rand_core;
-
-#[cfg(feature="serde1")] extern crate serde;
-#[cfg(feature="serde1")] #[macro_use] extern crate serde_derive;
-
 use core::num::Wrapping as w;
 use core::{fmt, slice};
 use rand_core::{RngCore, SeedableRng, Error, impls, le};
+#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
 
 /// An Xorshift random number generator.
 ///
diff --git a/rand_xorshift/tests/mod.rs b/rand_xorshift/tests/mod.rs
index 32f6b94..7ecdeae 100644
--- a/rand_xorshift/tests/mod.rs
+++ b/rand_xorshift/tests/mod.rs
@@ -1,7 +1,3 @@
-extern crate rand_core;
-extern crate rand_xorshift;
-#[cfg(all(feature="serde1", test))] extern crate bincode;
-
 use rand_core::{RngCore, SeedableRng};
 use rand_xorshift::XorShiftRng;
 
diff --git a/rand_xoshiro/CHANGELOG.md b/rand_xoshiro/CHANGELOG.md
index 8a32c6a..0edf848 100644
--- a/rand_xoshiro/CHANGELOG.md
+++ b/rand_xoshiro/CHANGELOG.md
@@ -4,7 +4,11 @@
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
-## [0.2.1] - 2019-06-06
+## [0.3.0] - 2019-06-12
+- Bump minor crate version since rand_core bump is a breaking change
+- Switch to Edition 2018
+
+## [0.2.1] - 2019-06-06 - yanked
 - Bump `rand_core` version
 - Document crate features in README
 
diff --git a/rand_xoshiro/Cargo.toml b/rand_xoshiro/Cargo.toml
index 94b0a29..43a5b88 100644
--- a/rand_xoshiro/Cargo.toml
+++ b/rand_xoshiro/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "rand_xoshiro"
-version = "0.2.1" # NB: When modifying, also modify html_root_url in lib.rs
+version = "0.3.0" # NB: When modifying, also modify html_root_url in lib.rs
 authors = ["The Rand Project Developers"]
 license = "MIT/Apache-2.0"
 readme = "README.md"
@@ -10,15 +10,15 @@
 description = "Xoshiro, xoroshiro and splitmix64 random number generators"
 keywords = ["random", "rng"]
 categories = ["algorithms"]
+edition = "2018"
 
 [features]
-serde1 = ["serde", "serde_derive"]
+serde1 = ["serde"]
 
 [dependencies]
 byteorder = { version = "1", default-features=false }
 rand_core = { path = "../rand_core", version = "0.5" }
-serde = { version = "1", optional=true }
-serde_derive = { version = "^1.0.38", optional=true }
+serde = { version = "1", features = ["derive"], optional=true }
 
 [dev-dependencies]
 # This is for testing serde, unfortunately we can't specify feature-gated dev
diff --git a/rand_xoshiro/src/common.rs b/rand_xoshiro/src/common.rs
index 9ee09e2..b188dd6 100644
--- a/rand_xoshiro/src/common.rs
+++ b/rand_xoshiro/src/common.rs
@@ -9,7 +9,7 @@
 /// Initialize a RNG from a `u64` seed using `SplitMix64`.
 macro_rules! from_splitmix {
     ($seed:expr) => { {
-        let mut rng = ::SplitMix64::seed_from_u64($seed);
+        let mut rng = crate::SplitMix64::seed_from_u64($seed);
         Self::from_rng(&mut rng).unwrap()
     } }
 }
diff --git a/rand_xoshiro/src/lib.rs b/rand_xoshiro/src/lib.rs
index 4ea92cb..42ee963 100644
--- a/rand_xoshiro/src/lib.rs
+++ b/rand_xoshiro/src/lib.rs
@@ -58,16 +58,12 @@
 
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
        html_favicon_url = "https://www.rust-lang.org/favicon.ico",
-       html_root_url = "https://docs.rs/rand_xoshiro/0.2.1")]
+       html_root_url = "https://docs.rs/rand_xoshiro/0.3.0")]
 
 #![deny(missing_docs)]
 #![deny(missing_debug_implementations)]
 #![cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))]
 #![no_std]
-extern crate byteorder;
-pub extern crate rand_core;
-#[cfg(feature="serde1")] extern crate serde;
-#[cfg(feature="serde1")] #[macro_use] extern crate serde_derive;
 
 #[macro_use]
 mod common;
@@ -83,6 +79,7 @@
 mod xoroshiro64starstar;
 mod xoroshiro64star;
 
+pub use rand_core;
 pub use splitmix64::SplitMix64;
 pub use xoshiro128starstar::Xoshiro128StarStar;
 pub use xoshiro128plus::Xoshiro128Plus;
diff --git a/rand_xoshiro/src/splitmix64.rs b/rand_xoshiro/src/splitmix64.rs
index d83f9c9..9a29faf 100644
--- a/rand_xoshiro/src/splitmix64.rs
+++ b/rand_xoshiro/src/splitmix64.rs
@@ -6,6 +6,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
 use byteorder::{ByteOrder, LittleEndian};
 use rand_core::le::read_u64_into;
 use rand_core::impls::fill_bytes_via_next;
diff --git a/rand_xoshiro/src/xoroshiro128plus.rs b/rand_xoshiro/src/xoroshiro128plus.rs
index 2a3e095..243b427 100644
--- a/rand_xoshiro/src/xoroshiro128plus.rs
+++ b/rand_xoshiro/src/xoroshiro128plus.rs
@@ -6,6 +6,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
 use rand_core;
 use rand_core::le::read_u64_into;
 use rand_core::impls::fill_bytes_via_next;
diff --git a/rand_xoshiro/src/xoroshiro128starstar.rs b/rand_xoshiro/src/xoroshiro128starstar.rs
index a15fc50..32f13c8 100644
--- a/rand_xoshiro/src/xoroshiro128starstar.rs
+++ b/rand_xoshiro/src/xoroshiro128starstar.rs
@@ -6,6 +6,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
 use rand_core;
 use rand_core::le::read_u64_into;
 use rand_core::impls::fill_bytes_via_next;
diff --git a/rand_xoshiro/src/xoroshiro64star.rs b/rand_xoshiro/src/xoroshiro64star.rs
index 7237411..6bb708a 100644
--- a/rand_xoshiro/src/xoroshiro64star.rs
+++ b/rand_xoshiro/src/xoroshiro64star.rs
@@ -6,6 +6,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
 use rand_core;
 use rand_core::le::read_u32_into;
 use rand_core::impls::{fill_bytes_via_next, next_u64_via_u32};
diff --git a/rand_xoshiro/src/xoroshiro64starstar.rs b/rand_xoshiro/src/xoroshiro64starstar.rs
index fef840c..8e1aea1 100644
--- a/rand_xoshiro/src/xoroshiro64starstar.rs
+++ b/rand_xoshiro/src/xoroshiro64starstar.rs
@@ -6,6 +6,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
 use rand_core;
 use rand_core::le::read_u32_into;
 use rand_core::impls::{fill_bytes_via_next, next_u64_via_u32};
diff --git a/rand_xoshiro/src/xoshiro128plus.rs b/rand_xoshiro/src/xoshiro128plus.rs
index e24fa45..9bcdaf3 100644
--- a/rand_xoshiro/src/xoshiro128plus.rs
+++ b/rand_xoshiro/src/xoshiro128plus.rs
@@ -6,6 +6,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
 use rand_core::impls::{next_u64_via_u32, fill_bytes_via_next};
 use rand_core::le::read_u32_into;
 use rand_core::{SeedableRng, RngCore, Error};
diff --git a/rand_xoshiro/src/xoshiro128starstar.rs b/rand_xoshiro/src/xoshiro128starstar.rs
index ee485f3..aa1c4bf 100644
--- a/rand_xoshiro/src/xoshiro128starstar.rs
+++ b/rand_xoshiro/src/xoshiro128starstar.rs
@@ -6,6 +6,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
 use rand_core::impls::{next_u64_via_u32, fill_bytes_via_next};
 use rand_core::le::read_u32_into;
 use rand_core::{SeedableRng, RngCore, Error};
diff --git a/rand_xoshiro/src/xoshiro256plus.rs b/rand_xoshiro/src/xoshiro256plus.rs
index 4e577b6..0821abc 100644
--- a/rand_xoshiro/src/xoshiro256plus.rs
+++ b/rand_xoshiro/src/xoshiro256plus.rs
@@ -6,6 +6,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
 use rand_core::impls::fill_bytes_via_next;
 use rand_core::le::read_u64_into;
 use rand_core::{SeedableRng, RngCore, Error};
diff --git a/rand_xoshiro/src/xoshiro256starstar.rs b/rand_xoshiro/src/xoshiro256starstar.rs
index 1c2e83b..2c9aacc 100644
--- a/rand_xoshiro/src/xoshiro256starstar.rs
+++ b/rand_xoshiro/src/xoshiro256starstar.rs
@@ -6,6 +6,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
 use rand_core::impls::fill_bytes_via_next;
 use rand_core::le::read_u64_into;
 use rand_core::{SeedableRng, RngCore, Error};
diff --git a/rand_xoshiro/src/xoshiro512plus.rs b/rand_xoshiro/src/xoshiro512plus.rs
index bc4823a..68ac385 100644
--- a/rand_xoshiro/src/xoshiro512plus.rs
+++ b/rand_xoshiro/src/xoshiro512plus.rs
@@ -6,11 +6,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
 use rand_core::impls::fill_bytes_via_next;
 use rand_core::le::read_u64_into;
 use rand_core::{SeedableRng, RngCore, Error};
 
-use Seed512;
+use crate::Seed512;
 
 /// A xoshiro512+ random number generator.
 ///
diff --git a/rand_xoshiro/src/xoshiro512starstar.rs b/rand_xoshiro/src/xoshiro512starstar.rs
index 3109f2b..92fc5fe 100644
--- a/rand_xoshiro/src/xoshiro512starstar.rs
+++ b/rand_xoshiro/src/xoshiro512starstar.rs
@@ -6,11 +6,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
 use rand_core::impls::fill_bytes_via_next;
 use rand_core::le::read_u64_into;
 use rand_core::{SeedableRng, RngCore, Error};
 
-use Seed512;
+use crate::Seed512;
 
 /// A xoshiro512** random number generator.
 ///