Skip to content

Quantity types aren't Unpin #204

@Michael-F-Bryan

Description

@Michael-F-Bryan

I'm trying to use uom types in an async context and found that quantities are !Unpin.

Types like uom::si::f64::Velocity are meant to be identical to a normal float, so it should be perfectly fine for them to be Unpin. I'm guessing the offending part is the use of dyn trait objects that don't have + Unpin in their trait bounds.

This was found on uom 0.29.0 and rustc version 1.48.0-nightly (397b390cc 2020-08-27).

Here's a minimal test case:

#[test]
fn velocity_should_be_unpin() {
    fn assert_unpin<T: Unpin>() {}

    assert_unpin::<uom::si::f64::Velocity>();
}

And it fails with this compilation error:

error[E0277]: `(dyn uom::si::Dimension<T = uom::typenum::NInt<uom::typenum::UInt<uom::typenum::UTerm, uom::typenum::B1>>, I = uom::typenum::Z0, N = uom::typenum::Z0, L = uom::typenum::PInt<uom::typenum::UInt<uom::typenum::UTerm, uom::typenum::B1>>, Kind = (dyn uom::Kind + 'static), M = uom::typenum::Z0, J = uom::typenum::Z0, Th = uom::typenum::Z0> + 'static)` cannot be unpinned
  --> indexer\src\systems\motion\manual_mode.rs:94:9
   |
92 |         fn assert_unpin<T: Unpin>() {}
   |                            ----- required by this bound in `systems::motion::manual_mode::tests::velocity_should_be_unpin::assert_unpin`
93 |
94 |         assert_unpin::<uom::si::f64::Velocity>();
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `uom::si::Quantity<(dyn uom::si::Dimension<T = uom::typenum::NInt<uom::typenum::UInt<uom::typenum::UTerm, uom::typenum::B1>>, I = uom::typenum::Z0, N = uom::typenum::Z0, L = uom::typenum::PInt<uom::typenum::UInt<uom::typenum::UTerm, uom::typenum::B1>>, Kind = (dyn uom::Kind + 'static), M = uom::typenum::Z0, J = uom::typenum::Z0, Th = uom::typenum::Z0> + 'static), (dyn uom::si::Units<f64, thermodynamic_temperature = uom::si::thermodynamic_temperature::kelvin, mass = uom::si::mass::kilogram, amount_of_substance = uom::si::amount_of_substance::mole, electric_current = uom::si::electric_current::ampere, length = uom::si::length::meter, luminous_intensity = uom::si::luminous_intensity::candela, time = uom::si::time::second> + 'static), f64>`, the trait `std::marker::Unpin` is not implemented for `(dyn uom::si::Dimension<T = uom::typenum::NInt<uom::typenum::UInt<uom::typenum::UTerm, uom::typenum::B1>>, I = uom::typenum::Z0, N = uom::typenum::Z0, L = uom::typenum::PInt<uom::typenum::UInt<uom::typenum::UTerm, uom::typenum::B1>>, Kind = (dyn uom::Kind + 'static), M = uom::typenum::Z0, J = uom::typenum::Z0, Th = uom::typenum::Z0> + 'static)`
   |
   = note: required because it appears within the type `std::marker::PhantomData<(dyn uom::si::Dimension<T = uom::typenum::NInt<uom::typenum::UInt<uom::typenum::UTerm, uom::typenum::B1>>, I = uom::typenum::Z0, N = uom::typenum::Z0, L = uom::typenum::PInt<uom::typenum::UInt<uom::typenum::UTerm, uom::typenum::B1>>, Kind = (dyn uom::Kind + 'static), M = uom::typenum::Z0, J = uom::typenum::Z0, Th = uom::typenum::Z0> + 'static)>`
   = note: required because it appears within the type `uom::si::Quantity<(dyn uom::si::Dimension<T = uom::typenum::NInt<uom::typenum::UInt<uom::typenum::UTerm, uom::typenum::B1>>, I = uom::typenum::Z0, N = uom::typenum::Z0, L = uom::typenum::PInt<uom::typenum::UInt<uom::typenum::UTerm, uom::typenum::B1>>, Kind = (dyn uom::Kind + 'static), M = uom::typenum::Z0, J = uom::typenum::Z0, Th = uom::typenum::Z0> + 'static), (dyn uom::si::Units<f64, thermodynamic_temperature = uom::si::thermodynamic_temperature::kelvin, mass = uom::si::mass::kilogram, amount_of_substance = uom::si::amount_of_substance::mole, electric_current = uom::si::electric_current::ampere, length = uom::si::length::meter, luminous_intensity = uom::si::luminous_intensity::candela, time = uom::si::time::second> + 'static), f64>`

In my real code, the compiler suggests using #![feature(trivial_bounds)] (rust-lang/rust#48214).

    = note: required because it appears within the type `systems::motion::manual_mode::ManualMode`
    = help: see issue #48214
    = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions