rust-ux / uX

Non standard integer types like `u7`, `u9`, `u10`, `u63`, `i7`, `i9`
Apache License 2.0
119 stars 37 forks source link

Add feature gated and unstable const constructor for nightly? #5

Open phil-opp opened 6 years ago

phil-opp commented 6 years ago

Hi, we're using this library for rust-osdev/x86_64. We now have the problem that the ux types do not have a const constructor. Would you accept a pull request that adds a “nightly" feature and conditionally implements unstable const constructors?

kjetilkjeka commented 6 years ago

Hi, awesome that you're using the library. Yes, this is something i would merge.

The construction of ux types are at the moment far from ideal. The ideal case would be custom literals that evaluates in compile time and give a warning if numbers are out of range (just like rust built in integeres). The new function is a way to circumvent that this is not at the moment possible. I think that lack of a good way to do construction is the biggest 1.0 blocker at the moment.

What is the status of const fn panicing these day? The new function currently panics if given an integer out of range.

Are there any other constructors than a const fn new() that is needed?

Ixrec commented 6 years ago

Seems like panicking in const fns is stalled, I can't find a discussion more recent than the RFC https://github.com/rust-lang/rfcs/pull/2345, which hasn't even been postponed.

kitlith commented 5 years ago

It appears at this point the RFC is merged and implemented under the feature flag const_panic.

Nemo157 commented 5 years ago

Panicking in constants works, but there are no conditionals yet so you can only have a const fn that always panics. Supporting conditionals in const fn are on the roadmap, and likely to be one of the next supported const features.

In the meantime, it should be possible to provide const unsafe fn new_unchecked(value: u8) -> u4 etc. (same as the recently const-stabilised NonZeroU32::new_unchecked).

BenLeadbetter commented 1 month ago

We could potentially add a procedural macro constructor which can check the value of a literal at compile time.

let _ = ux::lit!(0x7F_u7);
let _ = ux::lit!(0xFF_u7); // compile error

Of course, this would a bunch of proc macro dependency to the now otherwise very lightweight crate. I guess this constructor could go behind a feature?

BenLeadbetter commented 1 month ago

In the meantime, it should be possible to provide const unsafe fn new_unchecked(value: u8) -> u4

I've been wanting this function for a while now too. 👍

I think the unsafe keyword would not be appropriate, however. It wouldn't violate the rust memory model when misused - it's just the internal state of the type which would be in an invalid state. The _unchecked suffix suffices imo.

chrysn commented 1 month ago

I do think this should be unsafe, as we (should?) guarantee that high bits are zero.

This allows us to have niches visible to the compiler eventually, and allows other crates to have their unsafe code rely on us.

For example, it should be sound to get_unchecked into a [T; 4] with a user provided u2, and for that to be ok, new_unchecked must be unsafe.

chrysn commented 1 month ago

At least for latest Rust, the macko can be by example, use the fallible constructor,and unwrap inside a const expar.