danlehmann / arbitrary-int

A modern and lightweight implementation of arbitrary integers for Rust
MIT License
32 stars 13 forks source link

cannot call non-const fn `<UInt<u8, 2> as arbitrary_int::Number>::value after upgrade from 1.2.1 to 1.2.2 #4

Closed pbl-pw closed 1 year ago

danlehmann commented 1 year ago

Hey,

I did some quick tests to call Number::value and it worked for me. Could you give me a code example that demonstrates the problem?

Thanks!

pbl-pw commented 1 year ago

for example:

const TTTT: u8 = u7::new(127).value();

= note: calls in constants are limited to constant functions, tuple structs and tuple variants

Actually I use https://crates.io/crates/bitbybit , but the problem is constant context

And I found the reason :

impl UInt<$type, BITS> { ... pub const fn value() ... }

had changed to

impl Number for UInt<$type, BITS> { ... fn value() ... }

because const_trait_impl not stable, so can't be const for trait fn

danlehmann commented 1 year ago

Hey,

Thanks for the report. This is an issue with name resolution that I didn't know about. I'll give you long answer first: 1.2.2 introduced a Number trait, which allows generic code to be written for both u2, u3, ... AND u8, u16 etc

That Number trait has a function named value, which is non-const. However, the const function still exists. What I didn't know is that the Rust compiler prefers the Trait version over the version of the type itself IF the trait is imported.

For example, this works:

use arbitrary_int::u7;
const TTTT: u8 = u7::new(127).value();

However, this breaks:

use arbitrary_int::u7;
use arbitrary_int::Number;
const TTTT: u8 = u7::new(127).value();

To unblock you, there are two workarounds: a) Don't import Number if you don't need it b) Specify the u7 value function directly like this:

use arbitrary_int::u7;
use arbitrary_int::Number;
const TTTT: u8 = u7::value(&u7::new(127));

Probably the best fix on my end would be to rename Number::value() to something else (e.g. Number::number_value()). While that is an API change, it seems I already broke you unknowingly, so that is probably worth doing anyway.

Sorry for the breakage!

danlehmann commented 1 year ago

Actually, there seems to be an easier fix: const fn value takes a reference instead of value. If I change it to value it will prefer that function over the Trait function. That sounds like the much smaller breakage, so I guess that's a quick fix I can implement on my end

danlehmann commented 1 year ago

I just merged a fix. Would you mind giving it a try before I upload to crates.io?

You can fetch the crate like this:

arbitrary-int = { git = "https://github.com/danlehmann/arbitrary-int.git" }
pbl-pw commented 1 year ago

You are right After i change from ' use arbitrary_int::*;' to 'use arbitrary_int::{u7,u....};', then it works Thanks you!

For your future plan, give some additional information: after import Number will report with 1.2.2 error[E0015]: cannot call non-const fn <UInt<u8, 4> as arbitrary_int::Number>::value in constant functions --> gen.rs:52:1 52 #[bitenum(u4, exhaustive: false)] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the attribute macro bitenum (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0015]: cannot call non-const fn <UInt<u8, 4> as arbitrary_int::Number>::value in constant functions --> gen.rs:61:1 61 #[bitfield(u16)] ^^^^^^^^^^^^^^^^

= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the attribute macro bitfield (in Nightly builds, run with -Z macro-backtrace for more info)

danlehmann commented 1 year ago

Yikes, that's a good find! Thanks a lot for reporting this!

pbl-pw commented 1 year ago

I just merged a fix. Would you mind giving it a try before I upload to crates.io?

You can fetch the crate like this:

arbitrary-int = { git = "https://github.com/danlehmann/arbitrary-int.git" }

This also works even import with 'use arbitrary_int::*;' Thanks you!

danlehmann commented 1 year ago

Thank you. I will upload this to crates.io shortly. But it sounds like you are unblocked.

Best, Daniel