Modernize the `testcrate` slighty

* Update `rand` dependency
* Drop `cast` in favor of explicit casting or crate-defined
* Move build script to 2018 edition
This commit is contained in:
Alex Crichton 2019-08-19 14:02:08 -07:00
parent 36da64f20e
commit 332220adea
2 changed files with 83 additions and 51 deletions

View File

@ -2,14 +2,14 @@
name = "testcrate" name = "testcrate"
version = "0.1.0" version = "0.1.0"
authors = ["Alex Crichton <alex@alexcrichton.com>"] authors = ["Alex Crichton <alex@alexcrichton.com>"]
edition = "2018"
[lib] [lib]
test = false test = false
doctest = false doctest = false
[build-dependencies] [build-dependencies]
cast = { version = "0.2.2", features = ["x128"] } rand = "0.7"
rand = { version = "0.4", features = ["i128_support"] }
[dependencies.compiler_builtins] [dependencies.compiler_builtins]
path = ".." path = ".."

View File

@ -1,6 +1,5 @@
extern crate cast; use rand::seq::SliceRandom;
extern crate rand; use rand::Rng;
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt; use std::fmt;
use std::fmt::Write as FmtWrite; use std::fmt::Write as FmtWrite;
@ -10,9 +9,6 @@ use std::io::Write;
use std::path::PathBuf; use std::path::PathBuf;
use std::{env, mem}; use std::{env, mem};
use self::cast::{f32, f64, i128, i32, i64, u128, u32, u64};
use self::rand::Rng;
const NTESTS: usize = 1_000; const NTESTS: usize = 1_000;
fn main() { fn main() {
@ -397,7 +393,7 @@ fn main() {
if a.0.is_nan() { if a.0.is_nan() {
return None; return None;
} }
Some(f64(a.0)) Some(f64::from(a.0))
}, },
"builtins::float::extend::__extendsfdf2(a)", "builtins::float::extend::__extendsfdf2(a)",
); );
@ -407,7 +403,7 @@ fn main() {
if a.0.is_nan() { if a.0.is_nan() {
return None; return None;
} }
Some(f64(a.0)) Some(f64::from(a.0))
}, },
"builtins::float::extend::__extendsfdf2vfp(a)", "builtins::float::extend::__extendsfdf2vfp(a)",
); );
@ -415,92 +411,92 @@ fn main() {
// float/conv.rs // float/conv.rs
gen( gen(
|a: MyF64| i64(a.0).ok(), |a: MyF64| i64::cast(a.0),
"builtins::float::conv::__fixdfdi(a)", "builtins::float::conv::__fixdfdi(a)",
); );
gen( gen(
|a: MyF64| i32(a.0).ok(), |a: MyF64| i32::cast(a.0),
"builtins::float::conv::__fixdfsi(a)", "builtins::float::conv::__fixdfsi(a)",
); );
gen( gen(
|a: MyF32| i64(a.0).ok(), |a: MyF32| i64::cast(a.0),
"builtins::float::conv::__fixsfdi(a)", "builtins::float::conv::__fixsfdi(a)",
); );
gen( gen(
|a: MyF32| i32(a.0).ok(), |a: MyF32| i32::cast(a.0),
"builtins::float::conv::__fixsfsi(a)", "builtins::float::conv::__fixsfsi(a)",
); );
gen( gen(
|a: MyF32| i128(a.0).ok(), |a: MyF32| i128::cast(a.0),
"builtins::float::conv::__fixsfti(a)", "builtins::float::conv::__fixsfti(a)",
); );
gen( gen(
|a: MyF64| i128(a.0).ok(), |a: MyF64| i128::cast(a.0),
"builtins::float::conv::__fixdfti(a)", "builtins::float::conv::__fixdfti(a)",
); );
gen( gen(
|a: MyF64| u64(a.0).ok(), |a: MyF64| u64::cast(a.0),
"builtins::float::conv::__fixunsdfdi(a)", "builtins::float::conv::__fixunsdfdi(a)",
); );
gen( gen(
|a: MyF64| u32(a.0).ok(), |a: MyF64| u32::cast(a.0),
"builtins::float::conv::__fixunsdfsi(a)", "builtins::float::conv::__fixunsdfsi(a)",
); );
gen( gen(
|a: MyF32| u64(a.0).ok(), |a: MyF32| u64::cast(a.0),
"builtins::float::conv::__fixunssfdi(a)", "builtins::float::conv::__fixunssfdi(a)",
); );
gen( gen(
|a: MyF32| u32(a.0).ok(), |a: MyF32| u32::cast(a.0),
"builtins::float::conv::__fixunssfsi(a)", "builtins::float::conv::__fixunssfsi(a)",
); );
gen( gen(
|a: MyF32| u128(a.0).ok(), |a: MyF32| u128::cast(a.0),
"builtins::float::conv::__fixunssfti(a)", "builtins::float::conv::__fixunssfti(a)",
); );
gen( gen(
|a: MyF64| u128(a.0).ok(), |a: MyF64| u128::cast(a.0),
"builtins::float::conv::__fixunsdfti(a)", "builtins::float::conv::__fixunsdfti(a)",
); );
gen( gen(
|a: MyI64| Some(f64(a.0)), |a: MyI64| Some(a.0 as f64),
"builtins::float::conv::__floatdidf(a)", "builtins::float::conv::__floatdidf(a)",
); );
gen( gen(
|a: MyI32| Some(f64(a.0)), |a: MyI32| Some(a.0 as f64),
"builtins::float::conv::__floatsidf(a)", "builtins::float::conv::__floatsidf(a)",
); );
gen( gen(
|a: MyI32| Some(f32(a.0)), |a: MyI32| Some(a.0 as f32),
"builtins::float::conv::__floatsisf(a)", "builtins::float::conv::__floatsisf(a)",
); );
gen( gen(
|a: MyU64| Some(f64(a.0)), |a: MyU64| Some(a.0 as f64),
"builtins::float::conv::__floatundidf(a)", "builtins::float::conv::__floatundidf(a)",
); );
gen( gen(
|a: MyU32| Some(f64(a.0)), |a: MyU32| Some(a.0 as f64),
"builtins::float::conv::__floatunsidf(a)", "builtins::float::conv::__floatunsidf(a)",
); );
gen( gen(
|a: MyU32| Some(f32(a.0)), |a: MyU32| Some(a.0 as f32),
"builtins::float::conv::__floatunsisf(a)", "builtins::float::conv::__floatunsisf(a)",
); );
gen( gen(
|a: MyU128| f32(a.0).ok(), |a: MyU128| Some(a.0 as f32),
"builtins::float::conv::__floatuntisf(a)", "builtins::float::conv::__floatuntisf(a)",
); );
if !target_arch_mips { if !target_arch_mips {
gen( gen(
|a: MyI128| Some(f32(a.0)), |a: MyI128| Some(a.0 as f32),
"builtins::float::conv::__floattisf(a)", "builtins::float::conv::__floattisf(a)",
); );
gen( gen(
|a: MyI128| Some(f64(a.0)), |a: MyI128| Some(a.0 as f64),
"builtins::float::conv::__floattidf(a)", "builtins::float::conv::__floattidf(a)",
); );
gen( gen(
|a: MyU128| Some(f64(a.0)), |a: MyU128| Some(a.0 as f64),
"builtins::float::conv::__floatuntidf(a)", "builtins::float::conv::__floatuntidf(a)",
); );
} }
@ -996,7 +992,7 @@ macro_rules! gen_float {
$significand_bits:expr) => { $significand_bits:expr) => {
pub fn $name<R>(rng: &mut R) -> $fty pub fn $name<R>(rng: &mut R) -> $fty
where where
R: Rng, R: Rng + ?Sized,
{ {
const BITS: u8 = $bits; const BITS: u8 = $bits;
const SIGNIFICAND_BITS: u8 = $significand_bits; const SIGNIFICAND_BITS: u8 = $significand_bits;
@ -1015,9 +1011,9 @@ macro_rules! gen_float {
} }
} }
if rng.gen_weighted_bool(10) { if rng.gen_range(0, 10) == 1 {
// Special values // Special values
*rng.choose(&[ *[
-0.0, -0.0,
0.0, 0.0,
::std::$fty::MIN, ::std::$fty::MIN,
@ -1026,9 +1022,10 @@ macro_rules! gen_float {
::std::$fty::NAN, ::std::$fty::NAN,
::std::$fty::INFINITY, ::std::$fty::INFINITY,
-::std::$fty::INFINITY, -::std::$fty::INFINITY,
]) ]
.choose(rng)
.unwrap() .unwrap()
} else if rng.gen_weighted_bool(10) { } else if rng.gen_range(0, 10) == 1 {
// NaN patterns // NaN patterns
mk_f32(rng.gen(), rng.gen(), 0) mk_f32(rng.gen(), rng.gen(), 0)
} else if rng.gen() { } else if rng.gen() {
@ -1053,7 +1050,7 @@ macro_rules! gen_large_float {
$significand_bits:expr) => { $significand_bits:expr) => {
pub fn $name<R>(rng: &mut R) -> $fty pub fn $name<R>(rng: &mut R) -> $fty
where where
R: Rng, R: Rng + ?Sized,
{ {
const BITS: u8 = $bits; const BITS: u8 = $bits;
const SIGNIFICAND_BITS: u8 = $significand_bits; const SIGNIFICAND_BITS: u8 = $significand_bits;
@ -1072,9 +1069,9 @@ macro_rules! gen_large_float {
} }
} }
if rng.gen_weighted_bool(10) { if rng.gen_range(0, 10) == 1 {
// Special values // Special values
*rng.choose(&[ *[
-0.0, -0.0,
0.0, 0.0,
::std::$fty::MIN, ::std::$fty::MIN,
@ -1083,9 +1080,10 @@ macro_rules! gen_large_float {
::std::$fty::NAN, ::std::$fty::NAN,
::std::$fty::INFINITY, ::std::$fty::INFINITY,
-::std::$fty::INFINITY, -::std::$fty::INFINITY,
]) ]
.choose(rng)
.unwrap() .unwrap()
} else if rng.gen_weighted_bool(10) { } else if rng.gen_range(0, 10) == 1 {
// NaN patterns // NaN patterns
mk_f32(rng.gen(), rng.gen(), 0) mk_f32(rng.gen(), rng.gen(), 0)
} else if rng.gen() { } else if rng.gen() {
@ -1102,7 +1100,7 @@ macro_rules! gen_large_float {
gen_large_float!(gen_large_f32, f32, u32, 32, 23); gen_large_float!(gen_large_f32, f32, u32, 32, 23);
gen_large_float!(gen_large_f64, f64, u64, 64, 52); gen_large_float!(gen_large_f64, f64, u64, 64, 52);
trait TestInput: rand::Rand + Hash + Eq + fmt::Debug { trait TestInput: Hash + Eq + fmt::Debug {
fn ty_name() -> String; fn ty_name() -> String;
fn generate_lets(container: &str, cnt: &mut u8) -> String; fn generate_lets(container: &str, cnt: &mut u8) -> String;
fn generate_static(&self, dst: &mut String); fn generate_static(&self, dst: &mut String);
@ -1119,6 +1117,7 @@ where
F: FnMut(A) -> Option<R>, F: FnMut(A) -> Option<R>,
A: TestInput + Copy, A: TestInput + Copy,
R: TestOutput, R: TestOutput,
rand::distributions::Standard: rand::distributions::Distribution<A>,
{ {
let rng = &mut rand::thread_rng(); let rng = &mut rand::thread_rng();
let testname = test.split("::").last().unwrap().split("(").next().unwrap(); let testname = test.split("::").last().unwrap().split("(").next().unwrap();
@ -1207,8 +1206,8 @@ macro_rules! my_float {
} }
} }
impl rand::Rand for $name { impl rand::distributions::Distribution<$name> for rand::distributions::Standard {
fn rand<R: rand::Rng>(r: &mut R) -> $name { fn sample<R: rand::Rng + ?Sized >(&self, r: &mut R) -> $name {
$name($gen(r)) $name($gen(r))
} }
} }
@ -1260,18 +1259,18 @@ macro_rules! my_integer {
} }
} }
impl rand::Rand for $name { impl rand::distributions::Distribution<$name> for rand::distributions::Standard {
fn rand<R: rand::Rng>(rng: &mut R) -> $name { fn sample<R: rand::Rng + ?Sized >(&self, r: &mut R) -> $name {
let bits = (0 as $inner).count_zeros(); let bits = (0 as $inner).count_zeros();
let mut mk = || { let mut mk = || {
if rng.gen_weighted_bool(10) { if r.gen_range(0, 10) == 1 {
*rng.choose(&[ *[
::std::$inner::MAX >> (bits / 2), ::std::$inner::MAX >> (bits / 2),
0, 0,
::std::$inner::MIN >> (bits / 2), ::std::$inner::MIN >> (bits / 2),
]).unwrap() ].choose(r).unwrap()
} else { } else {
rng.gen::<$inner>() r.gen::<$inner>()
} }
}; };
let a = mk(); let a = mk();
@ -1386,3 +1385,36 @@ where
container.to_string() container.to_string()
} }
} }
trait FromFloat<T>: Sized {
fn cast(src: T) -> Option<Self>;
}
macro_rules! from_float {
($($src:ident => $($dst:ident),+);+;) => {
$(
$(
impl FromFloat<$src> for $dst {
fn cast(src: $src) -> Option<$dst> {
use std::{$dst, $src};
if src.is_nan() ||
src.is_infinite() ||
src < std::$dst::MIN as $src ||
src > std::$dst::MAX as $src
{
None
} else {
Some(src as $dst)
}
}
}
)+
)+
}
}
from_float! {
f32 => i32, i64, i128, u32, u64, u128;
f64 => i32, i64, i128, u32, u64, u128;
}