Repository: rust-ndarray/ndarray (Rust)

Issue:
ndarray-rand doesn't work with rand 0.7
The test program in the ndarray-rand documentation doesn't compile with rand 0.7:

main.rs:
```
use ndarray::Array;
use ndarray_rand::RandomExt;
use rand::distributions::Uniform;

fn main() {
    let a = Array::random((2, 5), Uniform::new(0., 10.));
    println!("{:8.4}", a);
}
```

cargo.toml:
```
[package]
name = "rand-test"
version = "0.1.0"
authors = ["Nathan Goldbaum <nathan12343@gmail.com>"]
edition = "2018"

[dependencies]
ndarray = { version = "0.12", features = ["blas"] }
ndarray-rand = "0.9"
rand = "0.7"
```

compile error:
```
    Updating crates.io index
   Compiling rand-test v0.1.0 (/home/goldbaum/Documents/rand-test)
error[E0277]: the trait bound `rand::distributions::uniform::Uniform<{float}>: rand::distributions::Distribution<_>` is not satisfied
 --> src/main.rs:6:13
  |
6 |     let a = Array::random((2, 5), Uniform::new(0., 10.));
  |             ^^^^^^^^^^^^^ the trait `rand::distributions::Distribution<_>` is not implemented for `rand::distributions::uniform::Uniform<{float}>`
  |
  = note: required by `ndarray_rand::RandomExt::random`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: Could not compile `rand-test`.
```

It works if I specify `rand = "0.6"` in cargo.toml.

Apologies if this issue is documented already and I've missed it.


Discussion:
perhaps i'm hitting https://github.com/rust-lang/rust/issues/22750. I guess if ndarray-rand doesn't support rand 0.7 that should be encoded in ndarray-rand's cargo.toml?
Ah I see it does specify 0.6 explicitly:

https://github.com/rust-ndarray/ndarray/blob/98bf3b6605208b0498bfbcf0f302510ade870e81/ndarray-rand/Cargo.toml#L15
I had the exact same issue a couple of hours ago when working on https://github.com/rust-ndarray/ndarray-linalg/pull/166 - I am little bit surprised by `cargo`'s behavior here, because `ndarray-rand` does indeed specify `0.6`.

I guess, overall, we should aim to keep close to the latest release of `rand` - #659 goes in the right direction.
Any ideas why cargo doesn't use `0.6.0`? 

Is there some complexity with there being a workspace?

Seems unlikely but @ngoldbaum if the `cargo.toml` above includes the full semver version `rand = "0.6.0"` (with the trailing patch version included), does that work?
Argh, I'm sorry, I copy/pasted the `cargo.toml` that works. It does work if I explicitly depend on `rand 0.6` and fails if I use `rand 0.7`. I've edited the issue to reflect that.
Ah OK that makes sense. 

I had thought cargo would use the necessary version for each crate... Or at least state that there were conflicting versions - not sure why this silently breaks...
Yeah, the bad error messages are an instance of rust-lang/rust#22750. Hopefully that'll get fixed at some point. This kind of issue has come up in the past with `ndarray-rand` (e.g. #530).

We should update `ndarray-rand` to use the latest version of `rand` (#659).



Patch:
diff --git a/.travis.yml b/.travis.yml
index 06f592dff..5bb167234 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,7 +4,7 @@ sudo: required
 dist: trusty
 matrix:
   include:
-    - rust: 1.31.0
+    - rust: 1.32.0
       env:
        - FEATURES='test docs'
     - rust: stable
diff --git a/ndarray-rand/Cargo.toml b/ndarray-rand/Cargo.toml
index 0293778d9..024174a28 100644
--- a/ndarray-rand/Cargo.toml
+++ b/ndarray-rand/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "ndarray-rand"
-version = "0.9.0"
+version = "0.10.0"
 edition = "2018"
 authors = ["bluss"]
 license = "MIT/Apache-2.0"
@@ -13,9 +13,15 @@ description = "Constructors for randomized arrays. `rand` integration for `ndarr
 keywords = ["multidimensional", "matrix", "rand", "ndarray"]
 
 [dependencies]
-rand = "0.6.0"
 ndarray = { version = "0.12.0", path = ".." }
 
+[dependencies.rand]
+version = "0.7.0"
+features = ["small_rng"]
+
+[dev-dependencies]
+rand_distr = "0.2.1"
+
 [package.metadata.release]
 no-dev-version = true
 
diff --git a/ndarray-rand/README.rst b/ndarray-rand/README.rst
index cd7e00225..d764b6cbb 100644
--- a/ndarray-rand/README.rst
+++ b/ndarray-rand/README.rst
@@ -1,9 +1,25 @@
 ndarray-rand
 ============
 
+Dependencies
+------------
+
+``ndarray-rand`` depends on ``rand`` 0.7. If you use any other items from
+``rand``, you need to specify a compatible version of ``rand`` in your
+``Cargo.toml``. If you want to use a RNG or distribution from another crate
+with ``ndarray-rand``, you need to make sure that crate also depends on the
+correct version of ``rand``. Otherwise, the compiler will return errors saying
+that the items are not compatible (e.g. that a type doesn't implement a
+necessary trait).
+
 Recent Changes
 --------------
 
+- 0.10.0
+
+  - Require rand 0.7
+  - Require Rust 1.32 or later
+
 - 0.9.0
 
   - Require rand 0.6
diff --git a/ndarray-rand/benches/bench.rs b/ndarray-rand/benches/bench.rs
index 8d47b7b3f..bdd010bc1 100644
--- a/ndarray-rand/benches/bench.rs
+++ b/ndarray-rand/benches/bench.rs
@@ -1,41 +1,29 @@
 #![feature(test)]
 
-extern crate ndarray;
-extern crate ndarray_rand;
-extern crate rand;
 extern crate test;
 
 use ndarray::Array;
 use ndarray_rand::RandomExt;
 use ndarray_rand::F32;
-use rand::distributions::Normal;
-use rand::distributions::Uniform;
+use rand_distr::Normal;
+use rand_distr::Uniform;
 
 use test::Bencher;
 
 #[bench]
 fn uniform_f32(b: &mut Bencher) {
     let m = 100;
-    b.iter(|| {
-        let a = Array::random((m, m), Uniform::new(-1f32, 1.));
-        a
-    });
+    b.iter(|| Array::random((m, m), Uniform::new(-1f32, 1.)));
 }
 
 #[bench]
 fn norm_f32(b: &mut Bencher) {
     let m = 100;
-    b.iter(|| {
-        let a = Array::random((m, m), F32(Normal::new(0., 1.)));
-        a
-    });
+    b.iter(|| Array::random((m, m), F32(Normal::new(0., 1.).unwrap())));
 }
 
 #[bench]
 fn norm_f64(b: &mut Bencher) {
     let m = 100;
-    b.iter(|| {
-        let a = Array::random((m, m), Normal::new(0., 1.));
-        a
-    });
+    b.iter(|| Array::random((m, m), Normal::new(0., 1.).unwrap()));
 }
diff --git a/ndarray-rand/src/lib.rs b/ndarray-rand/src/lib.rs
index 6e2a4591e..69d088096 100644
--- a/ndarray-rand/src/lib.rs
+++ b/ndarray-rand/src/lib.rs
@@ -9,6 +9,14 @@
 //! Constructors for randomized arrays. `rand` integration for `ndarray`.
 //!
 //! See [**`RandomExt`**](trait.RandomExt.html) for usage examples.
+//!
+//! **Note:** `ndarray-rand` depends on `rand` 0.7. If you use any other items
+//! from `rand`, you need to specify a compatible version of `rand` in your
+//! `Cargo.toml`. If you want to use a RNG or distribution from another crate
+//! with `ndarray-rand`, you need to make sure that crate also depends on the
+//! correct version of `rand`. Otherwise, the compiler will return errors
+//! saying that the items are not compatible (e.g. that a type doesn't
+//! implement a necessary trait).
 
 use rand::distributions::Distribution;
 use rand::rngs::SmallRng;
diff --git a/src/lib.rs b/src/lib.rs
index ec097faea..d680a3995 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -61,7 +61,7 @@
 //!     needs matching memory layout to be efficient (with some exceptions).
 //!   + Efficient floating point matrix multiplication even for very large
 //!     matrices; can optionally use BLAS to improve it further.
-//! - **Requires Rust 1.31**
+//! - **Requires Rust 1.32**
 //!
 //! ## Crate Feature Flags
 //!


Test patch:
diff --git a/numeric-tests/Cargo.toml b/numeric-tests/Cargo.toml
index 79e525c83..dc1261512 100644
--- a/numeric-tests/Cargo.toml
+++ b/numeric-tests/Cargo.toml
@@ -8,7 +8,11 @@ publish = false
 approx = "0.3.2"
 ndarray = { path = "..", features = ["approx"] }
 ndarray-rand = { path = "../ndarray-rand/" }
-rand = "0.6.0"
+rand_distr = "0.2.1"
+
+[dependencies.rand]
+version = "0.7.0"
+features = ["small_rng"]
 
 [lib]
 test = false
diff --git a/numeric-tests/tests/accuracy.rs b/numeric-tests/tests/accuracy.rs
index f2b278909..4f61248df 100644
--- a/numeric-tests/tests/accuracy.rs
+++ b/numeric-tests/tests/accuracy.rs
@@ -1,10 +1,11 @@
 extern crate approx;
+extern crate rand_distr;
 extern crate ndarray;
 extern crate ndarray_rand;
 extern crate rand;
 
 use ndarray_rand::{RandomExt, F32};
-use rand::{FromEntropy, Rng};
+use rand::{Rng, SeedableRng};
 use rand::rngs::SmallRng;
 
 use ndarray::prelude::*;
@@ -14,7 +15,7 @@ use ndarray::{
 };
 use ndarray::linalg::general_mat_mul;
 
-use rand::distributions::Normal;
+use rand_distr::Normal;
 
 use approx::{assert_abs_diff_eq, assert_relative_eq};
 
@@ -52,12 +53,12 @@ fn reference_mat_mul<A, S, S2>(lhs: &ArrayBase<S, Ix2>, rhs: &ArrayBase<S2, Ix2>
 fn gen<D>(d: D) -> Array<f32, D>
     where D: Dimension,
 {
-    Array::random(d, F32(Normal::new(0., 1.)))
+    Array::random(d, F32(Normal::new(0., 1.).unwrap()))
 }
 fn gen_f64<D>(d: D) -> Array<f64, D>
     where D: Dimension,
 {
-    Array::random(d, Normal::new(0., 1.))
+    Array::random(d, Normal::new(0., 1.).unwrap())
 }
 
 #[test]