Tehforsch / diman

Define rust compile time unit systems using const generics
53 stars 2 forks source link

Blocked on compiler: More generic `Mul` and `Div` implementations #2

Closed Tehforsch closed 1 year ago

Tehforsch commented 2 years ago

In principle, we can write

        impl<SL, SR, const DL: $dimension, const DR: $dimension> std::ops::Mul<$quantity<SR, DR>>
            for $quantity<SL, DL>
        where
            $quantity<SL, { DL.dimension_mul(DR) }>:,
            SL: std::ops::Mul<SR>,
        {
            type Output = $quantity<<SL as std::ops::Mul<SR>>::Output, { DL.dimension_mul(DR) }>;

            fn mul(self, rhs: $quantity<SR, DR>) -> Self::Output {
                $quantity(self.0 * rhs.0)
            }
        }

However, this actually caused some problems with the compiler:

error[E0275]: overflow evaluating the requirement `f64: Div<&ndarray::ArrayBase<_, _>>`
  --> src/timestep/mod.rs:77:46
   |
77 |         let timestep_ratio: f64 = *(timestep / parameters.max_timestep).value();
   |                                              ^
   |
   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`raxiom`)
note: required for `f64` to implement `Div<Quantity<&ndarray::ArrayBase<_, _>, _>>`
  --> src/units/mod.rs:11:1
   |
11 | define_system!(Quantity, Dimension, NONE, UNIT_NAMES);
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: 124 redundant requirements hidden
   = note: required for `f64` to implement `Div<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<Quantity<&ndarray::ArrayBase<_, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>, _>>`
note: required by a bound in `<Quantity<SL, DL> as Div<Quantity<SR, DR>>>`
  --> src/units/mod.rs:11:1
   |
11 | define_system!(Quantity, Dimension, NONE, UNIT_NAMES);
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<Quantity<SL, DL> as Div<Quantity<SR, DR>>>`
   = note: this error originates in the macro `$crate::impl_concrete_float_methods` which comes from the expansion of the macro `define_system` (in Nightly builds, run with -Z macro-backtrace for more info)

This happened in raxiom, where ndarray is in scope. I assume that this added to the amount of types for which Div and Mul are implemented, which somehow resulted in this monstrosity of an error. It is peculiar that just dividing Time by Time was completely fine in other places of the (raxiom) code.

For now I fixed this bug by only implementing concrete Mul and Div implementations between the appropriate float/float and vector/float combinations. However, this is more restrictive than it has to be. I assume that we can change this back in the future, once generic_const_exprs become stable.