parity-common icon indicating copy to clipboard operation
parity-common copied to clipboard

uint crate cannot create very large integers

Open That3Percent opened this issue 4 years ago • 6 comments

Trying to create a U4096 type with:

use uint::construct_uint;
construct_uint! {
    pub struct U4096(64);
}

Rust-analyzer produces various errors:

arrays only have std trait implementations for lengths 0..=32
required because of the requirements on the impl of `std::cmp::Eq` for `[u64; 64]`
required by `std::cmp::AssertParamIsEq`rustc(E0277)
binary operation `==` cannot be applied to type `[u64; 64]`rustc(E0369)
binary operation `!=` cannot be applied to type `[u64; 64]`rustc(E0369)
arrays only have std trait implementations for lengths 0..=32
required because of the requirements on the impl of `std::hash::Hash` for `[u64; 64]`rustc(E0277)
mod.rs(176, 13): required by this bound in `std::hash::Hash::hash`

And trying to do cargo check seems to hang the compiler indefinitely.

That3Percent avatar May 08 '20 21:05 That3Percent

hey @That3Percent

this code generates a type

#[derive(PartialEq, Eq, Hash)]
pub struct U4096(pub [u64; 64]);
...

The problem is that rust implements these traits (Hash, Eq, etc) only for arrays up to 32 elements. So it is currently blocked on https://github.com/rust-lang/rust/issues/61415. Does it make sense?

Maybe we should document this in the readme that currently only up to 2048 bits are supported. Would you mind submitting a PR?

ordian avatar May 08 '20 21:05 ordian

Actually, I think it's possible to manually implement these traits instead of deriving them.

ordian avatar May 08 '20 21:05 ordian

Yes, I think manually implementing the traits is the way to go here.

That3Percent avatar May 09 '20 19:05 That3Percent

I came back to this to try and optimize stable-hash which does a multiply of a large number and there seem to be at least two issues here. One is the aformentioned compiler hang, and one is invalid tokens generated by the macro.

This produces a compiler hang:

construct_uint! {
    pub struct U4096(64);
}

And this produces invalid tokens:

construct_uint! {
    pub struct U4160(65);
}

Error:

error: no rules expected the token `@`
 --> src/lib.rs:2:1
  |
2 | / construct_uint! {
3 | |     pub struct U4160(65);
4 | | }
  | |_^ no rules expected this token in macro call

That3Percent avatar Mar 31 '21 20:03 That3Percent

And a third issue...

This panics the compiler.

construct_uint! {
    pub struct U1088(17);
}

With this panic:

    Checking u4160 v0.1.0 (/Users/zacharyburns/Documents/git/the-graph/u4160)
thread 'rustc' panicked at 'assertion failed: `(left == right)`
  left: `2817`,
 right: `9590`', /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/compiler/rustc_middle/src/ty/query/on_disk_cache.rs:743:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.51.0 (2fd73fabe 2021-03-23) running on x86_64-apple-darwin

note: compiler flags: -C embed-bitcode=no -C debuginfo=2 -C incremental --crate-type lib

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
#0 [codegen_fn_attrs] computing codegen attributes of `std::convert::From::from`
#1 [codegen_fn_attrs] computing codegen attributes of `<U1088 as std::convert::From<u128>>::from`
end of query stack
error: could not compile `u4160`

That3Percent avatar Mar 31 '21 21:03 That3Percent

interesting, thank you for digging into this, I believe this is due to how we use https://github.com/Vurich/crunchy/ unrolling maybe it's time to rewrite uint using generic arrays

ordian avatar Apr 01 '21 22:04 ordian

Rust-analyzer produces various errors:

arrays only have std trait implementations for lengths 0..=32
required because of the requirements on the impl of `std::cmp::Eq` for `[u64; 64]`
required by `std::cmp::AssertParamIsEq`rustc(E0277)

This was fixed long time ago. See https://blog.rust-lang.org/2020/10/08/Rust-1.47.html#traits-on-larger-arrays

This panics the compiler.

construct_uint! {
    pub struct U1088(17);
}

Works with rustc 1.63.0 (4b91a6ea7 2022-08-08)

This produces a compiler hang:

construct_uint! {
    pub struct U4096(64);
}

Well it takes huge time to materialize the code and lots of time to compile it but it works.

error: no rules expected the token `@`
  --> src/lib.rs:11:1
   |
11 | / construct_uint! {
12 | |     pub struct U4160(65);
13 | | }
   | |_^ no rules expected this token in macro call

This one is confirmed. Would you please file a new issue?

kpp avatar Sep 01 '22 12:09 kpp