From f73edb4b5c9ece97ec162d924c11142ca3574f86 Mon Sep 17 00:00:00 2001 From: Christophe Troestler Date: Mon, 25 Dec 2023 21:31:14 +0100 Subject: [PATCH] Conditionally activate the never type --- .github/workflows/main.yml | 4 +++- Cargo.toml | 4 ++++ src/lib.rs | 39 +++++++++++++++++++++----------------- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b4f3415..92ae76e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -61,6 +61,8 @@ jobs: shell: bash - run: rustup target add ${{ matrix.target }} - run: cargo build + - run: cargo test --features rug + if: startsWith(matrix.os, 'ubuntu') && ${{ matrix.rust }} != "nightly" - run: cargo test --all-features - if: startsWith(matrix.os, 'ubuntu') + if: startsWith(matrix.os, 'ubuntu') && ${{ matrix.rust }} == "nightly" - run: cargo run --example speed_toms748 diff --git a/Cargo.toml b/Cargo.toml index e595a15..3a6979b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,10 @@ default-features = false features = ["float", "rational"] optional = true +[features] +default = [] +nightly = [] + [dev-dependencies] criterion = "0.3.5" roots = "0.0.7" diff --git a/src/lib.rs b/src/lib.rs index e400a04..7be79d1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,7 +40,7 @@ //! [`toms748`] (resp. [`toms748_mut`]), you must also implement the //! trait [`OrdField`] (resp. [`OrdFieldMut`]). -#![feature(never_type)] +#![cfg_attr(feature = "nightly", feature(never_type))] use std::{ cmp::Ordering, @@ -54,9 +54,15 @@ use std::{ result::Result, }; +#[cfg(feature = "nightly")] +pub type NoError = !; +#[cfg(not(feature = "nightly"))] +#[derive(Debug)] +pub enum NoError {} + /// Errors that may be returned by the root finding methods. #[derive(Debug)] -pub enum Error { +pub enum Error { /// Error indicating that the function evaluated at `x` returned /// the non-finite value `fx`. NotFinite { x: T, fx: T }, @@ -106,10 +112,10 @@ pub trait FloatOrError { macro_rules! impl_float_or_error { ($t: ty) => { impl FloatOrError<$t> for $t { - type Error = !; + type Error = NoError; #[inline] - fn to_result(self) -> Result<$t, !> { Ok(self) } + fn to_result(self) -> Result<$t, NoError> { Ok(self) } } impl FloatOrError<$t> for Result<$t, E> { type Error = E; @@ -140,7 +146,7 @@ pub trait UnitOrError { } impl UnitOrError for () { - type Error = !; + type Error = NoError; #[inline] fn to_result(self) -> Result<(), Self::Error> { Ok(()) } @@ -1925,10 +1931,10 @@ macro_rules! assert_approx_eq { mod tests { use std::{fmt::{Debug, Display}, f64::consts::PI}; - use crate as root1d; + use crate::{self as root1d, NoError}; //use test::bench::Bencher; - type R = Result<(), root1d::Error>; + type R = Result<(), root1d::Error>; #[test] fn error_is_static() { @@ -1936,7 +1942,7 @@ mod tests { fn _f(x: T) -> Result<(), Box> where T: Debug + Display + 'static + Clone { let fx = x.clone(); - Err(Box::new(root1d::Error::<_, !>::NotFinite{x, fx})) + Err(Box::new(root1d::Error::<_, NoError>::NotFinite{x, fx})) } } @@ -1950,24 +1956,23 @@ mod tests { Ok(()) } + type Toms = root1d::Toms748::< + f64, fn(f64) -> f64, root1d::Tol, NoError>; + #[test] fn test_ipzero() { // y³ + 3 = x - let r = root1d::Toms748:: f64, root1d::Tol, !> - ::ipzero([-5., 2., 4., 11.], - [-2., -1., 1., 2.]); + let r = Toms::ipzero([-5., 2., 4., 11.], [-2., -1., 1., 2.]); assert_eq!(r, 3.); } #[test] fn test_newton_quadratic() { - let r = root1d::Toms748:: f64, root1d::Tol, !> - ::newton_quadratic::<0>(0., 2., 1., - -1., 3., 0.); + let r = Toms::newton_quadratic::<0>(0., 2., 1., + -1., 3., 0.); assert_eq!(r, 1.25); - let r = root1d::Toms748:: f64, root1d::Tol, !> - ::newton_quadratic::<1>(0., 2., 1., - -1., 3., 0.); + let r = Toms::newton_quadratic::<1>(0., 2., 1., + -1., 3., 0.); assert_eq!(r, 41. / 40.); }