From dcfd3569de06a0df6b49e5bf213fd8887c23c310 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 12:59:38 +0200 Subject: [PATCH 01/28] Clippy: Whitelist a false positive about alignment --- rand_core/src/block.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rand_core/src/block.rs b/rand_core/src/block.rs index 7d222784337..43e0efef53a 100644 --- a/rand_core/src/block.rs +++ b/rand_core/src/block.rs @@ -188,6 +188,7 @@ where ::Results: AsRef<[u32]> + AsMut<[u32]> let read_u64 = |results: &[u32], index| { if cfg!(any(target_endian = "little")) { // requires little-endian CPU + #[allow(clippy::cast_ptr_alignment)] // fase positive let ptr: *const u64 = results[index..=index+1].as_ptr() as *const u64; unsafe { ptr::read_unaligned(ptr) } } else { From c2202a913c3f84ec4a2a432e392594f5b81c4dd9 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 13:05:06 +0200 Subject: [PATCH 02/28] Remove useless annotation --- src/rngs/entropy.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rngs/entropy.rs b/src/rngs/entropy.rs index cfb6490fbfe..1ed59ab1503 100644 --- a/src/rngs/entropy.rs +++ b/src/rngs/entropy.rs @@ -11,7 +11,6 @@ #![allow(deprecated)] // whole module is deprecated use rand_core::{RngCore, CryptoRng, Error}; -#[allow(unused)] use crate::rngs::OsRng; /// An interface returning random data from external source(s), provided From 3808dd2b9ea1ed34f170b9a1e2aa5007e0b2303b Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 13:05:17 +0200 Subject: [PATCH 03/28] Disable noisy clippy lints --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 31f0169e1ae..dcda8fd57fe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,6 +53,8 @@ #![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)] + #[cfg(all(feature="alloc", not(feature="std")))] extern crate alloc; From 74484bf3a54ba6a5a878ad37c57394997d088fab Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 13:16:34 +0200 Subject: [PATCH 04/28] Clippy: Allow float comparisons --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index dcda8fd57fe..5d8fa23b300 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,7 +53,7 @@ #![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)] +#![allow(clippy::excessive_precision, clippy::unreadable_literal, clippy::float_cmp)] #[cfg(all(feature="alloc", not(feature="std")))] extern crate alloc; From fef8f78defa014876a3215a86ddaeadeb06651c8 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 13:17:12 +0200 Subject: [PATCH 05/28] seq: Fix some minor clippy warnings --- src/seq/index.rs | 44 ++++++++++++++++++++++---------------------- src/seq/mod.rs | 9 ++++----- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/seq/index.rs b/src/seq/index.rs index 0c9a477f24f..6fe954e1483 100644 --- a/src/seq/index.rs +++ b/src/seq/index.rs @@ -31,9 +31,9 @@ pub enum IndexVec { impl IndexVec { /// Returns the number of indices pub fn len(&self) -> usize { - match self { - &IndexVec::U32(ref v) => v.len(), - &IndexVec::USize(ref v) => v.len(), + match *self { + IndexVec::U32(ref v) => v.len(), + IndexVec::USize(ref v) => v.len(), } } @@ -42,9 +42,9 @@ impl IndexVec { /// (Note: we cannot implement [`std::ops::Index`] because of lifetime /// restrictions.) pub fn index(&self, index: usize) -> usize { - match self { - &IndexVec::U32(ref v) => v[index] as usize, - &IndexVec::USize(ref v) => v[index], + match *self { + IndexVec::U32(ref v) => v[index] as usize, + IndexVec::USize(ref v) => v[index], } } @@ -57,10 +57,10 @@ impl IndexVec { } /// Iterate over the indices as a sequence of `usize` values - pub fn iter<'a>(&'a self) -> IndexVecIter<'a> { - match self { - &IndexVec::U32(ref v) => IndexVecIter::U32(v.iter()), - &IndexVec::USize(ref v) => IndexVecIter::USize(v.iter()), + pub fn iter(&self) -> IndexVecIter<'_> { + match *self { + IndexVec::U32(ref v) => IndexVecIter::U32(v.iter()), + IndexVec::USize(ref v) => IndexVecIter::USize(v.iter()), } } @@ -110,16 +110,16 @@ impl<'a> Iterator for IndexVecIter<'a> { type Item = usize; fn next(&mut self) -> Option { use self::IndexVecIter::*; - match self { - &mut U32(ref mut iter) => iter.next().map(|i| *i as usize), - &mut USize(ref mut iter) => iter.next().cloned(), + match *self { + U32(ref mut iter) => iter.next().map(|i| *i as usize), + USize(ref mut iter) => iter.next().cloned(), } } fn size_hint(&self) -> (usize, Option) { - match self { - &IndexVecIter::U32(ref v) => v.size_hint(), - &IndexVecIter::USize(ref v) => v.size_hint(), + match *self { + IndexVecIter::U32(ref v) => v.size_hint(), + IndexVecIter::USize(ref v) => v.size_hint(), } } } @@ -138,17 +138,17 @@ impl Iterator for IndexVecIntoIter { fn next(&mut self) -> Option { use self::IndexVecIntoIter::*; - match self { - &mut U32(ref mut v) => v.next().map(|i| i as usize), - &mut USize(ref mut v) => v.next(), + match *self { + U32(ref mut v) => v.next().map(|i| i as usize), + USize(ref mut v) => v.next(), } } fn size_hint(&self) -> (usize, Option) { use self::IndexVecIntoIter::*; - match self { - &U32(ref v) => v.size_hint(), - &USize(ref v) => v.size_hint(), + match *self { + U32(ref v) => v.size_hint(), + USize(ref v) => v.size_hint(), } } } diff --git a/src/seq/mod.rs b/src/seq/mod.rs index 1f3d103d495..cec9bb1f505 100644 --- a/src/seq/mod.rs +++ b/src/seq/mod.rs @@ -265,13 +265,12 @@ pub trait IteratorRandom: Iterator + Sized { loop { if lower > 1 { let ix = gen_index(rng, lower + consumed); - let skip; - if ix < lower { + let skip = if ix < lower { result = self.nth(ix); - skip = lower - (ix + 1); + lower - (ix + 1) } else { - skip = lower; - } + lower + }; if upper == Some(lower) { return result; } From d74c6035cfbc6ac3d4e3c791721115e0a5d856d8 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 13:20:06 +0200 Subject: [PATCH 06/28] Implement `IndexVec::is_empty` --- src/seq/index.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/seq/index.rs b/src/seq/index.rs index 6fe954e1483..85786fa85b5 100644 --- a/src/seq/index.rs +++ b/src/seq/index.rs @@ -37,6 +37,14 @@ impl IndexVec { } } + /// Returns `true` if the length is 0. + pub fn is_empty(&self) -> bool { + match *self { + IndexVec::U32(ref v) => v.is_empty(), + IndexVec::USize(ref v) => v.is_empty(), + } + } + /// Return the value at the given `index`. /// /// (Note: we cannot implement [`std::ops::Index`] because of lifetime From 4af56712963d60e7725d7b9399ccf277e1b0f0e6 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 13:24:44 +0200 Subject: [PATCH 07/28] Fix a few minor clippy warnings --- src/rngs/adapter/read.rs | 2 +- src/rngs/adapter/reseeding.rs | 3 ++- src/rngs/mock.rs | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/rngs/adapter/read.rs b/src/rngs/adapter/read.rs index c64230f3059..901462ea7ca 100644 --- a/src/rngs/adapter/read.rs +++ b/src/rngs/adapter/read.rs @@ -72,7 +72,7 @@ impl RngCore for ReadRng { } fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - if dest.len() == 0 { return Ok(()); } + if dest.is_empty() { return Ok(()); } // Use `std::io::read_exact`, which retries on `ErrorKind::Interrupted`. self.reader.read_exact(dest).map_err(|e| Error::new(ReadError(e))) } diff --git a/src/rngs/adapter/reseeding.rs b/src/rngs/adapter/reseeding.rs index b05c05247e9..ec88efe218f 100644 --- a/src/rngs/adapter/reseeding.rs +++ b/src/rngs/adapter/reseeding.rs @@ -225,6 +225,7 @@ where R: BlockRngCore + SeedableRng, results: &mut ::Results, global_fork_counter: usize) { + #![allow(clippy::if_same_then_else)] // false positive if self.is_forked(global_fork_counter) { info!("Fork detected, reseeding RNG"); } else { @@ -300,7 +301,7 @@ mod fork { } pub fn register_fork_handler() { - if FORK_HANDLER_REGISTERED.load(Ordering::Relaxed) == false { + if !FORK_HANDLER_REGISTERED.load(Ordering::Relaxed) { unsafe { libc::pthread_atfork(None, None, Some(fork_handler)) }; FORK_HANDLER_REGISTERED.store(true, Ordering::Relaxed); } diff --git a/src/rngs/mock.rs b/src/rngs/mock.rs index 4e8e74c2782..b4081daf355 100644 --- a/src/rngs/mock.rs +++ b/src/rngs/mock.rs @@ -58,6 +58,7 @@ impl RngCore for StepRng { #[inline] fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - Ok(self.fill_bytes(dest)) + self.fill_bytes(dest); + Ok(()) } } From 805d9460ac0695657d1e7e84e4a0c59824762add Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 13:29:09 +0200 Subject: [PATCH 08/28] Replace some transmutes with safe code --- src/distributions/float.rs | 4 +--- src/distributions/utils.rs | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/distributions/float.rs b/src/distributions/float.rs index ca1e79d341d..bda523ad485 100644 --- a/src/distributions/float.rs +++ b/src/distributions/float.rs @@ -95,9 +95,7 @@ macro_rules! float_impls { // The exponent is encoded using an offset-binary representation let exponent_bits: $u_scalar = (($exponent_bias + exponent) as $u_scalar) << $fraction_bits; - // TODO: use from_bits when min compiler > 1.25 (see #545) - // $ty::from_bits(self | exponent_bits) - unsafe{ mem::transmute(self | exponent_bits) } + $ty::from_bits(self | exponent_bits) } } diff --git a/src/distributions/utils.rs b/src/distributions/utils.rs index fb482a86cae..8f8b49d7800 100644 --- a/src/distributions/utils.rs +++ b/src/distributions/utils.rs @@ -308,13 +308,13 @@ macro_rules! scalar_float_impl { #[inline] fn to_bits(self) -> Self::Bits { - unsafe { ::core::mem::transmute(self) } + self.to_bits() } #[inline] fn from_bits(v: Self::Bits) -> Self { // It turns out the safety issues with sNaN were overblown! Hooray! - unsafe { ::core::mem::transmute(v) } + Self::from_bits(v) } } From ce583e01e051361c8a915ed8d451f644787a622e Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 13:30:48 +0200 Subject: [PATCH 09/28] Prefer `From` over `as` --- src/distributions/integer.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/distributions/integer.rs b/src/distributions/integer.rs index 31eb237e9f8..5238339a026 100644 --- a/src/distributions/integer.rs +++ b/src/distributions/integer.rs @@ -52,8 +52,8 @@ impl Distribution for Standard { #[inline] fn sample(&self, rng: &mut R) -> u128 { // Use LE; we explicitly generate one value before the next. - let x = rng.next_u64() as u128; - let y = rng.next_u64() as u128; + let x = u128::from(rng.next_u64()); + let y = u128::from(rng.next_u64()); (y << 64) | x } } From 047fc24c0e8ab6f0285ea4127c4ec7297c1f938e Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 13:44:39 +0200 Subject: [PATCH 10/28] Uniform: Fix some clippy lints --- src/distributions/uniform.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/distributions/uniform.rs b/src/distributions/uniform.rs index f07fba95374..8c90f4e4bd2 100644 --- a/src/distributions/uniform.rs +++ b/src/distributions/uniform.rs @@ -380,7 +380,7 @@ macro_rules! uniform_int_impl { let range = high.wrapping_sub(low).wrapping_add(1) as $unsigned; let ints_to_reject = if range > 0 { - let range = range as $u_large; + let range = $u_large::from(range); (unsigned_max - range + 1) % range } else { 0 @@ -865,8 +865,8 @@ impl UniformSampler for UniformDuration { let mut high_n = high.subsec_nanos(); if high_n < low_n { - high_s = high_s - 1; - high_n = high_n + 1_000_000_000; + high_s -= 1; + high_n += 1_000_000_000; } let mode = if low_s == high_s { @@ -877,10 +877,10 @@ impl UniformSampler for UniformDuration { } else { let max = high_s .checked_mul(1_000_000_000) - .and_then(|n| n.checked_add(high_n as u64)); + .and_then(|n| n.checked_add(u64::from(high_n))); if let Some(higher_bound) = max { - let lower_bound = low_s * 1_000_000_000 + low_n as u64; + let lower_bound = low_s * 1_000_000_000 + u64::from(low_n); UniformDurationMode::Medium { nanos: Uniform::new_inclusive(lower_bound, higher_bound), } From 8f8f836f79bd2b6c73e8d0abfae1ee8ae5a80663 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 13:48:49 +0200 Subject: [PATCH 11/28] Fix some minor clippy lints --- src/distributions/mod.rs | 2 +- src/distributions/other.rs | 3 ++- src/seq/index.rs | 8 +++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/distributions/mod.rs b/src/distributions/mod.rs index 693e0f97fe6..02ece6f98ef 100644 --- a/src/distributions/mod.rs +++ b/src/distributions/mod.rs @@ -213,7 +213,7 @@ pub trait Distribution { { DistIter { distr: self, - rng: rng, + rng, phantom: ::core::marker::PhantomData, } } diff --git a/src/distributions/other.rs b/src/distributions/other.rs index a3af1dc8415..6ec04734842 100644 --- a/src/distributions/other.rs +++ b/src/distributions/other.rs @@ -11,7 +11,7 @@ use core::char; use core::num::Wrapping; -use crate::{Rng}; +use crate::Rng; use crate::distributions::{Distribution, Standard, Uniform}; // ----- Sampling distributions ----- @@ -116,6 +116,7 @@ macro_rules! tuple_impl { } impl Distribution<()> for Standard { + #[allow(clippy::unused_unit)] #[inline] fn sample(&self, _: &mut R) -> () { () } } diff --git a/src/seq/index.rs b/src/seq/index.rs index 85786fa85b5..7d4ffdcf4ee 100644 --- a/src/seq/index.rs +++ b/src/seq/index.rs @@ -247,11 +247,9 @@ where R: Rng + ?Sized { indices.insert(pos, j); continue; } - } else { - if indices.contains(&t) { - indices.push(j); - continue; - } + } else if indices.contains(&t) { + indices.push(j); + continue; } indices.push(t); } From 553088ffabf5533d561e90d99f5eba001f8d5956 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 13:53:42 +0200 Subject: [PATCH 12/28] Bernoulli: Fix some clippy lints --- src/distributions/bernoulli.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/distributions/bernoulli.rs b/src/distributions/bernoulli.rs index f7bdae46947..eadd0563b05 100644 --- a/src/distributions/bernoulli.rs +++ b/src/distributions/bernoulli.rs @@ -96,13 +96,13 @@ impl Bernoulli { /// return `true`. If `numerator == 0` it will always return `false`. #[inline] pub fn from_ratio(numerator: u32, denominator: u32) -> Result { - if !(numerator <= denominator) { + if numerator > denominator { return Err(BernoulliError::InvalidProbability); } if numerator == denominator { return Ok(Bernoulli { p_int: ALWAYS_TRUE }) } - let p_int = ((numerator as f64 / denominator as f64) * SCALE) as u64; + let p_int = ((f64::from(numerator) / f64::from(denominator)) * SCALE) as u64; Ok(Bernoulli { p_int }) } } From 60107ebd49d487c6f58a0eab6cdaa48acb754337 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 13:54:01 +0200 Subject: [PATCH 13/28] Ignore clippy lints in deprecated code --- src/distributions/binomial.rs | 1 + src/distributions/cauchy.rs | 1 + src/distributions/dirichlet.rs | 1 + src/distributions/unit_circle.rs | 1 + src/distributions/unit_sphere.rs | 1 + 5 files changed, 5 insertions(+) diff --git a/src/distributions/binomial.rs b/src/distributions/binomial.rs index 977e3ce026b..8fc290aae99 100644 --- a/src/distributions/binomial.rs +++ b/src/distributions/binomial.rs @@ -9,6 +9,7 @@ //! The binomial distribution. #![allow(deprecated)] +#![allow(clippy::all)] use crate::Rng; use crate::distributions::{Distribution, Uniform}; diff --git a/src/distributions/cauchy.rs b/src/distributions/cauchy.rs index 61ea95dd02c..0a5d1497acd 100644 --- a/src/distributions/cauchy.rs +++ b/src/distributions/cauchy.rs @@ -9,6 +9,7 @@ //! The Cauchy distribution. #![allow(deprecated)] +#![allow(clippy::all)] use crate::Rng; use crate::distributions::Distribution; diff --git a/src/distributions/dirichlet.rs b/src/distributions/dirichlet.rs index e9352446128..1ce01fdd0f2 100644 --- a/src/distributions/dirichlet.rs +++ b/src/distributions/dirichlet.rs @@ -9,6 +9,7 @@ //! The dirichlet distribution. #![allow(deprecated)] +#![allow(clippy::all)] use crate::Rng; use crate::distributions::Distribution; diff --git a/src/distributions/unit_circle.rs b/src/distributions/unit_circle.rs index 1f3cb77a207..56e75b600cd 100644 --- a/src/distributions/unit_circle.rs +++ b/src/distributions/unit_circle.rs @@ -7,6 +7,7 @@ // except according to those terms. #![allow(deprecated)] +#![allow(clippy::all)] use crate::Rng; use crate::distributions::{Distribution, Uniform}; diff --git a/src/distributions/unit_sphere.rs b/src/distributions/unit_sphere.rs index 2a224cbe5ec..188f48ca19a 100644 --- a/src/distributions/unit_sphere.rs +++ b/src/distributions/unit_sphere.rs @@ -7,6 +7,7 @@ // except according to those terms. #![allow(deprecated)] +#![allow(clippy::all)] use crate::Rng; use crate::distributions::{Distribution, Uniform}; From 6947154d5f9247e9e6744cb47c603105a51b84ce Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 14:04:13 +0200 Subject: [PATCH 14/28] rand_core: Fix clippy warnings --- rand_core/src/block.rs | 6 ++++-- rand_core/src/lib.rs | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/rand_core/src/block.rs b/rand_core/src/block.rs index 43e0efef53a..5e8a6efbc48 100644 --- a/rand_core/src/block.rs +++ b/rand_core/src/block.rs @@ -234,7 +234,8 @@ where ::Results: AsRef<[u32]> + AsMut<[u32]> #[inline(always)] fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - Ok(self.fill_bytes(dest)) + self.fill_bytes(dest); + Ok(()) } } @@ -409,7 +410,8 @@ where ::Results: AsRef<[u64]> + AsMut<[u64]> #[inline(always)] fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - Ok(self.fill_bytes(dest)) + self.fill_bytes(dest); + Ok(()) } } diff --git a/rand_core/src/lib.rs b/rand_core/src/lib.rs index e210b5eca37..babea55ad1a 100644 --- a/rand_core/src/lib.rs +++ b/rand_core/src/lib.rs @@ -35,6 +35,8 @@ #![deny(missing_debug_implementations)] #![doc(test(attr(allow(unused_variables), deny(warnings))))] +#![allow(clippy::unreadable_literal)] + #![cfg_attr(not(feature="std"), no_std)] #![cfg_attr(all(feature="alloc", not(feature="std")), feature(alloc))] From 78c470e5f3ce6f5cf1d377e5dd658bc04bf8e4b2 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 14:08:57 +0200 Subject: [PATCH 15/28] rand_pcg: Fix clippy warnings --- rand_pcg/src/lib.rs | 2 ++ rand_pcg/src/pcg128.rs | 14 ++++++++------ rand_pcg/src/pcg64.rs | 3 ++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/rand_pcg/src/lib.rs b/rand_pcg/src/lib.rs index 9ebfb0bda57..22ba4a05d32 100644 --- a/rand_pcg/src/lib.rs +++ b/rand_pcg/src/lib.rs @@ -35,6 +35,8 @@ #![deny(missing_docs)] #![deny(missing_debug_implementations)] +#![allow(clippy::unreadable_literal)] + #![no_std] mod pcg64; diff --git a/rand_pcg/src/pcg128.rs b/rand_pcg/src/pcg128.rs index eb462f7de66..f0e4c191acd 100644 --- a/rand_pcg/src/pcg128.rs +++ b/rand_pcg/src/pcg128.rs @@ -86,8 +86,8 @@ impl SeedableRng for Lcg128Xsl64 { 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); + let state = u128::from(seed_u64[0]) | (u128::from(seed_u64[1]) << 64); + let incr = u128::from(seed_u64[2]) | (u128::from(seed_u64[3]) << 64); // The increment must be odd, hence we discard one bit: Lcg128Xsl64::from_state_incr(state, incr | 1) @@ -113,7 +113,8 @@ impl RngCore for Lcg128Xsl64 { #[inline] fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - Ok(self.fill_bytes(dest)) + self.fill_bytes(dest); + Ok(()) } } @@ -166,8 +167,8 @@ impl SeedableRng for Mcg128Xsl64 { // Read as if a little-endian u128 value: let mut seed_u64 = [0u64; 2]; le::read_u64_into(&seed, &mut seed_u64); - let state = (seed_u64[0] as u128) | - (seed_u64[1] as u128) << 64; + let state = u128::from(seed_u64[0]) | + u128::from(seed_u64[1]) << 64; Mcg128Xsl64::new(state) } } @@ -191,7 +192,8 @@ impl RngCore for Mcg128Xsl64 { #[inline] fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - Ok(self.fill_bytes(dest)) + self.fill_bytes(dest); + Ok(()) } } diff --git a/rand_pcg/src/pcg64.rs b/rand_pcg/src/pcg64.rs index dd145303a6c..fadc6dcdeeb 100644 --- a/rand_pcg/src/pcg64.rs +++ b/rand_pcg/src/pcg64.rs @@ -121,6 +121,7 @@ impl RngCore for Lcg64Xsh32 { #[inline] fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - Ok(self.fill_bytes(dest)) + self.fill_bytes(dest); + Ok(()) } } From 1c516ebd663113b770402c19be9c36e4cd778fbd Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 14:10:45 +0200 Subject: [PATCH 16/28] rand_pcg: Replace transmutes with safe code --- rand_pcg/src/pcg128.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/rand_pcg/src/pcg128.rs b/rand_pcg/src/pcg128.rs index f0e4c191acd..311a41b29d8 100644 --- a/rand_pcg/src/pcg128.rs +++ b/rand_pcg/src/pcg128.rs @@ -14,7 +14,6 @@ const MULTIPLIER: u128 = 0x2360_ED05_1FC6_5DA4_4385_DF64_9FCC_F645; use core::fmt; -use core::mem::transmute; use rand_core::{RngCore, SeedableRng, Error, le}; #[cfg(feature="serde1")] use serde::{Serialize, Deserialize}; @@ -215,16 +214,12 @@ fn fill_bytes_impl(rng: &mut R, dest: &mut [u8]) { 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()) - }; + let chunk: [u8; 8] = rng.next_u64().to_le_bytes(); l.copy_from_slice(&chunk); } let n = left.len(); if n > 0 { - let chunk: [u8; 8] = unsafe { - transmute(rng.next_u64().to_le()) - }; + let chunk: [u8; 8] = rng.next_u64().to_le_bytes(); left.copy_from_slice(&chunk[..n]); } } From 183fadb81e09c01da3597a10477e2f22618a3b76 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 14:12:35 +0200 Subject: [PATCH 17/28] rand_core: Replace transmutes with safe code --- rand_core/src/impls.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/rand_core/src/impls.rs b/rand_core/src/impls.rs index 4978ae42d2a..dee4ed11e6b 100644 --- a/rand_core/src/impls.rs +++ b/rand_core/src/impls.rs @@ -17,7 +17,6 @@ //! to/from byte sequences, and since its purpose is reproducibility, //! non-reproducible sources (e.g. `OsRng`) need not bother with it. -use core::intrinsics::transmute; use core::ptr::copy_nonoverlapping; use core::slice; use core::cmp::min; @@ -44,21 +43,15 @@ pub fn fill_bytes_via_next(rng: &mut R, dest: &mut [u8]) { 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()) - }; + let chunk: [u8; 8] = rng.next_u64().to_le_bytes(); l.copy_from_slice(&chunk); } let n = left.len(); if n > 4 { - let chunk: [u8; 8] = unsafe { - transmute(rng.next_u64().to_le()) - }; + let chunk: [u8; 8] = rng.next_u64().to_le_bytes(); left.copy_from_slice(&chunk[..n]); } else if n > 0 { - let chunk: [u8; 4] = unsafe { - transmute(rng.next_u32().to_le()) - }; + let chunk: [u8; 4] = rng.next_u32().to_le_bytes(); left.copy_from_slice(&chunk[..n]); } } From 80f35711032dfdccac32d02e3761c8cfb171f590 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 14:13:57 +0200 Subject: [PATCH 18/28] rand_xoshiro: Fix clippy warnings --- rand_xoshiro/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rand_xoshiro/src/lib.rs b/rand_xoshiro/src/lib.rs index 42ee9633e19..b851b9c3aaf 100644 --- a/rand_xoshiro/src/lib.rs +++ b/rand_xoshiro/src/lib.rs @@ -62,7 +62,7 @@ #![deny(missing_docs)] #![deny(missing_debug_implementations)] -#![cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))] +#![allow(clippy::unreadable_literal)] #![no_std] #[macro_use] From b92db7cbbaabfefc89d9b8b2178420f8cf65b7aa Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 14:17:07 +0200 Subject: [PATCH 19/28] rand_chacha: Replace transmute with safe code --- rand_chacha/src/chacha.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rand_chacha/src/chacha.rs b/rand_chacha/src/chacha.rs index a4c9552a909..b1b89e0ff59 100644 --- a/rand_chacha/src/chacha.rs +++ b/rand_chacha/src/chacha.rs @@ -79,7 +79,7 @@ macro_rules! chacha_impl { fn generate(&mut self, r: &mut Self::Results) { // Fill slice of words by writing to equivalent slice of bytes, then fixing endianness. self.state.refill4($rounds, unsafe { - core::mem::transmute::<&mut Array64, &mut [u8; 256]>(&mut *r) + &mut *(&mut *r as *mut Array64 as *mut [u8; 256]) }); for x in r.as_mut() { *x = x.to_le(); From 1b40a2b474c911584f8f506ed01a66b8b6a3f535 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 14:18:29 +0200 Subject: [PATCH 20/28] rand_xorshift: Fix clippy warnings --- rand_xorshift/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rand_xorshift/src/lib.rs b/rand_xorshift/src/lib.rs index acdee56be75..b9fef23012b 100644 --- a/rand_xorshift/src/lib.rs +++ b/rand_xorshift/src/lib.rs @@ -71,7 +71,8 @@ impl RngCore for XorShiftRng { } fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - Ok(self.fill_bytes(dest)) + self.fill_bytes(dest); + Ok(()) } } From 13fa09c48e07d1636328c88480e9b5eeaef93abf Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 14:24:52 +0200 Subject: [PATCH 21/28] rand_distr: Prefer `Into` over `as` --- rand_distr/src/utils.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rand_distr/src/utils.rs b/rand_distr/src/utils.rs index c275d0e5cba..75b350053f3 100644 --- a/rand_distr/src/utils.rs +++ b/rand_distr/src/utils.rs @@ -88,9 +88,9 @@ impl Float for f32 { fn tan(self) -> Self { self.tan() } #[inline] fn log_gamma(self) -> Self { - let result = log_gamma(self as f64); - assert!(result <= ::core::f32::MAX as f64); - assert!(result >= ::core::f32::MIN as f64); + let result = log_gamma(self.into()); + assert!(result <= ::core::f32::MAX.into()); + assert!(result >= ::core::f32::MIN.into()); result as f32 } } From bab3a37e99426c5627f1f1f8b3d59650f1b547d1 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 14:25:16 +0200 Subject: [PATCH 22/28] rand_distr: Disable noisy clippy lints --- rand_distr/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rand_distr/src/lib.rs b/rand_distr/src/lib.rs index 070194f1972..a0ac80047ca 100644 --- a/rand_distr/src/lib.rs +++ b/rand_distr/src/lib.rs @@ -13,6 +13,8 @@ #![deny(missing_docs)] #![deny(missing_debug_implementations)] +#![allow(clippy::excessive_precision, clippy::float_cmp)] + //! Generating random samples from probability distributions. //! //! ## Re-exports From a983df4c2ab833d3a08a8e29c4df96e66c3854a4 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 14:30:03 +0200 Subject: [PATCH 23/28] rand_distr: Disable some more noisy lints --- rand_distr/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rand_distr/src/lib.rs b/rand_distr/src/lib.rs index a0ac80047ca..baf65ed07a7 100644 --- a/rand_distr/src/lib.rs +++ b/rand_distr/src/lib.rs @@ -13,7 +13,8 @@ #![deny(missing_docs)] #![deny(missing_debug_implementations)] -#![allow(clippy::excessive_precision, clippy::float_cmp)] +#![allow(clippy::excessive_precision, clippy::float_cmp, clippy::unreadable_literal)] +#![allow(clippy::neg_cmp_op_on_partial_ord)] // suggested fix too verbose //! Generating random samples from probability distributions. //! From 4607c32e06aebde2fbfb44be763c4ffd7c78b5a9 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 14:30:36 +0200 Subject: [PATCH 24/28] Dirichlet: Prefer iterators over index variables --- rand_distr/src/dirichlet.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/rand_distr/src/dirichlet.rs b/rand_distr/src/dirichlet.rs index b4ef530c075..71cf73c9033 100644 --- a/rand_distr/src/dirichlet.rs +++ b/rand_distr/src/dirichlet.rs @@ -58,8 +58,8 @@ where StandardNormal: Distribution, Exp1: Distribution, Open01: Distributi if a.len() < 2 { return Err(Error::AlphaTooShort); } - for i in 0..a.len() { - if !(a[i] > N::from(0.0)) { + for &ai in &a { + if !(ai > N::from(0.0)) { return Err(Error::AlphaTooSmall); } } @@ -92,14 +92,14 @@ where StandardNormal: Distribution, Exp1: Distribution, Open01: Distributi let mut samples = vec![N::from(0.0); n]; let mut sum = N::from(0.0); - for i in 0..n { - let g = Gamma::new(self.alpha[i], N::from(1.0)).unwrap(); - samples[i] = g.sample(rng); - sum += samples[i]; + for (s, &a) in samples.iter_mut().zip(self.alpha.iter()) { + let g = Gamma::new(a, N::from(1.0)).unwrap(); + *s = g.sample(rng); + sum += *s; } let invacc = N::from(1.0) / sum; - for i in 0..n { - samples[i] *= invacc; + for s in samples.iter_mut() { + *s *= invacc; } samples } From 6d79ebddd37606dfe0687aa372f21caf8b8801f7 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 9 Jul 2019 14:32:45 +0200 Subject: [PATCH 25/28] rand_distr: Fix remaining clippy warnings --- rand_distr/src/binomial.rs | 1 + rand_distr/src/cauchy.rs | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rand_distr/src/binomial.rs b/rand_distr/src/binomial.rs index f58148c130e..0e6bf9a1e18 100644 --- a/rand_distr/src/binomial.rs +++ b/rand_distr/src/binomial.rs @@ -65,6 +65,7 @@ fn f64_to_i64(x: f64) -> i64 { } impl Distribution for Binomial { + #[allow(clippy::many_single_char_names)] // Same names as in the reference. fn sample(&self, rng: &mut R) -> u64 { // Handle these values directly. if self.p == 0.0 { diff --git a/rand_distr/src/cauchy.rs b/rand_distr/src/cauchy.rs index 37ec28e59b2..6b0e7c6cf33 100644 --- a/rand_distr/src/cauchy.rs +++ b/rand_distr/src/cauchy.rs @@ -66,8 +66,7 @@ where Standard: Distribution // note that π/2 is not exactly representable, even if x=0.5 the result is finite let comp_dev = (N::pi() * x).tan(); // shift and scale according to parameters - let result = self.median + self.scale * comp_dev; - result + self.median + self.scale * comp_dev } } From 1510b6ce7b6512d5256773e7b8bc4df326157608 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Mon, 22 Jul 2019 10:31:45 +0200 Subject: [PATCH 26/28] Fix typo --- rand_core/src/block.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rand_core/src/block.rs b/rand_core/src/block.rs index 5e8a6efbc48..0ab7458377f 100644 --- a/rand_core/src/block.rs +++ b/rand_core/src/block.rs @@ -188,7 +188,7 @@ where ::Results: AsRef<[u32]> + AsMut<[u32]> let read_u64 = |results: &[u32], index| { if cfg!(any(target_endian = "little")) { // requires little-endian CPU - #[allow(clippy::cast_ptr_alignment)] // fase positive + #[allow(clippy::cast_ptr_alignment)] // false positive let ptr: *const u64 = results[index..=index+1].as_ptr() as *const u64; unsafe { ptr::read_unaligned(ptr) } } else { From cf1b67cf8dff6486e01e137f01563bc06cf0b32c Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 23 Jul 2019 12:07:30 +0200 Subject: [PATCH 27/28] Don't reimplement `to_bits` and `from_bits` for floats They are provided by `core` since Rust 1.20. --- src/distributions/utils.rs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/distributions/utils.rs b/src/distributions/utils.rs index 8f8b49d7800..3af4e86fdec 100644 --- a/src/distributions/utils.rs +++ b/src/distributions/utils.rs @@ -249,13 +249,9 @@ pub(crate) trait FloatSIMDUtils { /// Implement functions available in std builds but missing from core primitives #[cfg(not(std))] pub(crate) trait Float : Sized { - type Bits; - fn is_nan(self) -> bool; fn is_infinite(self) -> bool; fn is_finite(self) -> bool; - fn to_bits(self) -> Self::Bits; - fn from_bits(v: Self::Bits) -> Self; } /// Implement functions on f32/f64 to give them APIs similar to SIMD types @@ -289,8 +285,6 @@ macro_rules! scalar_float_impl { ($ty:ident, $uty:ident) => { #[cfg(not(std))] impl Float for $ty { - type Bits = $uty; - #[inline] fn is_nan(self) -> bool { self != self @@ -305,17 +299,6 @@ macro_rules! scalar_float_impl { fn is_finite(self) -> bool { !(self.is_nan() || self.is_infinite()) } - - #[inline] - fn to_bits(self) -> Self::Bits { - self.to_bits() - } - - #[inline] - fn from_bits(v: Self::Bits) -> Self { - // It turns out the safety issues with sNaN were overblown! Hooray! - Self::from_bits(v) - } } impl FloatSIMDUtils for $ty { From 2d4a6eef66a379f42488c6892f830fbea4e90503 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Thu, 25 Jul 2019 14:13:01 +0200 Subject: [PATCH 28/28] IndexVec: Inline most methods They are very small and usually just refering to the implementation of the underlying types. --- src/seq/index.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/seq/index.rs b/src/seq/index.rs index 7d4ffdcf4ee..22a5733f37f 100644 --- a/src/seq/index.rs +++ b/src/seq/index.rs @@ -30,6 +30,7 @@ pub enum IndexVec { impl IndexVec { /// Returns the number of indices + #[inline] pub fn len(&self) -> usize { match *self { IndexVec::U32(ref v) => v.len(), @@ -38,6 +39,7 @@ impl IndexVec { } /// Returns `true` if the length is 0. + #[inline] pub fn is_empty(&self) -> bool { match *self { IndexVec::U32(ref v) => v.is_empty(), @@ -49,6 +51,7 @@ impl IndexVec { /// /// (Note: we cannot implement [`std::ops::Index`] because of lifetime /// restrictions.) + #[inline] pub fn index(&self, index: usize) -> usize { match *self { IndexVec::U32(ref v) => v[index] as usize, @@ -57,6 +60,7 @@ impl IndexVec { } /// Return result as a `Vec`. Conversion may or may not be trivial. + #[inline] pub fn into_vec(self) -> Vec { match self { IndexVec::U32(v) => v.into_iter().map(|i| i as usize).collect(), @@ -65,6 +69,7 @@ impl IndexVec { } /// Iterate over the indices as a sequence of `usize` values + #[inline] pub fn iter(&self) -> IndexVecIter<'_> { match *self { IndexVec::U32(ref v) => IndexVecIter::U32(v.iter()), @@ -73,6 +78,7 @@ impl IndexVec { } /// Convert into an iterator over the indices as a sequence of `usize` values + #[inline] pub fn into_iter(self) -> IndexVecIntoIter { match self { IndexVec::U32(v) => IndexVecIntoIter::U32(v.into_iter()), @@ -96,12 +102,14 @@ impl PartialEq for IndexVec { } impl From> for IndexVec { + #[inline] fn from(v: Vec) -> Self { IndexVec::U32(v) } } impl From> for IndexVec { + #[inline] fn from(v: Vec) -> Self { IndexVec::USize(v) } @@ -116,6 +124,7 @@ pub enum IndexVecIter<'a> { impl<'a> Iterator for IndexVecIter<'a> { type Item = usize; + #[inline] fn next(&mut self) -> Option { use self::IndexVecIter::*; match *self { @@ -124,6 +133,7 @@ impl<'a> Iterator for IndexVecIter<'a> { } } + #[inline] fn size_hint(&self) -> (usize, Option) { match *self { IndexVecIter::U32(ref v) => v.size_hint(), @@ -144,6 +154,7 @@ pub enum IndexVecIntoIter { impl Iterator for IndexVecIntoIter { type Item = usize; + #[inline] fn next(&mut self) -> Option { use self::IndexVecIntoIter::*; match *self { @@ -152,6 +163,7 @@ impl Iterator for IndexVecIntoIter { } } + #[inline] fn size_hint(&self) -> (usize, Option) { use self::IndexVecIntoIter::*; match *self {