88#![ allow( internal_features) ]  
99#![ allow( unnecessary_transmutes) ]  
1010
11+ #[ path = "../utils/mod.rs" ]  
12+ mod  utils; 
1113use  std:: any:: type_name; 
1214use  std:: cmp:: min; 
1315use  std:: fmt:: { Debug ,  Display ,  LowerHex } ; 
1416use  std:: hint:: black_box; 
1517use  std:: { f32,  f64} ; 
1618
19+ use  utils:: check_nondet; 
20+ 
1721/// Compare the two floats, allowing for $ulp many ULPs of error. 
1822/// 
1923/// ULP means "Units in the Last Place" or "Units of Least Precision". 
@@ -1429,29 +1433,14 @@ fn test_fmuladd() {
14291433
14301434/// `min` and `max` on equal arguments are non-deterministic. 
14311435fn  test_min_max_nondet ( )  { 
1432-     /// Ensure that if we call the closure often enough, we see both `true` and `false.` 
1433- #[ track_caller]  
1434-     fn  ensure_both ( f :  impl  Fn ( )  -> bool )  { 
1435-         let  rounds = 32 ; 
1436-         let  first = f ( ) ; 
1437-         for  _ in  1 ..rounds { 
1438-             if  f ( )  != first { 
1439-                 // We saw two different values! 
1440-                 return ; 
1441-             } 
1442-         } 
1443-         // We saw the same thing N times. 
1444-         panic ! ( "expected non-determinism, got {rounds} times the same result: {first:?}" ) ; 
1445-     } 
1446- 
1447-     ensure_both ( || f16:: min ( 0.0 ,  -0.0 ) . is_sign_positive ( ) ) ; 
1448-     ensure_both ( || f16:: max ( 0.0 ,  -0.0 ) . is_sign_positive ( ) ) ; 
1449-     ensure_both ( || f32:: min ( 0.0 ,  -0.0 ) . is_sign_positive ( ) ) ; 
1450-     ensure_both ( || f32:: max ( 0.0 ,  -0.0 ) . is_sign_positive ( ) ) ; 
1451-     ensure_both ( || f64:: min ( 0.0 ,  -0.0 ) . is_sign_positive ( ) ) ; 
1452-     ensure_both ( || f64:: max ( 0.0 ,  -0.0 ) . is_sign_positive ( ) ) ; 
1453-     ensure_both ( || f128:: min ( 0.0 ,  -0.0 ) . is_sign_positive ( ) ) ; 
1454-     ensure_both ( || f128:: max ( 0.0 ,  -0.0 ) . is_sign_positive ( ) ) ; 
1436+     check_nondet ( || f16:: min ( 0.0 ,  -0.0 ) . is_sign_positive ( ) ) ; 
1437+     check_nondet ( || f16:: max ( 0.0 ,  -0.0 ) . is_sign_positive ( ) ) ; 
1438+     check_nondet ( || f32:: min ( 0.0 ,  -0.0 ) . is_sign_positive ( ) ) ; 
1439+     check_nondet ( || f32:: max ( 0.0 ,  -0.0 ) . is_sign_positive ( ) ) ; 
1440+     check_nondet ( || f64:: min ( 0.0 ,  -0.0 ) . is_sign_positive ( ) ) ; 
1441+     check_nondet ( || f64:: max ( 0.0 ,  -0.0 ) . is_sign_positive ( ) ) ; 
1442+     check_nondet ( || f128:: min ( 0.0 ,  -0.0 ) . is_sign_positive ( ) ) ; 
1443+     check_nondet ( || f128:: max ( 0.0 ,  -0.0 ) . is_sign_positive ( ) ) ; 
14551444} 
14561445
14571446fn  test_non_determinism ( )  { 
@@ -1461,35 +1450,20 @@ fn test_non_determinism() {
14611450    } ; 
14621451    use  std:: { f32,  f64} ; 
14631452
1464-     /// Ensure that the operation is non-deterministic 
1465- #[ track_caller]  
1466-     fn  ensure_nondet < T :  PartialEq  + std:: fmt:: Debug > ( f :  impl  Fn ( )  -> T )  { 
1467-         let  rounds = 16 ; 
1468-         let  first = f ( ) ; 
1469-         for  _ in  1 ..rounds { 
1470-             if  f ( )  != first { 
1471-                 // We saw two different values! 
1472-                 return ; 
1473-             } 
1474-         } 
1475-         // We saw the same thing N times. 
1476-         panic ! ( "expected non-determinism, got {rounds} times the same result: {first:?}" ) ; 
1477-     } 
1478- 
14791453    macro_rules!  test_operations_f { 
14801454        ( $a: expr,  $b: expr)  => { 
1481-             ensure_nondet ( || fadd_algebraic( $a,  $b) ) ; 
1482-             ensure_nondet ( || fsub_algebraic( $a,  $b) ) ; 
1483-             ensure_nondet ( || fmul_algebraic( $a,  $b) ) ; 
1484-             ensure_nondet ( || fdiv_algebraic( $a,  $b) ) ; 
1485-             ensure_nondet ( || frem_algebraic( $a,  $b) ) ; 
1455+             check_nondet ( || fadd_algebraic( $a,  $b) ) ; 
1456+             check_nondet ( || fsub_algebraic( $a,  $b) ) ; 
1457+             check_nondet ( || fmul_algebraic( $a,  $b) ) ; 
1458+             check_nondet ( || fdiv_algebraic( $a,  $b) ) ; 
1459+             check_nondet ( || frem_algebraic( $a,  $b) ) ; 
14861460
14871461            unsafe  { 
1488-                 ensure_nondet ( || fadd_fast( $a,  $b) ) ; 
1489-                 ensure_nondet ( || fsub_fast( $a,  $b) ) ; 
1490-                 ensure_nondet ( || fmul_fast( $a,  $b) ) ; 
1491-                 ensure_nondet ( || fdiv_fast( $a,  $b) ) ; 
1492-                 ensure_nondet ( || frem_fast( $a,  $b) ) ; 
1462+                 check_nondet ( || fadd_fast( $a,  $b) ) ; 
1463+                 check_nondet ( || fsub_fast( $a,  $b) ) ; 
1464+                 check_nondet ( || fmul_fast( $a,  $b) ) ; 
1465+                 check_nondet ( || fdiv_fast( $a,  $b) ) ; 
1466+                 check_nondet ( || frem_fast( $a,  $b) ) ; 
14931467            } 
14941468        } ; 
14951469    } 
@@ -1499,70 +1473,70 @@ fn test_non_determinism() {
14991473    } 
15001474    pub  fn  test_operations_f32 ( a :  f32 ,  b :  f32 )  { 
15011475        test_operations_f ! ( a,  b) ; 
1502-         ensure_nondet ( || a. powf ( b) ) ; 
1503-         ensure_nondet ( || a. powi ( 2 ) ) ; 
1504-         ensure_nondet ( || a. log ( b) ) ; 
1505-         ensure_nondet ( || a. exp ( ) ) ; 
1506-         ensure_nondet ( || 10f32 . exp2 ( ) ) ; 
1507-         ensure_nondet ( || f32:: consts:: E . ln ( ) ) ; 
1508-         ensure_nondet ( || 10f32 . log10 ( ) ) ; 
1509-         ensure_nondet ( || 8f32 . log2 ( ) ) ; 
1510-         ensure_nondet ( || 1f32 . ln_1p ( ) ) ; 
1511-         ensure_nondet ( || 27.0f32 . cbrt ( ) ) ; 
1512-         ensure_nondet ( || 3.0f32 . hypot ( 4.0f32 ) ) ; 
1513-         ensure_nondet ( || 1f32 . sin ( ) ) ; 
1514-         ensure_nondet ( || 1f32 . cos ( ) ) ; 
1476+         check_nondet ( || a. powf ( b) ) ; 
1477+         check_nondet ( || a. powi ( 2 ) ) ; 
1478+         check_nondet ( || a. log ( b) ) ; 
1479+         check_nondet ( || a. exp ( ) ) ; 
1480+         check_nondet ( || 10f32 . exp2 ( ) ) ; 
1481+         check_nondet ( || f32:: consts:: E . ln ( ) ) ; 
1482+         check_nondet ( || 10f32 . log10 ( ) ) ; 
1483+         check_nondet ( || 8f32 . log2 ( ) ) ; 
1484+         check_nondet ( || 1f32 . ln_1p ( ) ) ; 
1485+         check_nondet ( || 27.0f32 . cbrt ( ) ) ; 
1486+         check_nondet ( || 3.0f32 . hypot ( 4.0f32 ) ) ; 
1487+         check_nondet ( || 1f32 . sin ( ) ) ; 
1488+         check_nondet ( || 1f32 . cos ( ) ) ; 
15151489        // On i686-pc-windows-msvc , these functions are implemented by calling the `f64` version, 
15161490        // which means the little rounding errors Miri introduces are discarded by the cast down to 
15171491        // `f32`. Just skip the test for them. 
15181492        if  !cfg ! ( all( target_os = "windows" ,  target_env = "msvc" ,  target_arch = "x86" ) )  { 
1519-             ensure_nondet ( || 1.0f32 . tan ( ) ) ; 
1520-             ensure_nondet ( || 1.0f32 . asin ( ) ) ; 
1521-             ensure_nondet ( || 5.0f32 . acos ( ) ) ; 
1522-             ensure_nondet ( || 1.0f32 . atan ( ) ) ; 
1523-             ensure_nondet ( || 1.0f32 . atan2 ( 2.0f32 ) ) ; 
1524-             ensure_nondet ( || 1.0f32 . sinh ( ) ) ; 
1525-             ensure_nondet ( || 1.0f32 . cosh ( ) ) ; 
1526-             ensure_nondet ( || 1.0f32 . tanh ( ) ) ; 
1493+             check_nondet ( || 1.0f32 . tan ( ) ) ; 
1494+             check_nondet ( || 1.0f32 . asin ( ) ) ; 
1495+             check_nondet ( || 5.0f32 . acos ( ) ) ; 
1496+             check_nondet ( || 1.0f32 . atan ( ) ) ; 
1497+             check_nondet ( || 1.0f32 . atan2 ( 2.0f32 ) ) ; 
1498+             check_nondet ( || 1.0f32 . sinh ( ) ) ; 
1499+             check_nondet ( || 1.0f32 . cosh ( ) ) ; 
1500+             check_nondet ( || 1.0f32 . tanh ( ) ) ; 
15271501        } 
1528-         ensure_nondet ( || 1.0f32 . asinh ( ) ) ; 
1529-         ensure_nondet ( || 2.0f32 . acosh ( ) ) ; 
1530-         ensure_nondet ( || 0.5f32 . atanh ( ) ) ; 
1531-         ensure_nondet ( || 5.0f32 . gamma ( ) ) ; 
1532-         ensure_nondet ( || 5.0f32 . ln_gamma ( ) ) ; 
1533-         ensure_nondet ( || 5.0f32 . erf ( ) ) ; 
1534-         ensure_nondet ( || 5.0f32 . erfc ( ) ) ; 
1502+         check_nondet ( || 1.0f32 . asinh ( ) ) ; 
1503+         check_nondet ( || 2.0f32 . acosh ( ) ) ; 
1504+         check_nondet ( || 0.5f32 . atanh ( ) ) ; 
1505+         check_nondet ( || 5.0f32 . gamma ( ) ) ; 
1506+         check_nondet ( || 5.0f32 . ln_gamma ( ) ) ; 
1507+         check_nondet ( || 5.0f32 . erf ( ) ) ; 
1508+         check_nondet ( || 5.0f32 . erfc ( ) ) ; 
15351509    } 
15361510    pub  fn  test_operations_f64 ( a :  f64 ,  b :  f64 )  { 
15371511        test_operations_f ! ( a,  b) ; 
1538-         ensure_nondet ( || a. powf ( b) ) ; 
1539-         ensure_nondet ( || a. powi ( 2 ) ) ; 
1540-         ensure_nondet ( || a. log ( b) ) ; 
1541-         ensure_nondet ( || a. exp ( ) ) ; 
1542-         ensure_nondet ( || 50f64 . exp2 ( ) ) ; 
1543-         ensure_nondet ( || 3f64 . ln ( ) ) ; 
1544-         ensure_nondet ( || f64:: consts:: E . log10 ( ) ) ; 
1545-         ensure_nondet ( || f64:: consts:: E . log2 ( ) ) ; 
1546-         ensure_nondet ( || 1f64 . ln_1p ( ) ) ; 
1547-         ensure_nondet ( || 27.0f64 . cbrt ( ) ) ; 
1548-         ensure_nondet ( || 3.0f64 . hypot ( 4.0f64 ) ) ; 
1549-         ensure_nondet ( || 1f64 . sin ( ) ) ; 
1550-         ensure_nondet ( || 1f64 . cos ( ) ) ; 
1551-         ensure_nondet ( || 1.0f64 . tan ( ) ) ; 
1552-         ensure_nondet ( || 1.0f64 . asin ( ) ) ; 
1553-         ensure_nondet ( || 5.0f64 . acos ( ) ) ; 
1554-         ensure_nondet ( || 1.0f64 . atan ( ) ) ; 
1555-         ensure_nondet ( || 1.0f64 . atan2 ( 2.0f64 ) ) ; 
1556-         ensure_nondet ( || 1.0f64 . sinh ( ) ) ; 
1557-         ensure_nondet ( || 1.0f64 . cosh ( ) ) ; 
1558-         ensure_nondet ( || 1.0f64 . tanh ( ) ) ; 
1559-         ensure_nondet ( || 1.0f64 . asinh ( ) ) ; 
1560-         ensure_nondet ( || 3.0f64 . acosh ( ) ) ; 
1561-         ensure_nondet ( || 0.5f64 . atanh ( ) ) ; 
1562-         ensure_nondet ( || 5.0f64 . gamma ( ) ) ; 
1563-         ensure_nondet ( || 5.0f64 . ln_gamma ( ) ) ; 
1564-         ensure_nondet ( || 5.0f64 . erf ( ) ) ; 
1565-         ensure_nondet ( || 5.0f64 . erfc ( ) ) ; 
1512+         check_nondet ( || a. powf ( b) ) ; 
1513+         check_nondet ( || a. powi ( 2 ) ) ; 
1514+         check_nondet ( || a. log ( b) ) ; 
1515+         check_nondet ( || a. exp ( ) ) ; 
1516+         check_nondet ( || 50f64 . exp2 ( ) ) ; 
1517+         check_nondet ( || 3f64 . ln ( ) ) ; 
1518+         check_nondet ( || f64:: consts:: E . log10 ( ) ) ; 
1519+         check_nondet ( || f64:: consts:: E . log2 ( ) ) ; 
1520+         check_nondet ( || 1f64 . ln_1p ( ) ) ; 
1521+         check_nondet ( || 27.0f64 . cbrt ( ) ) ; 
1522+         check_nondet ( || 3.0f64 . hypot ( 4.0f64 ) ) ; 
1523+         check_nondet ( || 1f64 . sin ( ) ) ; 
1524+         check_nondet ( || 1f64 . cos ( ) ) ; 
1525+         check_nondet ( || 1.0f64 . tan ( ) ) ; 
1526+         check_nondet ( || 1.0f64 . asin ( ) ) ; 
1527+         check_nondet ( || 5.0f64 . acos ( ) ) ; 
1528+         check_nondet ( || 1.0f64 . atan ( ) ) ; 
1529+         check_nondet ( || 1.0f64 . atan2 ( 2.0f64 ) ) ; 
1530+         check_nondet ( || 1.0f64 . sinh ( ) ) ; 
1531+         check_nondet ( || 1.0f64 . cosh ( ) ) ; 
1532+         check_nondet ( || 1.0f64 . tanh ( ) ) ; 
1533+         check_nondet ( || 1.0f64 . asinh ( ) ) ; 
1534+         check_nondet ( || 3.0f64 . acosh ( ) ) ; 
1535+         check_nondet ( || 0.5f64 . atanh ( ) ) ; 
1536+         check_nondet ( || 5.0f64 . gamma ( ) ) ; 
1537+         check_nondet ( || 5.0f64 . ln_gamma ( ) ) ; 
1538+         check_nondet ( || 5.0f64 . erf ( ) ) ; 
1539+         check_nondet ( || 5.0f64 . erfc ( ) ) ; 
15661540    } 
15671541    pub  fn  test_operations_f128 ( a :  f128 ,  b :  f128 )  { 
15681542        test_operations_f ! ( a,  b) ; 
@@ -1574,15 +1548,15 @@ fn test_non_determinism() {
15741548    test_operations_f128 ( 25. ,  18. ) ; 
15751549
15761550    // SNaN^0 = (1 | NaN) 
1577-     ensure_nondet ( || f32:: powf ( SNAN_F32 ,  0.0 ) . is_nan ( ) ) ; 
1578-     ensure_nondet ( || f64:: powf ( SNAN_F64 ,  0.0 ) . is_nan ( ) ) ; 
1551+     check_nondet ( || f32:: powf ( SNAN_F32 ,  0.0 ) . is_nan ( ) ) ; 
1552+     check_nondet ( || f64:: powf ( SNAN_F64 ,  0.0 ) . is_nan ( ) ) ; 
15791553
15801554    // 1^SNaN = (1 | NaN) 
1581-     ensure_nondet ( || f32:: powf ( 1.0 ,  SNAN_F32 ) . is_nan ( ) ) ; 
1582-     ensure_nondet ( || f64:: powf ( 1.0 ,  SNAN_F64 ) . is_nan ( ) ) ; 
1555+     check_nondet ( || f32:: powf ( 1.0 ,  SNAN_F32 ) . is_nan ( ) ) ; 
1556+     check_nondet ( || f64:: powf ( 1.0 ,  SNAN_F64 ) . is_nan ( ) ) ; 
15831557
15841558    // same as powf (keep it consistent): 
15851559    // x^SNaN = (1 | NaN) 
1586-     ensure_nondet ( || f32:: powi ( SNAN_F32 ,  0 ) . is_nan ( ) ) ; 
1587-     ensure_nondet ( || f64:: powi ( SNAN_F64 ,  0 ) . is_nan ( ) ) ; 
1560+     check_nondet ( || f32:: powi ( SNAN_F32 ,  0 ) . is_nan ( ) ) ; 
1561+     check_nondet ( || f64:: powi ( SNAN_F64 ,  0 ) . is_nan ( ) ) ; 
15881562} 
0 commit comments