Is a `runtime error: stack overflow` a (rust-lang) bug?

Here is the link to the playground;
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=45b530c7a18c34c21967097f8fa218ba

Manual expansion of the test_from macro:

use ::core::convert::From;

#[test]
fn test_from() {
    assert_eq!(
        DecimalFloatingPoint::from(1u8),
        DecimalFloatingPoint::new(1.0).unwrap(),
    );

    assert_eq!(
        DecimalFloatingPoint::from(1u16),
        DecimalFloatingPoint::new(1.0).unwrap(),
    );

    assert_eq!(
        DecimalFloatingPoint::from(1u32),
        DecimalFloatingPoint::new(1.0).unwrap(),
    );

    assert_eq!(
        DecimalFloatingPoint::from(1.0f32),
        DecimalFloatingPoint::new(1.0).unwrap(),
    );

    assert_eq!(
        DecimalFloatingPoint::from(-1.0f32),
        DecimalFloatingPoint::new(1.0).unwrap(),
    );

    assert_eq!(
        DecimalFloatingPoint::from(1.0f64),
        DecimalFloatingPoint::new(1.0).unwrap(),
    );

    assert_eq!(
        DecimalFloatingPoint::from(-1.0f64),
        DecimalFloatingPoint::new(1.0).unwrap(),
    );

    assert_eq!(
        DecimalFloatingPoint::from(Duration::from_secs(1)),
        DecimalFloatingPoint::new(1.0).unwrap(),
    );
}

cargo expand --tests --lib output:

fn test_from() {
    {
        {
            match (
                &DecimalFloatingPoint::from(1u8),
                &DecimalFloatingPoint::new(1.0).unwrap(),
            ) {
                (left_val, right_val) => {
                    if !(*left_val == *right_val) {
                        {
                            ::std::rt::begin_panic_fmt(
                                &::core::fmt::Arguments::new_v1(
                                    &[
                                        "assertion failed: `(left == right)`\n  left: `",
                                        "`,\n right: `",
                                        "`",
                                    ],
                                    &match (&&*left_val, &&*right_val) {
                                        (arg0, arg1) => [
                                            ::core::fmt::ArgumentV1::new(
                                                arg0,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                            ::core::fmt::ArgumentV1::new(
                                                arg1,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                        ],
                                    },
                                ),
                                &("src/types/decimal_floating_point.rs", 122u32, 5u32),
                            )
                        }
                    }
                }
            }
        }
    };
    {
        {
            match (
                &DecimalFloatingPoint::from(1u16),
                &DecimalFloatingPoint::new(1.0).unwrap(),
            ) {
                (left_val, right_val) => {
                    if !(*left_val == *right_val) {
                        {
                            ::std::rt::begin_panic_fmt(
                                &::core::fmt::Arguments::new_v1(
                                    &[
                                        "assertion failed: `(left == right)`\n  left: `",
                                        "`,\n right: `",
                                        "`",
                                    ],
                                    &match (&&*left_val, &&*right_val) {
                                        (arg0, arg1) => [
                                            ::core::fmt::ArgumentV1::new(
                                                arg0,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                            ::core::fmt::ArgumentV1::new(
                                                arg1,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                        ],
                                    },
                                ),
                                &("src/types/decimal_floating_point.rs", 122u32, 5u32),
                            )
                        }
                    }
                }
            }
        }
    };
    {
        {
            match (
                &DecimalFloatingPoint::from(1u32),
                &DecimalFloatingPoint::new(1.0).unwrap(),
            ) {
                (left_val, right_val) => {
                    if !(*left_val == *right_val) {
                        {
                            ::std::rt::begin_panic_fmt(
                                &::core::fmt::Arguments::new_v1(
                                    &[
                                        "assertion failed: `(left == right)`\n  left: `",
                                        "`,\n right: `",
                                        "`",
                                    ],
                                    &match (&&*left_val, &&*right_val) {
                                        (arg0, arg1) => [
                                            ::core::fmt::ArgumentV1::new(
                                                arg0,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                            ::core::fmt::ArgumentV1::new(
                                                arg1,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                        ],
                                    },
                                ),
                                &("src/types/decimal_floating_point.rs", 122u32, 5u32),
                            )
                        }
                    }
                }
            }
        }
    };
    {
        {
            match (
                &DecimalFloatingPoint::from(1.0f32),
                &DecimalFloatingPoint::new(1.0).unwrap(),
            ) {
                (left_val, right_val) => {
                    if !(*left_val == *right_val) {
                        {
                            ::std::rt::begin_panic_fmt(
                                &::core::fmt::Arguments::new_v1(
                                    &[
                                        "assertion failed: `(left == right)`\n  left: `",
                                        "`,\n right: `",
                                        "`",
                                    ],
                                    &match (&&*left_val, &&*right_val) {
                                        (arg0, arg1) => [
                                            ::core::fmt::ArgumentV1::new(
                                                arg0,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                            ::core::fmt::ArgumentV1::new(
                                                arg1,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                        ],
                                    },
                                ),
                                &("src/types/decimal_floating_point.rs", 122u32, 5u32),
                            )
                        }
                    }
                }
            }
        }
    };
    {
        {
            match (
                &DecimalFloatingPoint::from(-1.0f32),
                &DecimalFloatingPoint::new(1.0).unwrap(),
            ) {
                (left_val, right_val) => {
                    if !(*left_val == *right_val) {
                        {
                            ::std::rt::begin_panic_fmt(
                                &::core::fmt::Arguments::new_v1(
                                    &[
                                        "assertion failed: `(left == right)`\n  left: `",
                                        "`,\n right: `",
                                        "`",
                                    ],
                                    &match (&&*left_val, &&*right_val) {
                                        (arg0, arg1) => [
                                            ::core::fmt::ArgumentV1::new(
                                                arg0,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                            ::core::fmt::ArgumentV1::new(
                                                arg1,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                        ],
                                    },
                                ),
                                &("src/types/decimal_floating_point.rs", 122u32, 5u32),
                            )
                        }
                    }
                }
            }
        }
    };
    {
        {
            match (
                &DecimalFloatingPoint::from(1.0f64),
                &DecimalFloatingPoint::new(1.0).unwrap(),
            ) {
                (left_val, right_val) => {
                    if !(*left_val == *right_val) {
                        {
                            ::std::rt::begin_panic_fmt(
                                &::core::fmt::Arguments::new_v1(
                                    &[
                                        "assertion failed: `(left == right)`\n  left: `",
                                        "`,\n right: `",
                                        "`",
                                    ],
                                    &match (&&*left_val, &&*right_val) {
                                        (arg0, arg1) => [
                                            ::core::fmt::ArgumentV1::new(
                                                arg0,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                            ::core::fmt::ArgumentV1::new(
                                                arg1,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                        ],
                                    },
                                ),
                                &("src/types/decimal_floating_point.rs", 122u32, 5u32),
                            )
                        }
                    }
                }
            }
        }
    };
    {
        {
            match (
                &DecimalFloatingPoint::from(-1.0f64),
                &DecimalFloatingPoint::new(1.0).unwrap(),
            ) {
                (left_val, right_val) => {
                    if !(*left_val == *right_val) {
                        {
                            ::std::rt::begin_panic_fmt(
                                &::core::fmt::Arguments::new_v1(
                                    &[
                                        "assertion failed: `(left == right)`\n  left: `",
                                        "`,\n right: `",
                                        "`",
                                    ],
                                    &match (&&*left_val, &&*right_val) {
                                        (arg0, arg1) => [
                                            ::core::fmt::ArgumentV1::new(
                                                arg0,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                            ::core::fmt::ArgumentV1::new(
                                                arg1,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                        ],
                                    },
                                ),
                                &("src/types/decimal_floating_point.rs", 122u32, 5u32),
                            )
                        }
                    }
                }
            }
        }
    };
    {
        {
            match (
                &DecimalFloatingPoint::from(Duration::from_secs(1)),
                &DecimalFloatingPoint::new(1.0).unwrap(),
            ) {
                (left_val, right_val) => {
                    if !(*left_val == *right_val) {
                        {
                            ::std::rt::begin_panic_fmt(
                                &::core::fmt::Arguments::new_v1(
                                    &[
                                        "assertion failed: `(left == right)`\n  left: `",
                                        "`,\n right: `",
                                        "`",
                                    ],
                                    &match (&&*left_val, &&*right_val) {
                                        (arg0, arg1) => [
                                            ::core::fmt::ArgumentV1::new(
                                                arg0,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                            ::core::fmt::ArgumentV1::new(
                                                arg1,
                                                ::core::fmt::Debug::fmt,
                                            ),
                                        ],
                                    },
                                ),
                                &("src/types/decimal_floating_point.rs", 122u32, 5u32),
                            )
                        }
                    }
                }
            }
        }
    };
}

It's a bug in your code, you are recursing somewhere unconditionally and blowing the stack.

Line 61 looks suspicious, changing it to

f64::from(value).into()

Makes this work correctly.

1 Like