Merge pull request #880 from vks/vigna2019

rand_xoshiro: Bump minor version
diff --git a/.travis.yml b/.travis.yml
index c375880..bb4ce0f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,158 +1,42 @@
 language: rust
 sudo: false
 
-# We support too many combinations of Rust releases, crate features, operating
-# systems, and architectures to even remotely test all combinations.
-# Yet it turns out we can test most of these independent of each other, because
-# they serve different goals or test different pieces of code.
-#
-# RUST RELEASES
-# Goal: make sure we don't use language features unavailable on a certain
-#       version, and build without warnings.
-# We have different builders use 4 Rust releases, a pinned stable release,
-# the latest stable, beta and nightly.
-#
-# ARCHITECTURES
-# Goal: test against issues caused by differences in endianness, pointer sizes,
-#       etc.
-# We run tests on 4 different architectures.
-# - x64_84, default on Travis (Linux) and AppVeyor (Windows)
-# - i686, second AppVeyor (Windows) configuration
-# - MIPS, big-endian Linux emulated with QEMU (thanks to Trust)
-# - ARMv7, Android emulated with QEMU (thanks to Trust)
-#
-# OPERATING SYSTEMS
-# Goal: test on many operating systems, to verify the OsRng code, which is
-#       mostly architecture-independent.
-# We run tests on Linux, OS X, Windows, Android (emulated), and Node.js (using
-# cargo-web).
-# One builder cross-compiles for many of the remaining OSes, which ensures we
-# keep building, but doesn't run tests.
-# OSes supported by Rand but which we can't cross-compile because there
-# is no pre-built standard library available: Dragonfly BSD, Haiku, OpenBSD.
-#
-# CRATE FEATURES, TESTS, AND SUB-CRATES
-# Goal: Run unit tests, doctests, examples, and test benchmarks for all crates,
-#       in configurations that cover all interesting combinations of features.
-# Tests run on rand:
-# - test no_std support, but only the unit tests:
-#   `cargo test --tests --no-default-features`
-# - run unit tests and doctests with all features which are available on stable:
-#   `cargo test --features=serde1,log`
-# - test examples:
-#   `cargo test --examples`
-# Additional tests on nightly:
-# - run unit tests and doctests with all features which are available on nightly:
-#   `cargo test --all-features`
-# - test no_std support, including the nightly alloc feature:
-#   cargo test --tests --no-default-features --features=alloc
-# - run benchmarks as tests:
-#   `cargo test --benches --features=nightly`
-# Tests on subcrates:
-# - select crates via --manifest-path (more reliable than --package)
-# - test appropriate feature matrix
-#
-# TODO: SIMD support on stable releases
-# NOTE: SIMD support is unreliable on nightly; we track the latest release
+# Since most OS-specific code has moved to the getrandom crate, we require
+# few target-specific tests here.
+
 matrix:
   include:
     - rust: 1.32.0
-      env: DESCRIPTION="Linux, 1.32.0"
+      name: "Linux, 1.32.0"
+      env: ALLOC=0
       os: linux
-      script:
-        # Differs from standard script: rand_pcg features
-        - cargo test --tests --no-default-features
-        # TODO: add simd_support feature:
-        - cargo test --features=serde1,log
-        - cargo test --examples
-        - cargo test --manifest-path rand_core/Cargo.toml
-        - cargo test --manifest-path rand_core/Cargo.toml --no-default-features
-        - cargo test --manifest-path rand_distr/Cargo.toml
-        - cargo test --manifest-path rand_isaac/Cargo.toml --features=serde1
-        # TODO: cannot test rand_pcg due to explicit dependency on i128
-        - cargo test --manifest-path rand_xorshift/Cargo.toml --features=serde1
-        - cargo test --manifest-path rand_xoshiro/Cargo.toml
-        - cargo test --manifest-path rand_chacha/Cargo.toml
-        - cargo test --manifest-path rand_hc/Cargo.toml
-        - cargo test --manifest-path rand_jitter/Cargo.toml
-        - cargo test --manifest-path rand_os/Cargo.toml
-
-    - rust: 1.32.0
-      env: DESCRIPTION="OSX, 1.32.0"
-      os: osx
-      script:
-        # Differs from standard script: rand_pcg features
-        - cargo test --tests --no-default-features
-        # TODO: add simd_support feature:
-        - cargo test --features=serde1,log
-        - cargo test --examples
-        - cargo test --manifest-path rand_core/Cargo.toml
-        - cargo test --manifest-path rand_core/Cargo.toml --no-default-features
-        - cargo test --manifest-path rand_distr/Cargo.toml
-        - cargo test --manifest-path rand_isaac/Cargo.toml --features=serde1
-        # TODO: cannot test rand_pcg due to explicit dependency on i128
-        - cargo test --manifest-path rand_xorshift/Cargo.toml --features=serde1
-        - cargo test --manifest-path rand_xoshiro/Cargo.toml
-        - cargo test --manifest-path rand_chacha/Cargo.toml
-        - cargo test --manifest-path rand_hc/Cargo.toml
-        - cargo test --manifest-path rand_jitter/Cargo.toml
-        - cargo test --manifest-path rand_os/Cargo.toml
 
     - rust: stable
-      env: DESCRIPTION="Linux, stable"
+      name: "Linux, stable"
 
     - rust: stable
-      env: DESCRIPTION="OSX+iOS, stable"
+      name: "OSX+iOS, stable"
       os: osx
       install:
         - rustup target add aarch64-apple-ios
       script:
-        # Differs from standard script: includes aarch64-apple-ios cross-build
-        - cargo test --tests --no-default-features
-        # TODO: add simd_support feature:
-        - cargo test --features=serde1,log
-        - cargo test --examples
-        - cargo test --manifest-path rand_core/Cargo.toml
-        - cargo test --manifest-path rand_core/Cargo.toml --no-default-features
-        - cargo test --manifest-path rand_distr/Cargo.toml
-        - cargo test --manifest-path rand_isaac/Cargo.toml --features=serde1
-        - cargo test --manifest-path rand_pcg/Cargo.toml --features=serde1
-        - cargo test --manifest-path rand_xorshift/Cargo.toml --features=serde1
-        - cargo test --manifest-path rand_xoshiro/Cargo.toml
-        - cargo test --manifest-path rand_chacha/Cargo.toml
-        - cargo test --manifest-path rand_hc/Cargo.toml
-        - cargo test --manifest-path rand_jitter/Cargo.toml
-        - cargo test --manifest-path rand_os/Cargo.toml
+        - bash utils/ci/script.sh
         - cargo build --target=aarch64-apple-ios
 
     - rust: beta
-      env: DESCRIPTION="Linux, beta"
+      name: "Linux, beta"
 
     - rust: nightly
       os: linux
-      env: DESCRIPTION="Linux, nightly, docs"
+      name: "Linux, nightly, docs"
+      env: NIGHTLY=1
       install:
         - cargo --list | egrep "^\s*deadlinks$" -q || cargo install cargo-deadlinks
         - cargo deadlinks -V
       before_script:
         - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
       script:
-        # Differs from standard script: alloc feature, all features, doc build
-        - cargo test --tests --no-default-features --features=alloc
-        - cargo test --all-features
-        - cargo test --benches --features=nightly
-        - cargo test --examples
-        - cargo test --manifest-path rand_core/Cargo.toml
-        - cargo test --manifest-path rand_core/Cargo.toml --no-default-features --features=alloc
-        - cargo test --manifest-path rand_distr/Cargo.toml
-        - cargo test --manifest-path rand_isaac/Cargo.toml --features=serde1
-        - cargo test --manifest-path rand_pcg/Cargo.toml --features=serde1
-        - cargo test --manifest-path rand_xorshift/Cargo.toml --features=serde1
-        - cargo test --manifest-path rand_xoshiro/Cargo.toml
-        - cargo test --manifest-path rand_chacha/Cargo.toml
-        - cargo test --manifest-path rand_hc/Cargo.toml
-        - cargo test --manifest-path rand_jitter/Cargo.toml
-        - cargo test --manifest-path rand_os/Cargo.toml
+        - bash utils/ci/script.sh
         # remove cached documentation, otherwise files from previous PRs can get included
         - rm -rf target/doc
         - cargo doc --no-deps --all --all-features
@@ -160,103 +44,20 @@
       after_success:
         - travis-cargo --only nightly doc-upload
 
-    - rust: nightly
-      os: osx
-      env: DESCRIPTION="OSX, nightly, docs"
-      install:
-        - cargo --list | egrep "^\s*deadlinks$" -q || cargo install cargo-deadlinks
-        - cargo deadlinks -V
-      script:
-        # Differs from standard script: alloc feature, all features, doc build
-        - cargo test --tests --no-default-features --features=alloc
-        - cargo test --all-features
-        - cargo test --benches --features=nightly
-        - cargo test --examples
-        - cargo test --manifest-path rand_core/Cargo.toml
-        - cargo test --manifest-path rand_core/Cargo.toml --no-default-features --features=alloc
-        - cargo test --manifest-path rand_distr/Cargo.toml
-        - cargo test --manifest-path rand_isaac/Cargo.toml --features=serde1
-        - cargo test --manifest-path rand_pcg/Cargo.toml --features=serde1
-        - cargo test --manifest-path rand_xorshift/Cargo.toml --features=serde1
-        - cargo test --manifest-path rand_xoshiro/Cargo.toml
-        - cargo test --manifest-path rand_chacha/Cargo.toml
-        - cargo test --manifest-path rand_hc/Cargo.toml
-        - cargo test --manifest-path rand_jitter/Cargo.toml
-        - cargo test --manifest-path rand_os/Cargo.toml
-        # remove cached documentation, otherwise files from previous PRs can get included
-        - rm -rf target/doc
-        - cargo doc --no-deps --all --all-features
-        - cargo deadlinks --dir target/doc
-
-    - rust: nightly
-      env: DESCRIPTION="WASM via emscripten, stdweb and wasm-bindgen"
-      install:
-        - rustup target add wasm32-unknown-unknown
-        - rustup target add wasm32-unknown-emscripten
-        - nvm install 9
-        - ./utils/ci/install_cargo_web.sh
-        - cargo web prepare-emscripten
-        - cargo web -V
-        - cargo list | grep install-update || cargo install -f cargo-update
-        - cargo install-update -i cargo-update wasm-bindgen-cli wasm-pack
-      addons:
-        chrome: stable
-      script:
-        # Testing wasm32-unknown-emscripten fails because of rust-lang/rust#49877
-        # However, we can still build and link all tests to make sure that works.
-        # This is actually useful as it finds stuff such as rust-random/rand#669
-        - EMCC_CFLAGS="-s ERROR_ON_UNDEFINED_SYMBOLS=0" cargo web test --target wasm32-unknown-emscripten --no-run
-        #- cargo web test --target wasm32-unknown-emscripten
-        #- cargo web test --nodejs --target wasm32-unknown-emscripten
-        #- cargo build --target wasm32-unknown-unknown # without any features
-        - cargo build --target wasm32-unknown-unknown --features=wasm-bindgen
-        - cargo web test --target wasm32-unknown-unknown --features=stdweb
-        - cargo build --manifest-path tests/wasm_bindgen/Cargo.toml --target wasm32-unknown-unknown
-        - wasm-bindgen --nodejs target/wasm32-unknown-unknown/debug/rand_wasm_bindgen_test.wasm --out-dir tests/wasm_bindgen/js
-        - node tests/wasm_bindgen/js/index.js
-        - wasm-pack test --node tests/wasm_bindgen
-
-    - rust: nightly
-      env: DESCRIPTION="cross-platform builder (doesn't run tests)"
-      install:
-        - rustup target add x86_64-sun-solaris
-        - rustup target add x86_64-unknown-cloudabi
-        - rustup target add x86_64-unknown-freebsd
-        #- rustup target add x86_64-unknown-fuchsia
-        - rustup target add x86_64-unknown-netbsd
-        - rustup target add x86_64-unknown-redox
-      script:
-        # Test the top-level crate with all features:
-        - cargo build --target=x86_64-sun-solaris --all-features
-        - cargo build --target=x86_64-unknown-cloudabi --all-features
-        - cargo build --target=x86_64-unknown-freebsd --all-features
-        #- cargo build --target=x86_64-unknown-fuchsia --all-features
-        - cargo build --target=x86_64-unknown-netbsd --all-features
-        - cargo build --target=x86_64-unknown-redox --all-features
-
-    # Trust cross-built/emulated targets. We must repeat all non-default values.
+    # This target catches endianness issues
     - rust: stable
       sudo: required
       dist: trusty
       services: docker
-      env: DESCRIPTION="Linux (MIPS, big-endian)" TARGET=mips-unknown-linux-gnu
+      name: "Linux (MIPS, big-endian)"
+      env: TARGET=mips-unknown-linux-gnu
       install:
         - sh utils/ci/install.sh
         - source ~/.cargo/env || true
-      script:
-        - bash utils/ci/script.sh
-    - rust: stable
-      sudo: required
-      dist: trusty
-      services: docker
-      env: DESCRIPTION="Android (ARMv7)" TARGET=armv7-linux-androideabi
-      install:
-        - sh utils/ci/install.sh
-        - source ~/.cargo/env || true
-      script:
-        - bash utils/ci/script.sh
+
+    # This target checks we really can build no_std binaries
     - rust: nightly
-      env: DESCRIPTION="no_std platform test"
+      name: "no_std platform test"
       install:
         - rustup target add thumbv6m-none-eabi
       script:
@@ -265,42 +66,35 @@
 
     - rust: nightly
       os: linux
-      env: DESCRIPTION="Miri, nightly"
+      name: "Miri, nightly"
       script:
         - sh utils/ci/miri.sh
+    
+    - rust: nightly
+      os: linux
+      name: "Minimal dep versions"
+      script:
+        - cargo generate-lockfile -Z minimal-versions
+        - bash utils/ci/script.sh
 
 before_install:
   - set -e
   - rustup self update
 
 script:
-  - cargo test --tests --no-default-features
-  - cargo test --tests --no-default-features --features getrandom
-  # TODO: add simd_support feature:
-  - cargo test --features=serde1,log
-  - cargo test --examples
-  - cargo test --manifest-path rand_core/Cargo.toml
-  - cargo test --manifest-path rand_core/Cargo.toml --no-default-features
-  - cargo test --manifest-path rand_distr/Cargo.toml
-  - cargo test --manifest-path rand_isaac/Cargo.toml --features=serde1
-  - cargo test --manifest-path rand_pcg/Cargo.toml --features=serde1
-  - cargo test --manifest-path rand_xorshift/Cargo.toml --features=serde1
-  - cargo test --manifest-path rand_xoshiro/Cargo.toml
-  - cargo test --manifest-path rand_chacha/Cargo.toml
-  - cargo test --manifest-path rand_hc/Cargo.toml
-  - cargo test --manifest-path rand_jitter/Cargo.toml
-  - cargo test --manifest-path rand_os/Cargo.toml
+  - bash utils/ci/script.sh
 
 after_script: set +e
 
-cache:
-  cargo: true
-  directories:
-    - .local/share/cargo-web
+# Cache: this seems to do more harm than good
+#cache:
+  #cargo: true
+  #directories:
+    #- .local/share/cargo-web
 
-before_cache:
-  # Travis can't cache files that are not readable by "others"
-  - chmod -R a+r $HOME/.cargo
+#before_cache:
+  ## Travis can't cache files that are not readable by "others"
+  #- chmod -R a+r $HOME/.cargo
 
 env:
   global:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 88fba02..a2ae496 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@
 ## [Unreleased]
 - Fix `no_std` behaviour, appropriately enable c2-chacha's `std` feature (#844)
 - Add a `no_std` target to CI to continously evaluate `no_std` status (#844)
+- `alloc` feature in `no_std` is available since Rust 1.36 (#856)
 
 ## [0.7.0] - 2019-06-28
 
diff --git a/Cargo.toml b/Cargo.toml
index 5f30603..fead913 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -57,8 +57,10 @@
 rand_core = { path = "rand_core", version = "0.5" }
 rand_pcg = { path = "rand_pcg", version = "0.2", optional = true }
 # Do not depend on 'getrandom_package' directly; use the 'getrandom' feature!
+# This is a dependency because: we forward wasm feature flags
+# This is renamed because: we need getrandom to depend on rand_core/getrandom
 getrandom_package = { version = "0.1.1", package = "getrandom", optional = true }
-log = { version = "0.4", optional = true }
+log = { version = "0.4.4", optional = true }
 
 [dependencies.packed_simd]
 # NOTE: so far no version works reliably due to dependence on unstable features
diff --git a/README.md b/README.md
index b9d43e9..5acbadb 100644
--- a/README.md
+++ b/README.md
@@ -84,7 +84,7 @@
 Rand is built with these features enabled by default:
 
 -   `std` enables functionality dependent on the `std` lib
--   `alloc` (implied by `std`) enables functionality requiring an allocator
+-   `alloc` (implied by `std`) enables functionality requiring an allocator (when using this feature in `no_std`, Rand requires Rustc version 1.36 or greater)
 -   `getrandom` (implied by `std`) is an optional dependency providing the code
     behind `rngs::OsRng`
 
diff --git a/appveyor.yml b/appveyor.yml
index ef0b4bf..a4cfbee 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -32,12 +32,14 @@
 build: false
 
 test_script:
-  - cargo test --tests --no-default-features --features alloc
-  # TODO: use --all-features once simd_support is sufficiently stable:
+  - cargo test --tests --no-default-features
+  - cargo test --tests --no-default-features --features=alloc,getrandom
+  # all stable features:
   - cargo test --features=serde1,log
   - cargo test --benches --features=nightly
   - cargo test --examples
   - cargo test --manifest-path rand_core/Cargo.toml
+  - cargo test --manifest-path rand_core/Cargo.toml --no-default-features
   - cargo test --manifest-path rand_core/Cargo.toml --no-default-features --features=alloc
   - cargo test --manifest-path rand_distr/Cargo.toml
   - cargo test --manifest-path rand_isaac/Cargo.toml --features=serde1
@@ -46,4 +48,5 @@
   - cargo test --manifest-path rand_xoshiro/Cargo.toml
   - cargo test --manifest-path rand_chacha/Cargo.toml
   - cargo test --manifest-path rand_hc/Cargo.toml
+  - cargo test --manifest-path rand_jitter/Cargo.toml
   - cargo test --manifest-path rand_os/Cargo.toml
diff --git a/benches/weighted.rs b/benches/weighted.rs
new file mode 100644
index 0000000..5ddca3f
--- /dev/null
+++ b/benches/weighted.rs
@@ -0,0 +1,36 @@
+// Copyright 2019 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(test)]
+
+extern crate test;
+
+use test::Bencher;
+use rand::Rng;
+use rand::distributions::WeightedIndex;
+
+#[bench]
+fn weighted_index_creation(b: &mut Bencher) {
+    let mut rng = rand::thread_rng();
+    let weights = [1u32, 2, 4, 0, 5, 1, 7, 1, 2, 3, 4, 5, 6, 7];
+    b.iter(|| {
+        let distr = WeightedIndex::new(weights.to_vec()).unwrap();
+        rng.sample(distr)
+    })
+}
+
+#[bench]
+fn weighted_index_modification(b: &mut Bencher) {
+    let mut rng = rand::thread_rng();
+    let weights = [1u32, 2, 3, 0, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7];
+    let mut distr = WeightedIndex::new(weights.to_vec()).unwrap();
+    b.iter(|| {
+        distr.update_weights(&[(2, &4), (5, &1)]).unwrap();
+        rng.sample(&distr)
+    })
+}
diff --git a/rand_core/CHANGELOG.md b/rand_core/CHANGELOG.md
index 4542a3b..dfdd692 100644
--- a/rand_core/CHANGELOG.md
+++ b/rand_core/CHANGELOG.md
@@ -4,38 +4,55 @@
 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.5.1] - 2019-08-28
+- `OsRng` added to `rand_core` (#863)
+- `Error::INTERNAL_START` and `Error::CUSTOM_START` constants (#864)
+- `Error::raw_os_error` method (#864)
+- `Debug` and `Display` formatting for `getrandom` error codes without `std` (#864)
+### Changed
+- `alloc` feature in `no_std` is available since Rust 1.36 (#856)
+- Added `#[inline]` to `Error` conversion methods (#864)
+
 ## [0.5.0] - 2019-06-06
+### Changed
 - Enable testing with Miri and fix incorrect pointer usages (#779, #780, #781, #783, #784)
 - Rewrite `Error` type and adjust API (#800)
 - Adjust usage of `#[inline]` for `BlockRng` and `BlockRng64`
 
 ## [0.4.0] - 2019-01-24
+### Changed
 - Disable the `std` feature by default (#702)
 
 ## [0.3.0] - 2018-09-24
+### Added
 - Add `SeedableRng::seed_from_u64` for convenient seeding. (#537)
 
 ## [0.2.1] - 2018-06-08
+### Added
 - References to a `CryptoRng` now also implement `CryptoRng`. (#470)
 
 ## [0.2.0] - 2018-05-21
+### Changed
 - Enable the `std` feature by default. (#409)
 - Remove `BlockRng{64}::inner` and `BlockRng::inner_mut`; instead making `core` public
-- Add `BlockRng{64}::index` and `BlockRng{64}::generate_and_set`. (#374, #419)
 - Change `BlockRngCore::Results` bound to also require `AsMut<[Self::Item]>`. (#419)
+### Added
+- Add `BlockRng{64}::index` and `BlockRng{64}::generate_and_set`. (#374, #419)
 - Implement `std::io::Read` for RngCore. (#434)
 
 ## [0.1.0] - 2018-04-17
-(Split out of the Rand crate, changes here are relative to rand 0.4.2)
+(Split out of the Rand crate, changes here are relative to rand 0.4.2.)
+### Added
 - `RngCore` and `SeedableRng` are now part of `rand_core`. (#288)
 - Add modules to help implementing RNGs `impl` and `le`. (#209, #228)
 - Add `Error` and `ErrorKind`. (#225)
 - Add `CryptoRng` marker trait. (#273)
 - Add `BlockRngCore` trait. (#281)
 - Add `BlockRng` and `BlockRng64` wrappers to help implementations. (#281, #325)
+- Add `RngCore::try_fill_bytes`. (#225)
+### Changed
 - Revise the `SeedableRng` trait. (#233)
 - Remove default implementations for `RngCore::next_u64` and `RngCore::fill_bytes`. (#288)
-- Add `RngCore::try_fill_bytes`. (#225)
 
 ## [0.0.1] - 2017-09-14 (yanked)
 Experimental version as part of the rand crate refactor.
diff --git a/rand_core/Cargo.toml b/rand_core/Cargo.toml
index b9042c0..e52af5f 100644
--- a/rand_core/Cargo.toml
+++ b/rand_core/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "rand_core"
-version = "0.5.0"
+version = "0.5.1"
 authors = ["The Rand Project Developers", "The Rust Project Developers"]
 license = "MIT OR Apache-2.0"
 readme = "README.md"
diff --git a/rand_core/src/error.rs b/rand_core/src/error.rs
index 7e8f0c9..30b095c 100644
--- a/rand_core/src/error.rs
+++ b/rand_core/src/error.rs
@@ -17,7 +17,6 @@
 /// In order to be compatible with `std` and `no_std`, this type has two
 /// possible implementations: with `std` a boxed `Error` trait object is stored,
 /// while with `no_std` we merely store an error code.
-#[derive(Debug)]
 pub struct Error {
     #[cfg(feature="std")]
     inner: Box<dyn std::error::Error + Send + Sync + 'static>,
@@ -32,6 +31,7 @@
     /// 
     /// See also `From<NonZeroU32>`, which is available with and without `std`.
     #[cfg(feature="std")]
+    #[inline]
     pub fn new<E>(err: E) -> Self
     where E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>
     {
@@ -43,6 +43,7 @@
     /// When configured with `std`, this is a trivial operation and never
     /// panics. Without `std`, this method is simply unavailable.
     #[cfg(feature="std")]
+    #[inline]
     pub fn inner(&self) -> &(dyn std::error::Error + Send + Sync + 'static) {
         &*self.inner
     }
@@ -52,15 +53,45 @@
     /// When configured with `std`, this is a trivial operation and never
     /// panics. Without `std`, this method is simply unavailable.
     #[cfg(feature="std")]
+    #[inline]
     pub fn take_inner(self) -> Box<dyn std::error::Error + Send + Sync + 'static> {
         self.inner
     }
     
+    /// Codes below this point represent OS Errors (i.e. positive i32 values).
+    /// Codes at or above this point, but below [`Error::CUSTOM_START`] are
+    /// reserved for use by the `rand` and `getrandom` crates.
+    pub const INTERNAL_START: u32 = 1 << 31;
+
+    /// Codes at or above this point can be used by users to define their own
+    /// custom errors.
+    pub const CUSTOM_START: u32 = (1 << 31) + (1 << 30);
+
+    /// Extract the raw OS error code (if this error came from the OS)
+    ///
+    /// This method is identical to `std::io::Error::raw_os_error()`, except
+    /// that it works in `no_std` contexts. If this method returns `None`, the
+    /// error value can still be formatted via the `Diplay` implementation.
+    #[inline]
+    pub fn raw_os_error(&self) -> Option<i32> {
+        #[cfg(feature="std")] {
+            if let Some(e) = self.inner.downcast_ref::<std::io::Error>() {
+                return e.raw_os_error();
+            }
+        }
+        match self.code() {
+            Some(code) if u32::from(code) < Self::INTERNAL_START =>
+                Some(u32::from(code) as i32),
+            _ => None,
+        }
+    }
+
     /// Retrieve the error code, if any.
     /// 
     /// If this `Error` was constructed via `From<NonZeroU32>`, then this method
     /// will return this `NonZeroU32` code (for `no_std` this is always the
     /// case). Otherwise, this method will return `None`.
+    #[inline]
     pub fn code(&self) -> Option<NonZeroU32> {
         #[cfg(feature="std")] {
             self.inner.downcast_ref::<ErrorCode>().map(|c| c.0)
@@ -71,18 +102,36 @@
     }
 }
 
+impl fmt::Debug for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        #[cfg(feature="std")] {
+            write!(f, "Error {{ inner: {:?} }}", self.inner)
+        }
+        #[cfg(all(feature="getrandom", not(feature="std")))] {
+            getrandom::Error::from(self.code).fmt(f)
+        }
+        #[cfg(not(feature="getrandom"))] {
+            write!(f, "Error {{ code: {} }}", self.code)
+        }
+    }
+}
+
 impl fmt::Display for Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         #[cfg(feature="std")] {
             write!(f, "{}", self.inner)
         }
-        #[cfg(not(feature="std"))] {
+        #[cfg(all(feature="getrandom", not(feature="std")))] {
+            getrandom::Error::from(self.code).fmt(f)
+        }
+        #[cfg(not(feature="getrandom"))] {
             write!(f, "error code {}", self.code)
         }
     }
 }
 
 impl From<NonZeroU32> for Error {
+    #[inline]
     fn from(code: NonZeroU32) -> Self {
         #[cfg(feature="std")] {
             Error { inner: Box::new(ErrorCode(code)) }
@@ -95,6 +144,7 @@
 
 #[cfg(feature="getrandom")]
 impl From<getrandom::Error> for Error {
+    #[inline]
     fn from(error: getrandom::Error) -> Self {
         #[cfg(feature="std")] {
             Error { inner: Box::new(error) }
@@ -107,6 +157,7 @@
 
 #[cfg(feature="std")]
 impl std::error::Error for Error {
+    #[inline]
     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
         self.inner.source()
     }
@@ -114,8 +165,13 @@
 
 #[cfg(feature="std")]
 impl From<Error> for std::io::Error {
+    #[inline]
     fn from(error: Error) -> Self {
-        std::io::Error::new(std::io::ErrorKind::Other, error)
+        if let Some(code) = error.raw_os_error() {
+            std::io::Error::from_raw_os_error(code)
+        } else {
+            std::io::Error::new(std::io::ErrorKind::Other, error)
+        }
     }
 }
 
diff --git a/rand_core/src/lib.rs b/rand_core/src/lib.rs
index 96b9457..d8e0189 100644
--- a/rand_core/src/lib.rs
+++ b/rand_core/src/lib.rs
@@ -38,7 +38,6 @@
 #![allow(clippy::unreadable_literal)]
 
 #![cfg_attr(not(feature="std"), no_std)]
-#![cfg_attr(all(feature="alloc", not(feature="std")), feature(alloc))]
 
 
 use core::default::Default;
@@ -49,12 +48,14 @@
 #[cfg(all(feature="alloc", not(feature="std")))] use alloc::boxed::Box;
 
 pub use error::Error;
+#[cfg(feature="getrandom")] pub use os::OsRng;
 
 
 mod error;
 pub mod block;
 pub mod impls;
 pub mod le;
+#[cfg(feature="getrandom")] mod os;
 
 
 /// The core of a random number generator.
diff --git a/src/rngs/os.rs b/rand_core/src/os.rs
similarity index 80%
rename from src/rngs/os.rs
rename to rand_core/src/os.rs
index 46c3483..fc23a57 100644
--- a/src/rngs/os.rs
+++ b/rand_core/src/os.rs
@@ -9,8 +9,8 @@
 //! Interface to the random number generator of the operating system.
 // Note: keep this code in sync with the rand_os crate!
 
-use crate::getrandom::getrandom;
-use rand_core::{CryptoRng, RngCore, Error, impls};
+use getrandom::getrandom;
+use crate::{CryptoRng, RngCore, Error, impls};
 
 /// A random number generator that retrieves randomness from from the
 /// operating system.
@@ -20,6 +20,9 @@
 /// The implementation is provided by the [getrandom] crate. Refer to
 /// [getrandom] documentation for details.
 ///
+/// This struct is only available when specifying the crate feature `getrandom`
+/// or `std`. When using the `rand` lib, it is also available as `rand::rngs::OsRng`.
+///
 /// # Blocking and error handling
 ///
 /// It is possible that when used during early boot the first call to `OsRng`
@@ -33,30 +36,17 @@
 ///
 /// # Usage example
 /// ```
-/// use rand::rngs::{StdRng, OsRng};
-/// use rand::{RngCore, SeedableRng};
+/// use rand_core::{RngCore, OsRng};
 ///
 /// let mut key = [0u8; 16];
 /// OsRng.fill_bytes(&mut key);
 /// let random_u64 = OsRng.next_u64();
-/// 
-/// // OsRng is especially useful for seeding other RNGs (see also from_entropy)
-/// let mut rng = StdRng::from_rng(OsRng).unwrap();
-/// let _ = rng.next_u32();
 /// ```
 ///
 /// [getrandom]: https://crates.io/crates/getrandom
 #[derive(Clone, Copy, Debug, Default)]
 pub struct OsRng;
 
-impl OsRng {
-    /// Create a new `OsRng`.
-    #[deprecated(since="0.7.0", note="replace OsRng::new().unwrap() with just OsRng")]
-    pub fn new() -> Result<OsRng, Error> {
-        Ok(OsRng)
-    }
-}
-
 impl CryptoRng for OsRng {}
 
 impl RngCore for OsRng {
diff --git a/rand_distr/Cargo.toml b/rand_distr/Cargo.toml
index 315a5b0..8fbf33b 100644
--- a/rand_distr/Cargo.toml
+++ b/rand_distr/Cargo.toml
@@ -24,4 +24,4 @@
 [dev-dependencies]
 rand_pcg = { version = "0.2", path = "../rand_pcg" }
 # Histogram implementation for testing uniformity
-average = "0.9.2"
+average = "0.10.3"
diff --git a/rand_isaac/Cargo.toml b/rand_isaac/Cargo.toml
index c11c305..a63ab18 100644
--- a/rand_isaac/Cargo.toml
+++ b/rand_isaac/Cargo.toml
@@ -23,9 +23,11 @@
 
 [dependencies]
 rand_core = { path = "../rand_core", version = "0.5" }
-serde = { version = "1", features = ["derive"], optional = true }
+serde = { version = "1.0.63", features = ["derive"], optional = true }
+# Not a direct dependency but required to boost the minimum version:
+serde_derive = { version = "1.0.63", optional = true }
 
 [dev-dependencies]
 # This is for testing serde, unfortunately we can't specify feature-gated dev
 # deps yet, see: https://github.com/rust-lang/cargo/issues/1596
-bincode = "1"
+bincode = "1.1.4"
diff --git a/rand_jitter/CHANGELOG.md b/rand_jitter/CHANGELOG.md
index 9dd6c0a..9f4bb7e 100644
--- a/rand_jitter/CHANGELOG.md
+++ b/rand_jitter/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.1] - 2019-08-16
+### Changed
+- `TimerError` changed to `repr(u32)` (#864)
+- `TimerError` enum values all increased by `1<<30` to match new `rand_core::Error` range (#864)
+
 ## [0.2.0] - 2019-06-06
 - Bump `rand_core` version
 - Support new `Error` type in `rand_core` 0.5
diff --git a/rand_jitter/Cargo.toml b/rand_jitter/Cargo.toml
index 7380f70..5b7e3c3 100644
--- a/rand_jitter/Cargo.toml
+++ b/rand_jitter/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "rand_jitter"
-version = "0.2.0"
+version = "0.2.1"
 authors = ["The Rand Project Developers"]
 license = "MIT OR Apache-2.0"
 readme = "README.md"
diff --git a/rand_jitter/src/error.rs b/rand_jitter/src/error.rs
index 3ea72c3..b54fffa 100644
--- a/rand_jitter/src/error.rs
+++ b/rand_jitter/src/error.rs
@@ -10,24 +10,28 @@
 use rand_core::Error;
 use core::fmt;
 
+/// Base code for all `JitterRng` errors
+const ERROR_BASE: u32 = 0xAE53_0400;
+
 /// An error that can occur when [`JitterRng::test_timer`] fails.
 /// 
-/// All variants have a value of 0x6e530400 = 1850934272 plus a small
+/// All variants have a value of 0xAE530400 = 2924676096 plus a small
 /// increment (1 through 5).
 ///
 /// [`JitterRng::test_timer`]: crate::JitterRng::test_timer
 #[derive(Debug, Clone, PartialEq, Eq)]
+#[repr(u32)]
 pub enum TimerError {
     /// No timer available.
-    NoTimer = 0x6e530401,
+    NoTimer = ERROR_BASE + 1,
     /// Timer too coarse to use as an entropy source.
-    CoarseTimer = 0x6e530402,
+    CoarseTimer = ERROR_BASE + 2,
     /// Timer is not monotonically increasing.
-    NotMonotonic = 0x6e530403,
+    NotMonotonic = ERROR_BASE + 3,
     /// Variations of deltas of time too small.
-    TinyVariantions = 0x6e530404,
+    TinyVariantions = ERROR_BASE + 4,
     /// Too many stuck results (indicating no added entropy).
-    TooManyStuck = 0x6e530405,
+    TooManyStuck = ERROR_BASE + 5,
     #[doc(hidden)]
     __Nonexhaustive,
 }
diff --git a/rand_os/CHANGELOG.md b/rand_os/CHANGELOG.md
index 9b8f208..c80befd 100644
--- a/rand_os/CHANGELOG.md
+++ b/rand_os/CHANGELOG.md
@@ -4,6 +4,10 @@
 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.2] - 2019-08-28
+### Changed
+- `OsRng` added to `rand_core`, rendering this crate deprecated (#863)
+
 ## [0.2.1] - 2019-08-08
 ### Fixed
 - Fix `no_std` support.
diff --git a/rand_os/Cargo.toml b/rand_os/Cargo.toml
index 6edf27d..c8010e2 100644
--- a/rand_os/Cargo.toml
+++ b/rand_os/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "rand_os"
-version = "0.2.1"
+version = "0.2.2"
 authors = ["The Rand Project Developers"]
 license = "MIT OR Apache-2.0"
 readme = "README.md"
diff --git a/rand_os/README.md b/rand_os/README.md
index 8ed8c50..7b68b35 100644
--- a/rand_os/README.md
+++ b/rand_os/README.md
@@ -11,6 +11,8 @@
 A random number generator that retrieves randomness straight from the
 operating system.
 
+**This crate is deprecated:** `OsRng` is available in `rand_core` since version 0.5.1.
+
 This crate provides `OsRng` as a shim around
 [getrandom](https://crates.io/crates/getrandom)
 implementing `RngCore` from [rand_core](https://crates.io/crates/rand_core).
diff --git a/rand_os/src/lib.rs b/rand_os/src/lib.rs
index 9090ab8..abfdf79 100644
--- a/rand_os/src/lib.rs
+++ b/rand_os/src/lib.rs
@@ -19,6 +19,8 @@
 
 #![no_std]  // but see getrandom crate
 
+#![deprecated(since="0.2.2", note="OsRng is now provided by rand_core and rand")]
+
 pub use rand_core;  // re-export
 
 use getrandom::getrandom;
@@ -45,6 +47,7 @@
 ///
 /// # Usage example
 /// ```
+/// #![allow(deprecated)]
 /// use rand_os::rand_core::RngCore;
 /// use rand_os::OsRng;
 ///
diff --git a/src/distributions/weighted/mod.rs b/src/distributions/weighted/mod.rs
index 5c2cd97..2711637 100644
--- a/src/distributions/weighted/mod.rs
+++ b/src/distributions/weighted/mod.rs
@@ -84,6 +84,7 @@
 #[derive(Debug, Clone)]
 pub struct WeightedIndex<X: SampleUniform + PartialOrd> {
     cumulative_weights: Vec<X>,
+    total_weight: X,
     weight_distribution: X::Sampler,
 }
 
@@ -125,9 +126,98 @@
         if total_weight == zero {
             return Err(WeightedError::AllWeightsZero);
         }
-        let distr = X::Sampler::new(zero, total_weight);
+        let distr = X::Sampler::new(zero, total_weight.clone());
 
-        Ok(WeightedIndex { cumulative_weights: weights, weight_distribution: distr })
+        Ok(WeightedIndex { cumulative_weights: weights, total_weight, weight_distribution: distr })
+    }
+
+    /// Update a subset of weights, without changing the number of weights.
+    ///
+    /// `new_weights` must be sorted by the index.
+    ///
+    /// Using this method instead of `new` might be more efficient if only a small number of
+    /// weights is modified. No allocations are performed, unless the weight type `X` uses
+    /// allocation internally.
+    ///
+    /// In case of error, `self` is not modified.
+    pub fn update_weights(&mut self, new_weights: &[(usize, &X)]) -> Result<(), WeightedError>
+        where X: for<'a> ::core::ops::AddAssign<&'a X> +
+                 for<'a> ::core::ops::SubAssign<&'a X> +
+                 Clone +
+                 Default {
+        if new_weights.is_empty() {
+            return Ok(());
+        }
+
+        let zero = <X as Default>::default();
+
+        let mut total_weight = self.total_weight.clone();
+
+        // Check for errors first, so we don't modify `self` in case something
+        // goes wrong.
+        let mut prev_i = None;
+        for &(i, w) in new_weights {
+            if let Some(old_i) = prev_i {
+                if old_i >= i {
+                    return Err(WeightedError::InvalidWeight);
+                }
+            }
+            if *w < zero {
+                return Err(WeightedError::InvalidWeight);
+            }
+            if i >= self.cumulative_weights.len() + 1 {
+                return Err(WeightedError::TooMany);
+            }
+
+            let mut old_w = if i < self.cumulative_weights.len() {
+                self.cumulative_weights[i].clone()
+            } else {
+                self.total_weight.clone()
+            };
+            if i > 0 {
+                old_w -= &self.cumulative_weights[i - 1];
+            }
+
+            total_weight -= &old_w;
+            total_weight += w;
+            prev_i = Some(i);
+        }
+        if total_weight == zero {
+            return Err(WeightedError::AllWeightsZero);
+        }
+
+        // Update the weights. Because we checked all the preconditions in the
+        // previous loop, this should never panic.
+        let mut iter = new_weights.iter();
+
+        let mut prev_weight = zero.clone();
+        let mut next_new_weight = iter.next();
+        let &(first_new_index, _) = next_new_weight.unwrap();
+        let mut cumulative_weight = if first_new_index > 0 {
+            self.cumulative_weights[first_new_index - 1].clone()
+        } else {
+            zero.clone() 
+        };
+        for i in first_new_index..self.cumulative_weights.len() {
+            match next_new_weight {
+                Some(&(j, w)) if i == j => {
+                    cumulative_weight += w;
+                    next_new_weight = iter.next();
+                },
+                _ => {
+                    let mut tmp = self.cumulative_weights[i].clone();
+                    tmp -= &prev_weight;  // We know this is positive.
+                    cumulative_weight += &tmp;
+                }
+            }
+            prev_weight = cumulative_weight.clone();
+            core::mem::swap(&mut prev_weight, &mut self.cumulative_weights[i]);
+        }
+
+        self.total_weight = total_weight;
+        self.weight_distribution = X::Sampler::new(zero, self.total_weight.clone());
+
+        Ok(())
     }
 }
 
@@ -201,6 +291,31 @@
         assert_eq!(WeightedIndex::new(&[-10, 20, 1, 30]).unwrap_err(), WeightedError::InvalidWeight);
         assert_eq!(WeightedIndex::new(&[-10]).unwrap_err(), WeightedError::InvalidWeight);
     }
+
+    #[test]
+    fn test_update_weights() {
+        let data = [
+            (&[10u32, 2, 3, 4][..],
+             &[(1, &100), (2, &4)][..],  // positive change
+             &[10, 100, 4, 4][..]),
+            (&[1u32, 2, 3, 0, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7][..],
+             &[(2, &1), (5, &1), (13, &100)][..],  // negative change and last element
+             &[1u32, 2, 1, 0, 5, 1, 7, 1, 2, 3, 4, 5, 6, 100][..]),
+        ];
+
+        for (weights, update, expected_weights) in data.into_iter() {
+            let total_weight = weights.iter().sum::<u32>();
+            let mut distr = WeightedIndex::new(weights.to_vec()).unwrap();
+            assert_eq!(distr.total_weight, total_weight);
+
+            distr.update_weights(update).unwrap();
+            let expected_total_weight = expected_weights.iter().sum::<u32>();
+            let expected_distr = WeightedIndex::new(expected_weights.to_vec()).unwrap();
+            assert_eq!(distr.total_weight, expected_total_weight);
+            assert_eq!(distr.total_weight, expected_distr.total_weight);
+            assert_eq!(distr.cumulative_weights, expected_distr.cumulative_weights);
+        }
+    }
 }
 
 /// Error type returned from `WeightedIndex::new`.
diff --git a/src/lib.rs b/src/lib.rs
index 5d8fa23..53b043c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -50,7 +50,6 @@
 #![doc(test(attr(allow(unused_variables), deny(warnings))))]
 
 #![cfg_attr(not(feature="std"), no_std)]
-#![cfg_attr(all(feature="alloc", not(feature="std")), feature(alloc))]
 #![cfg_attr(all(feature="simd_support", feature="nightly"), feature(stdsimd))]
 
 #![allow(clippy::excessive_precision, clippy::unreadable_literal, clippy::float_cmp)]
@@ -58,9 +57,6 @@
 #[cfg(all(feature="alloc", not(feature="std")))]
 extern crate alloc;
 
-#[cfg(feature = "getrandom")]
-use getrandom_package as getrandom;
-
 #[allow(unused)]
 macro_rules! trace { ($($x:tt)*) => (
     #[cfg(feature = "log")] {
@@ -438,7 +434,7 @@
                 }
             }
         }
-        
+
         impl AsByteSliceMut for [Wrapping<$t>] {
             fn as_byte_slice_mut(&mut self) -> &mut [u8] {
                 if self.len() == 0 {
@@ -602,7 +598,7 @@
         rng.fill(&mut array[..]);
         assert_eq!(array, [x as u32, (x >> 32) as u32]);
         assert_eq!(rng.next_u32(), x as u32);
-        
+
         // Check equivalence using wrapped arrays
         let mut warray = [Wrapping(0u32); 2];
         rng.fill(&mut warray[..]);
diff --git a/src/rngs/mod.rs b/src/rngs/mod.rs
index f9cfe80..abf3243 100644
--- a/src/rngs/mod.rs
+++ b/src/rngs/mod.rs
@@ -116,5 +116,4 @@
 pub use self::std::StdRng;
 #[cfg(feature="std")] pub use self::thread::ThreadRng;
 
-#[cfg(feature="getrandom")] mod os;
-#[cfg(feature="getrandom")] pub use self::os::OsRng;
+#[cfg(feature="getrandom")] pub use rand_core::OsRng;
diff --git a/src/rngs/std.rs b/src/rngs/std.rs
index 22e08ae..8ebe6b8 100644
--- a/src/rngs/std.rs
+++ b/src/rngs/std.rs
@@ -10,8 +10,11 @@
 
 use crate::{RngCore, CryptoRng, Error, SeedableRng};
 
-#[cfg(target_os = "emscripten")] pub(crate) use rand_hc::Hc128Core as Core;
-#[cfg(not(target_os = "emscripten"))] pub(crate) use rand_chacha::ChaCha20Core as Core;
+#[cfg(all(any(test, feature = "std"), target_os = "emscripten"))]
+pub(crate) use rand_hc::Hc128Core as Core;
+#[cfg(all(any(test, feature = "std"), not(target_os = "emscripten")))]
+pub(crate) use rand_chacha::ChaCha20Core as Core;
+
 #[cfg(target_os = "emscripten")] use rand_hc::Hc128Rng as Rng;
 #[cfg(not(target_os = "emscripten"))] use rand_chacha::ChaCha20Rng as Rng;
 
diff --git a/utils/ci/script.sh b/utils/ci/script.sh
index 852a850..bd011d5 100644
--- a/utils/ci/script.sh
+++ b/utils/ci/script.sh
@@ -2,23 +2,56 @@
 
 set -ex
 
+# ----- Options -----
+
+# TARGET enables cross-building
+if [ -z $TARGET ]; then
+    CARGO=cargo
+else
+    CARGO=cross
+    TARGET="--target $TARGET"
+fi
+
+# ALLOC defaults on; is disabled for rustc < 1.36
+if [ -z $ALLOC ]; then
+    ALLOC=1
+fi
+
+# NIGHTLY defaults off
+
+
+# ----- Script -----
+
 main() {
-    cross test --target $TARGET --tests --no-default-features
-  # TODO: add simd_support feature:
-    cross test --target $TARGET --features=log
-    cross test --target $TARGET --examples
-    cross test --target $TARGET --manifest-path rand_core/Cargo.toml
-    cross test --target $TARGET --manifest-path rand_core/Cargo.toml --features=serde1
-    cross test --target $TARGET --manifest-path rand_core/Cargo.toml --no-default-features
-    cross test --target $TARGET --manifest-path rand_distr/Cargo.toml
-    cross test --target $TARGET --manifest-path rand_isaac/Cargo.toml --features=serde1
-    cross test --target $TARGET --manifest-path rand_pcg/Cargo.toml --features=serde1
-    cross test --target $TARGET --manifest-path rand_xorshift/Cargo.toml --features=serde1
-    cross test --target $TARGET --manifest-path rand_xoshiro/Cargo.toml --features=serde1
-    cross test --target $TARGET --manifest-path rand_chacha/Cargo.toml
-    cross test --target $TARGET --manifest-path rand_hc/Cargo.toml
-    cross test --target $TARGET --manifest-path rand_os/Cargo.toml
-    cross test --target $TARGET --manifest-path rand_jitter/Cargo.toml
+  if [ "0$NIGHTLY" -ge 1 ]; then
+    $CARGO test $TARGET --all-features
+    $CARGO test $TARGET --benches --features=nightly
+  else
+    # all stable features:
+    $CARGO test $TARGET --features=serde1,log,small_rng
+  fi
+
+  if [ "$ALLOC" -ge 1 ]; then
+    $CARGO test $TARGET --tests --no-default-features --features=alloc,getrandom,small_rng
+    $CARGO test $TARGET --manifest-path rand_core/Cargo.toml --no-default-features --features=alloc
+  fi
+  
+  $CARGO test $TARGET --tests --no-default-features
+  $CARGO test $TARGET --examples
+  
+  $CARGO test $TARGET --manifest-path rand_core/Cargo.toml
+  $CARGO test $TARGET --manifest-path rand_core/Cargo.toml --no-default-features
+  $CARGO test $TARGET --manifest-path rand_core/Cargo.toml --no-default-features --features=getrandom
+  
+  $CARGO test $TARGET --manifest-path rand_distr/Cargo.toml
+  $CARGO test $TARGET --manifest-path rand_isaac/Cargo.toml --features=serde1
+  $CARGO test $TARGET --manifest-path rand_pcg/Cargo.toml --features=serde1
+  $CARGO test $TARGET --manifest-path rand_xorshift/Cargo.toml --features=serde1
+  $CARGO test $TARGET --manifest-path rand_xoshiro/Cargo.toml
+  $CARGO test $TARGET --manifest-path rand_chacha/Cargo.toml
+  $CARGO test $TARGET --manifest-path rand_hc/Cargo.toml
+  $CARGO test $TARGET --manifest-path rand_jitter/Cargo.toml
+  $CARGO test $TARGET --manifest-path rand_os/Cargo.toml
 }
 
 # we don't run the "test phase" when doing deploys