Skip to content

Commit

Permalink
Add #![feature(generic_const_exprs)] to doctests
Browse files Browse the repository at this point in the history
Some of them were missing this feature annotation but used to compile
and pass for some inexplicable reason. Now this missing feature gate
causes an ICE (rust-lang/rust#133199). This
adds the feature gates in all the doctests, but does not yet address the
fact that this ICE also occurs in calling crates that don't have
`#![feature(generic_const_exprs)]` set. Maybe a workaround could be to
check for this feature explicitly and throw a helpful error message in
diman.
  • Loading branch information
Tehforsch committed Jan 8, 2025
1 parent 86ddeb2 commit 6f1763e
Showing 1 changed file with 36 additions and 13 deletions.
49 changes: 36 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//! Diman is a library for zero-cost compile time unit checking.
//!
//! ```
//! # #![feature(generic_const_exprs)]
//! # #![allow(incomplete_features)]
//! # #![feature(generic_const_exprs, adt_const_params)]
//! use diman::si::dimensions::{Length, Time, Velocity};
//! use diman::si::units::{seconds, meters, kilometers, hours, hour};
//!
Expand Down Expand Up @@ -60,13 +61,16 @@
//! ## Arithmetics and math
//! Addition and subtraction of two quantities is allowed if the dimensions match:
//! ```
//! # #![allow(incomplete_features)]
//! # #![feature(generic_const_exprs, adt_const_params)]
//! # use diman::si::dimensions::{Length};
//! # use diman::si::units::{kilometers, meters};
//! let l = 5.0 * meters + 10.0 * kilometers;
//! ```
//! Multiplication and division of two quantities produces a new quantity:
//! ```
//! # #![feature(generic_const_exprs)]
//! # #![allow(incomplete_features)]
//! # #![feature(generic_const_exprs, adt_const_params)]
//! # use diman::si::dimensions::{Length, Time, Velocity};
//! # use diman::si::units::{meters, seconds};
//! let l = 5.0 * meters;
Expand All @@ -75,7 +79,8 @@
//! ```
//! Addition and subtraction of a `Quantity` and a storage type is possible if and only if `D` is dimensionless:
//! ```
//! # #![feature(generic_const_exprs)]
//! # #![allow(incomplete_features)]
//! # #![feature(generic_const_exprs, adt_const_params)]
//! # use diman::si::dimensions::{Length};
//! # use diman::si::units::{kilometers, meters};
//! let l1 = 5.0 * meters;
Expand All @@ -85,7 +90,8 @@
//! ```
//! `Quantity` implements the dimensionless methods of `S`, such as `sin`, `cos`, etc. for dimensionless quantities:
//! ```
//! # #![feature(generic_const_exprs)]
//! # #![allow(incomplete_features)]
//! # #![feature(generic_const_exprs, adt_const_params)]
//! # use diman::si::dimensions::{Length};
//! # use diman::si::units::{kilometers, meters};
//! let l1 = 5.0f64 * meters;
Expand All @@ -94,6 +100,8 @@
//! ```
//! Exponentiation and related operations are supported via `squared`, `cubed`, `powi`, `sqrt`, `cbrt`:
//! ```
//! # #![allow(incomplete_features)]
//! # #![feature(generic_const_exprs, adt_const_params)]
//! # use diman::si::dimensions::{Length};
//! # use diman::si::units::{meters, cubic_meters, square_meters};
//! let length = 2.0f64 * meters;
Expand All @@ -109,7 +117,8 @@
//! ```
//! Note that unlike its float equivalent, `powi` receives its exponent as a generic instead of as a normal function argument. Exponentiation of dimensionful quantities with an non-constant integer is not supported, since the compiler cannot infer the dimension of the return type. However, dimensionless quantities can be raised to arbitrary powers using `powf`:
//! ```
//! # #![feature(generic_const_exprs)]
//! # #![allow(incomplete_features)]
//! # #![feature(generic_const_exprs, adt_const_params)]
//! # use diman::si::dimensions::{Length, Volume};
//! # use diman::si::units::{meters, kilometers};
//! let l1 = 2.0f64 * meters;
Expand All @@ -127,7 +136,8 @@
//! For a full list of the units supported by dimans `SI` module, see [the definitions](src/si.rs).
//! Composite units can be defined on the spot via multiplication/division of units:
//! ```
//! # #![feature(generic_const_exprs)]
//! # #![allow(incomplete_features)]
//! # #![feature(generic_const_exprs, adt_const_params)]
//! # use diman::si::units::{kilometers, meters, hour, meters_per_second};
//! let v1 = (kilometers / hour).new(3.6);
//! let v2 = 3.6 * kilometers / hour;
Expand All @@ -139,20 +149,24 @@
//!
//! Conversion into the underlying storage type can be done using the `value_in` function:
//! ```
//! # #![allow(incomplete_features)]
//! # #![feature(generic_const_exprs, adt_const_params)]
//! # use diman::si::units::{kilometers, meters};
//! let length = 2.0f64 * kilometers;
//! assert_eq!(format!("{} m", length.value_in(meters)), "2000 m");
//! ```
//! This also works for composite units:
//! ```
//! # #![feature(generic_const_exprs)]
//! # #![allow(incomplete_features)]
//! # #![feature(generic_const_exprs, adt_const_params)]
//! # use diman::si::units::{kilometers, meters_per_second, hour};
//! let vel = 10.0f64 * meters_per_second;
//! assert_eq!(format!("{} km/h", vel.value_in(kilometers / hour)), "36 km/h");
//! ```
//! For dimensionless quantities, `.value()` provides access to the underlying storage types. Alternatively, dimensionless quantities also implement `Deref` for the same operation.
//! ```
//! # #![feature(generic_const_exprs)]
//! # #![allow(incomplete_features)]
//! # #![feature(generic_const_exprs, adt_const_params)]
//! # use diman::si::dimensions::{Length};
//! # use diman::si::units::{kilometers, meters};
//! let l1: Length<f64> = 5.0 * meters;
Expand All @@ -164,7 +178,8 @@
//! ## Unchecked creation and conversion
//! If absolutely required, `.value_unchecked()` provides access to the underlying storage type for all quantities. This is **not unit-safe** since the return value will depend on the unit system!
//! ```
//! # #![feature(generic_const_exprs)]
//! # #![allow(incomplete_features)]
//! # #![feature(generic_const_exprs, adt_const_params)]
//! # use diman::si::dimensions::{Length};
//! # use diman::si::units::{kilometers};
//! let length: Length<f64> = 5.0 * kilometers;
Expand All @@ -173,14 +188,17 @@
//! ```
//! Similarly, if absolutely required, new quantities can be constructed from storage types using `Quantity::new_unchecked`. This operation is also **not unit-safe**!
//! ```
//! # #![feature(generic_const_exprs)]
//! # #![allow(incomplete_features)]
//! # #![feature(generic_const_exprs, adt_const_params)]
//! # use diman::si::dimensions::{Length};
//! # use diman::si::units::{kilometers};
//! let length: Length<f64> = Length::new_unchecked(5000.0);
//! assert_eq!(length, 5.0 * kilometers); // This only holds in SI units!
//! ```
//! The combination of `value_unchecked` and `new_unchecked` comes in handy when using third party libraries that only takes the raw storage type as argument. As an example, suppose we have a function `foo` that takes a `Vec<f64>` and returns a `Vec<f64>`, and suppose it sorts the numbers or does some other unit safe operation. Then we could reasonably write:
//! ```
//! # #![allow(incomplete_features)]
//! # #![feature(generic_const_exprs, adt_const_params)]
//! # use diman::si::dimensions::{Length};
//! # use diman::si::units::{meters, kilometers};
//! # fn foo(x: Vec<f64>) -> Vec<f64> {
Expand All @@ -202,7 +220,8 @@
//! ## Debug
//! `Debug` is implemented and will print the quantity in its base representation.
//! ```
//! # #![feature(generic_const_exprs)]
//! # #![allow(incomplete_features)]
//! # #![feature(generic_const_exprs, adt_const_params)]
//! # use diman::si::dimensions::{Length, Time};
//! # use diman::si::units::{kilometers, seconds};
//! let length: Length<f64> = 5.0 * kilometers;
Expand Down Expand Up @@ -312,6 +331,8 @@
//! not needed too many times. Having to add a definition to the unit system for this case can be cumbersome.
//! This is why the `Product` and `Quotient` types are provided:
//! ```
//! # #![allow(incomplete_features)]
//! # #![feature(generic_const_exprs, adt_const_params)]
//! use diman::si::dimensions::{Length, Time};
//! use diman::{Product, Quotient};
//!
Expand Down Expand Up @@ -517,7 +538,8 @@ pub use diman_unit_system::unit_system;

/// Constructs a product of quantities for one-off quantities.
/// ```
/// # #![feature(generic_const_exprs)]
/// # #![allow(incomplete_features)]
/// # #![feature(generic_const_exprs, adt_const_params)]
/// # use diman::si::dimensions::{Length, Time};
/// # use diman::si::units::{meters, seconds};
/// # use diman::Product;
Expand All @@ -527,7 +549,8 @@ pub type Product<Q1, Q2> = <Q1 as ::core::ops::Mul<Q2>>::Output;

/// Constructs a quotient of two quantities for one-off quantities.
/// ```
/// # #![feature(generic_const_exprs)]
/// # #![allow(incomplete_features)]
/// # #![feature(generic_const_exprs, adt_const_params)]
/// # use diman::si::dimensions::{Length, Time};
/// # use diman::si::units::{meters, seconds};
/// # use diman::Quotient;
Expand Down

0 comments on commit 6f1763e

Please sign in to comment.