Skip to content

Commit

Permalink
Conditionally activate the never type
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris00 committed Dec 25, 2023
1 parent 280e8d7 commit f73edb4
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 18 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
39 changes: 22 additions & 17 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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<T, E = !> {
pub enum Error<T, E = NoError> {
/// Error indicating that the function evaluated at `x` returned
/// the non-finite value `fx`.
NotFinite { x: T, fx: T },
Expand Down Expand Up @@ -106,10 +112,10 @@ pub trait FloatOrError<T> {

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<E> FloatOrError<$t> for Result<$t, E> {
type Error = E;
Expand Down Expand Up @@ -140,7 +146,7 @@ pub trait UnitOrError {
}

impl UnitOrError for () {
type Error = !;
type Error = NoError;

#[inline]
fn to_result(self) -> Result<(), Self::Error> { Ok(()) }
Expand Down Expand Up @@ -1925,18 +1931,18 @@ 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<T> = Result<(), root1d::Error<T, !>>;
type R<T> = Result<(), root1d::Error<T, NoError>>;

#[test]
fn error_is_static() {
// Compile time test.
fn _f<T>(x: T) -> Result<(), Box<dyn std::error::Error + 'static>>
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}))
}
}

Expand All @@ -1950,24 +1956,23 @@ mod tests {
Ok(())
}

type Toms = root1d::Toms748::<
f64, fn(f64) -> f64, root1d::Tol<f64>, NoError>;

#[test]
fn test_ipzero() {
// y³ + 3 = x
let r = root1d::Toms748::<f64, fn(f64) -> f64, root1d::Tol<f64>, !>
::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, fn(f64) -> f64, root1d::Tol<f64>, !>
::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, fn(f64) -> f64, root1d::Tol<f64>, !>
::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.);
}

Expand Down

0 comments on commit f73edb4

Please sign in to comment.