From 1fb7b704c0d8b6fbbd636531c948c7118afa6f74 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 21 Jul 2025 16:46:23 +0200 Subject: [PATCH 1/4] chore: bump MSRV to 1.85 --- .github/workflows/ci.yml | 10 +++++----- Cargo.toml | 35 +++++++++++++++++++++++++++++++++-- README.md | 2 +- clippy.toml | 2 +- src/lib.rs | 21 --------------------- 5 files changed, 40 insertions(+), 30 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f6873d9d..99e22bf3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,11 +23,11 @@ jobs: strategy: fail-fast: false matrix: - rust: ["stable", "beta", "nightly", "1.65"] # MSRV + rust: ["stable", "beta", "nightly", "1.85"] # MSRV flags: ["--no-default-features", "", "--all-features"] exclude: # Skip because some features have higher MSRV. - - rust: "1.65" # MSRV + - rust: "1.85" # MSRV flags: "--all-features" steps: - uses: actions/checkout@v4 @@ -44,7 +44,7 @@ jobs: cache-on-failure: true # Only run tests on latest stable and above - name: Check - if: ${{ matrix.rust == '1.65' }} # MSRV + if: ${{ matrix.rust == '1.85' }} # MSRV run: cargo check ${{ matrix.flags }} # Cargo doc test is not included in `--all-targets` so we call it separately. @@ -52,12 +52,12 @@ jobs: # Cargo doc test also doesn't support `--no-run`, so we run it but # have it just print `--help`. - name: Build tests - if: ${{ matrix.rust != '1.65' }} # MSRV + if: ${{ matrix.rust != '1.85' }} # MSRV run: | cargo test --workspace ${{ matrix.flags }} --all-targets --no-run cargo test --workspace ${{ matrix.flags }} --doc -- --help - name: Run tests - if: ${{ matrix.rust != '1.65' }} # MSRV + if: ${{ matrix.rust != '1.85' }} # MSRV run: | cargo test --workspace ${{ matrix.flags }} --all-targets -- --nocapture cargo test --workspace ${{ matrix.flags }} --doc -- --nocapture diff --git a/Cargo.toml b/Cargo.toml index 56b0fd02..4736ea60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,12 +29,43 @@ resolver = "2" [workspace.package] edition = "2021" -rust-version = "1.65" +rust-version = "1.85" authors = ["Remco Bloemen "] license = "MIT" homepage = "https://github.com/recmo/uint" repository = "https://github.com/recmo/uint" +[workspace.lints.clippy] +all = { level = "warn", priority = -1 } +pedantic = { level = "warn", priority = -1 } +nursery = { level = "warn", priority = -1 } +missing-inline-in-public-items = "warn" +std-instead-of-alloc = "warn" +std-instead-of-core = "warn" + +doc-markdown = "allow" # Unfortunately many false positives on Latex. +inline-always = "allow" +module-name-repetitions = "allow" +redundant-pub-crate = "allow" +unreadable-literal = "allow" +let-unit-value = "allow" +option-if-let-else = "allow" +cast-sign-loss = "allow" +cast-lossless = "allow" + +[workspace.lints.rust] +missing-copy-implementations = "warn" +missing-debug-implementations = "warn" +missing-docs = "warn" +rust-2018-idioms = "warn" +unreachable-pub = "warn" +unused-must-use = "warn" +redundant-lifetimes = "warn" +unnameable-types = "warn" + +[workspace.lints.rustdoc] +all = "warn" + [dependencies] ruint-macro = { version = "1.2.1", path = "ruint-macro" } @@ -141,7 +172,6 @@ std = [ "valuable?/std", "zeroize?/std", ] -ssz = ["std", "dep:ethereum_ssz"] alloc = [ "proptest?/alloc", "rand-08?/alloc", @@ -183,6 +213,7 @@ rkyv = ["dep:rkyv", "alloc"] rlp = ["dep:rlp", "alloc"] serde = ["dep:serde", "alloc"] # TODO: try to avoid alloc in serde impls sqlx = ["dep:sqlx-core", "std", "dep:thiserror"] +ssz = ["dep:ethereum_ssz", "std"] subtle = ["dep:subtle"] valuable = ["dep:valuable"] zeroize = ["dep:zeroize"] diff --git a/README.md b/README.md index 50fe6758..e97837c2 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ When updating this, also update: Uint will keep a rolling MSRV (minimum supported rust version) policy of **at least** 6 months. When increasing the MSRV, the new Rust version must have been -released at least six months ago. The current MSRV is 1.65.0. +released at least six months ago. The current MSRV is 1.85.0. Note that the MSRV is not increased automatically, and only as part of a minor release. diff --git a/clippy.toml b/clippy.toml index 8cfd2528..391677e3 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1,2 +1,2 @@ -msrv = "1.65" +msrv = "1.85" doc-valid-idents = ["CPython", "PyPy", ".."] diff --git a/src/lib.rs b/src/lib.rs index 6bda8b70..05e95e15 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,26 +1,5 @@ #![doc = include_str!("../README.md")] #![doc(issue_tracker_base_url = "https://github.com/recmo/uint/issues/")] -#![warn( - clippy::all, - clippy::pedantic, - clippy::nursery, - clippy::missing_inline_in_public_items, - clippy::std_instead_of_alloc, - clippy::std_instead_of_core, - missing_docs, - unreachable_pub -)] -#![allow( - clippy::doc_markdown, // Unfortunately many false positives on Latex. - clippy::inline_always, - clippy::module_name_repetitions, - clippy::redundant_pub_crate, - clippy::unreadable_literal, - clippy::let_unit_value, - clippy::option_if_let_else, - clippy::cast_sign_loss, - clippy::cast_lossless, -)] #![cfg_attr(test, allow(clippy::wildcard_imports, clippy::cognitive_complexity))] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(not(feature = "std"), no_std)] From d5ee8923552962fca7ad35495e8633b81412e37f Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 21 Jul 2025 16:47:46 +0200 Subject: [PATCH 2/4] chore: apply clippy for MSRV bump --- ruint-macro/src/lib.rs | 4 ++-- src/bits.rs | 2 +- src/bytes.rs | 4 ++-- src/lib.rs | 2 +- src/pow.rs | 4 ++-- src/support/alloy_rlp.rs | 4 ++-- src/support/arbitrary.rs | 6 +++--- src/support/fastrlp_03.rs | 4 ++-- src/support/fastrlp_04.rs | 4 ++-- src/support/postgres.rs | 3 +-- src/support/scale.rs | 2 +- 11 files changed, 19 insertions(+), 20 deletions(-) diff --git a/ruint-macro/src/lib.rs b/ruint-macro/src/lib.rs index fe0a08f9..46d15140 100644 --- a/ruint-macro/src/lib.rs +++ b/ruint-macro/src/lib.rs @@ -133,7 +133,7 @@ fn parse_digits(value: &str) -> Result, String> { fn pad_limbs(bits: usize, mut limbs: Vec) -> Option> { // Get limb count and mask - let num_limbs = (bits + 63) / 64; + let num_limbs = bits.div_ceil(64); let mask = if bits == 0 { 0 } else { @@ -196,7 +196,7 @@ impl Transformer { write!(&mut limbs_str, "0x{limb:016x}_u64, ").unwrap(); } let limbs_str = limbs_str.trim_end_matches(", "); - let limbs = (bits + 63) / 64; + let limbs = bits.div_ceil(64); let source = format!("::{base_type}::<{bits}, {limbs}>::from_limbs([{limbs_str}])"); let mut tokens = self.ruint_crate.clone(); diff --git a/src/bits.rs b/src/bits.rs index b80f4f1a..a9f74649 100644 --- a/src/bits.rs +++ b/src/bits.rs @@ -248,7 +248,7 @@ impl Uint { #[must_use] #[inline] pub const fn byte_len(&self) -> usize { - (self.bit_len() + 7) / 8 + self.bit_len().div_ceil(8) } /// Returns the most significant 64 bits of the number and the exponent. diff --git a/src/bytes.rs b/src/bytes.rs index 4938ad43..6ee6ffc1 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -12,7 +12,7 @@ use alloc::{borrow::Cow, vec::Vec}; impl Uint { /// The size of this integer type in bytes. Note that some bits may be /// forced zero if BITS is not cleanly divisible by eight. - pub const BYTES: usize = (BITS + 7) / 8; + pub const BYTES: usize = BITS.div_ceil(8); /// Access the underlying store as a little-endian slice of bytes. /// @@ -463,7 +463,7 @@ impl Uint { #[inline] #[must_use] pub const fn nbytes(bits: usize) -> usize { - (bits + 7) / 8 + bits.div_ceil(8) } #[cfg(test)] diff --git a/src/lib.rs b/src/lib.rs index 05e95e15..afe31460 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -347,7 +347,7 @@ impl Default for Uint { #[inline] #[must_use] pub const fn nlimbs(bits: usize) -> usize { - (bits + 63) / 64 + bits.div_ceil(64) } /// Mask to apply to the highest limb to get the correct number of bits. diff --git a/src/pow.rs b/src/pow.rs index b5583ae5..084e9329 100644 --- a/src/pow.rs +++ b/src/pow.rs @@ -181,7 +181,7 @@ impl Uint { mod tests { use super::*; use crate::{const_for, nlimbs}; - use core::iter::repeat; + use core::iter::repeat_n; use proptest::proptest; #[test] @@ -202,7 +202,7 @@ mod tests { type U = Uint; proptest!(|(b in 2_u64..100, e in 0_usize..100)| { let b = U::from(b); - let prod = repeat(b).take(e).product::(); + let prod = repeat_n(b, e).product::(); assert_eq!(b.pow(U::from(e)), prod); }); }); diff --git a/src/support/alloy_rlp.rs b/src/support/alloy_rlp.rs index 50ebb976..a54d99b4 100644 --- a/src/support/alloy_rlp.rs +++ b/src/support/alloy_rlp.rs @@ -21,7 +21,7 @@ impl Encodable for Uint { if bits <= 7 { 1 } else { - let bytes = (bits + 7) / 8; + let bytes = bits.div_ceil(8); bytes + length_of_length(bytes) } } @@ -56,7 +56,7 @@ impl Encodable for Uint { #[cfg(target_endian = "big")] let bytes = self.to_be_bytes_vec(); - let leading_zero_bytes = Self::BYTES - (bits + 7) / 8; + let leading_zero_bytes = Self::BYTES - bits.div_ceil(8); let trimmed = &bytes[leading_zero_bytes..]; if bits > MAX_BITS { trimmed.encode(out); diff --git a/src/support/arbitrary.rs b/src/support/arbitrary.rs index f2e27c7d..ead599a5 100644 --- a/src/support/arbitrary.rs +++ b/src/support/arbitrary.rs @@ -25,7 +25,7 @@ impl<'a, const BITS: usize, const LIMBS: usize> Arbitrary<'a> for Uint (usize, Option) { - let bytes = (BITS + 7) / 8; + let bytes = BITS.div_ceil(8); (bytes, Some(bytes)) } } @@ -34,7 +34,7 @@ impl<'a, const BITS: usize, const LIMBS: usize> Arbitrary<'a> for Uint::size_hint(0); - let bytes = repeat(0x55u8).take(num_bytes).collect::>(); + let bytes = repeat_n(0x55u8, num_bytes).collect::>(); let mut u = arbitrary::Unstructured::new(&bytes); Uint::::arbitrary(&mut u).unwrap(); }); diff --git a/src/support/fastrlp_03.rs b/src/support/fastrlp_03.rs index 4026e9ef..ed031ff9 100644 --- a/src/support/fastrlp_03.rs +++ b/src/support/fastrlp_03.rs @@ -21,7 +21,7 @@ impl Encodable for Uint { if bits <= 7 { 1 } else { - let bytes = (bits + 7) / 8; + let bytes = bits.div_ceil(8); bytes + length_of_length(bytes) } } @@ -56,7 +56,7 @@ impl Encodable for Uint { #[cfg(target_endian = "big")] let bytes = self.to_be_bytes_vec(); - let leading_zero_bytes = Self::BYTES - (bits + 7) / 8; + let leading_zero_bytes = Self::BYTES - bits.div_ceil(8); let trimmed = &bytes[leading_zero_bytes..]; if bits > MAX_BITS { trimmed.encode(out); diff --git a/src/support/fastrlp_04.rs b/src/support/fastrlp_04.rs index 264bb133..edd103a8 100644 --- a/src/support/fastrlp_04.rs +++ b/src/support/fastrlp_04.rs @@ -21,7 +21,7 @@ impl Encodable for Uint { if bits <= 7 { 1 } else { - let bytes = (bits + 7) / 8; + let bytes = bits.div_ceil(8); bytes + length_of_length(bytes) } } @@ -56,7 +56,7 @@ impl Encodable for Uint { #[cfg(target_endian = "big")] let bytes = self.to_be_bytes_vec(); - let leading_zero_bytes = Self::BYTES - (bits + 7) / 8; + let leading_zero_bytes = Self::BYTES - bits.div_ceil(8); let trimmed = &bytes[leading_zero_bytes..]; if bits > MAX_BITS { trimmed.encode(out); diff --git a/src/support/postgres.rs b/src/support/postgres.rs index a9aae9b5..b03ee5ba 100644 --- a/src/support/postgres.rs +++ b/src/support/postgres.rs @@ -10,7 +10,6 @@ use crate::{ use bytes::{BufMut, BytesMut}; use core::{ error::Error, - iter, str::{from_utf8, FromStr}, }; use postgres_types::{to_sql_checked, FromSql, IsNull, ToSql, Type, WrongType}; @@ -290,7 +289,7 @@ impl<'a, const BITS: usize, const LIMBS: usize> FromSql<'a> for Uint Decode for CompactUint let x = Uint::::try_from_le_slice(&le_byte_slice) .ok_or_else(|| Error::from("value is larger than fits the Uint"))?; let bits = bytes as usize * 8; - let limbs = (bits + 64 - 1) / 64; + let limbs = bits.div_ceil(64); let mut new_limbs = vec![u64::MAX; limbs]; if bits > 0 { From 4881bbf4745982fcfbe24401463d868caa01a4d3 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 21 Jul 2025 17:52:32 +0200 Subject: [PATCH 3/4] chore: update code for new MSRV --- src/algorithms/mul_redc.rs | 1 + src/base_convert.rs | 5 +---- src/bit_arr.rs | 2 +- src/bits.rs | 2 +- src/bytes.rs | 19 +++++++++---------- src/fmt.rs | 7 +------ src/lib.rs | 18 +++++------------- src/string.rs | 3 +-- src/support/scale.rs | 10 ++++------ 9 files changed, 24 insertions(+), 43 deletions(-) diff --git a/src/algorithms/mul_redc.rs b/src/algorithms/mul_redc.rs index 9a52ce89..fe0c6cde 100644 --- a/src/algorithms/mul_redc.rs +++ b/src/algorithms/mul_redc.rs @@ -129,6 +129,7 @@ fn reduce1_carry(value: [u64; N], modulus: [u64; N], carry: bool let (reduced, borrow) = sub(value, modulus); // TODO: Ideally this turns into a cmov, which makes the whole mul_redc constant // time. + // TODO(MSRV-1.88): Use `core::hint::select_unpredictable`. if carry | !borrow { reduced } else { diff --git a/src/base_convert.rs b/src/base_convert.rs index dfd113e0..a3747bd1 100644 --- a/src/base_convert.rs +++ b/src/base_convert.rs @@ -393,10 +393,7 @@ impl SpigotBuf { base = crate::utils::max_pow_u64(base); let mut buf = [[MaybeUninit::uninit(); 2]; LIMBS]; - // TODO(MSRV-1.80): let as_slice = buf.as_flattened_mut(); - let as_slice = unsafe { - core::slice::from_raw_parts_mut(buf.as_mut_ptr().cast::>(), LIMBS * 2) - }; + let as_slice = buf.as_flattened_mut(); let mut i = 0; for limb in SpigotLittle::new(limbs, base) { debug_assert!( diff --git a/src/bit_arr.rs b/src/bit_arr.rs index 48ba2f97..c2da581a 100644 --- a/src/bit_arr.rs +++ b/src/bit_arr.rs @@ -71,7 +71,7 @@ impl Bits { /// Returns a mutable reference to the inner [Uint]. #[must_use] #[inline(always)] - pub fn as_uint_mut(&mut self) -> &mut Uint { + pub const fn as_uint_mut(&mut self) -> &mut Uint { &mut self.0 } } diff --git a/src/bits.rs b/src/bits.rs index a9f74649..88afc8a3 100644 --- a/src/bits.rs +++ b/src/bits.rs @@ -20,7 +20,7 @@ impl Uint { /// Sets a specific bit to a value. #[inline] - pub fn set_bit(&mut self, index: usize, value: bool) { + pub const fn set_bit(&mut self, index: usize, value: bool) { if index >= BITS { return; } diff --git a/src/bytes.rs b/src/bytes.rs index 6ee6ffc1..f807253c 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -1,6 +1,3 @@ -// OPT: Use u64::from_{be/le}_bytes() to work 8 bytes at a time. -// FEATURE: (BLOCKED) Make `const fn`s when `const_for` is stable. - use crate::Uint; use core::slice; @@ -39,7 +36,7 @@ impl Uint { #[cfg(target_endian = "little")] #[must_use] #[inline(always)] - pub unsafe fn as_le_slice_mut(&mut self) -> &mut [u8] { + pub const unsafe fn as_le_slice_mut(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self.limbs.as_mut_ptr().cast(), Self::BYTES) } } @@ -96,8 +93,7 @@ impl Uint { #[inline] #[must_use] pub const fn to_le_bytes(&self) -> [u8; BYTES] { - // TODO: Use a `const {}` block for this assertion - assert!(BYTES == Self::BYTES, "BYTES must be equal to Self::BYTES"); + const { Self::assert_bytes(BYTES) } // Specialized impl #[cfg(target_endian = "little")] @@ -209,8 +205,7 @@ impl Uint { #[track_caller] #[inline] pub const fn from_be_bytes(bytes: [u8; BYTES]) -> Self { - // TODO: Use a `const {}` block for this assertion - assert!(BYTES == Self::BYTES, "BYTES must be equal to Self::BYTES"); + const { Self::assert_bytes(BYTES) } Self::from_be_slice(&bytes) } @@ -288,8 +283,7 @@ impl Uint { #[track_caller] #[inline] pub const fn from_le_bytes(bytes: [u8; BYTES]) -> Self { - // TODO: Use a `const {}` block for this assertion - assert!(BYTES == Self::BYTES, "BYTES must be equal to Self::BYTES"); + const { Self::assert_bytes(BYTES) } Self::from_le_slice(&bytes) } @@ -453,6 +447,11 @@ impl Uint { Some(self.copy_be_bytes_to(buf)) } + + #[track_caller] + const fn assert_bytes(bytes: usize) { + assert!(bytes == Self::BYTES, "BYTES must be equal to Self::BYTES"); + } } /// Number of bytes required to represent the given number of bits. diff --git a/src/fmt.rs b/src/fmt.rs index 5ac5fcc9..ae267651 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -17,36 +17,31 @@ mod base { const MAX: u64 = crate::utils::max_pow_u64(Self::BASE); /// Number of characters written using `MAX` as the base in /// `to_base_be`. - // TODO(MSRV-1.67): = `Self::MAX.ilog(Self::BASE)` - const WIDTH: usize; + const WIDTH: usize = Self::MAX.ilog(Self::BASE) as _; } pub(super) struct Binary; impl Base for Binary { const BASE: u64 = 2; const PREFIX: &'static str = "0b"; - const WIDTH: usize = 63; } pub(super) struct Octal; impl Base for Octal { const BASE: u64 = 8; const PREFIX: &'static str = "0o"; - const WIDTH: usize = 21; } pub(super) struct Decimal; impl Base for Decimal { const BASE: u64 = 10; const PREFIX: &'static str = ""; - const WIDTH: usize = 19; } pub(super) struct Hexadecimal; impl Base for Hexadecimal { const BASE: u64 = 16; const PREFIX: &'static str = "0x"; - const WIDTH: usize = 15; } } use base::Base; diff --git a/src/lib.rs b/src/lib.rs index afe31460..d10680b6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -92,14 +92,6 @@ pub mod nightly { pub type Bits = crate::Bits; } -// FEATURE: (BLOCKED) Many functions could be made `const` if a number of -// features land. This requires -// #![feature(const_mut_refs)] -// #![feature(const_float_classify)] -// #![feature(const_fn_floating_point_arithmetic)] -// #![feature(const_float_bits_conv)] -// and more. - /// Packed u128, for [`as_double_words`](Uint::as_double_words). #[derive(Clone, Copy)] #[allow(non_camel_case_types)] @@ -204,7 +196,7 @@ impl Uint { /// size if the bit-size is not limb-aligned. #[inline(always)] #[must_use] - pub unsafe fn as_limbs_mut(&mut self) -> &mut [u64; LIMBS] { + pub const unsafe fn as_limbs_mut(&mut self) -> &mut [u64; LIMBS] { &mut self.limbs } @@ -242,12 +234,14 @@ impl Uint { "Value too large for this Uint" ); } + let _ = Self::LIMBS; // Triggers the assertion. Self { limbs } } #[inline(always)] #[must_use] const fn from_limbs_unmasked(limbs: [u64; LIMBS]) -> Self { + let _ = Self::LIMBS; // Triggers the assertion. Self { limbs }.masked() } @@ -320,7 +314,7 @@ impl Uint { } #[inline(always)] - fn apply_mask(&mut self) { + const fn apply_mask(&mut self) { if Self::SHOULD_MASK { self.limbs[LIMBS - 1] &= Self::MASK; } @@ -328,9 +322,7 @@ impl Uint { #[inline(always)] const fn masked(mut self) -> Self { - if Self::SHOULD_MASK { - self.limbs[LIMBS - 1] &= Self::MASK; - } + self.apply_mask(); self } } diff --git a/src/string.rs b/src/string.rs index 4bc4bcf6..1e6115c4 100644 --- a/src/string.rs +++ b/src/string.rs @@ -106,8 +106,7 @@ impl FromStr for Uint { type Err = ParseError; fn from_str(src: &str) -> Result { - let (src, radix) = if src.is_char_boundary(2) { - let (prefix, rest) = src.split_at(2); + let (src, radix) = if let Some((prefix, rest)) = src.split_at_checked(2) { match prefix { "0x" | "0X" => (rest, 16), "0o" | "0O" => (rest, 8), diff --git a/src/support/scale.rs b/src/support/scale.rs index bdcac99f..05f9c655 100644 --- a/src/support/scale.rs +++ b/src/support/scale.rs @@ -43,8 +43,6 @@ impl Decode for Uint { } } -// TODO: Use nightly generic const expressions to validate that BITS parameter -// is less than 536 pub struct CompactUint(pub Uint); impl From> for CompactUint { @@ -123,7 +121,7 @@ impl Encode for CompactRefUint<'_, BITS, } fn encode_to(&self, dest: &mut T) { - assert_compact_supported::(); + const { assert_compact_supported(BITS) } match self.0.bit_len() { // 0..=0b0011_1111 @@ -177,7 +175,7 @@ const OUT_OF_RANGE: &str = "out of range Uint decoding"; impl Decode for CompactUint { fn decode(input: &mut I) -> Result { - assert_compact_supported::(); + const { assert_compact_supported(BITS) } let prefix = input.read_byte()?; Ok(Self(match prefix % 4 { @@ -261,9 +259,9 @@ impl Decode for CompactUint } } -fn assert_compact_supported() { +const fn assert_compact_supported(bits: usize) { assert!( - BITS < COMPACT_BITS_LIMIT, + bits < COMPACT_BITS_LIMIT, "compact encoding is supported only for 0-(2**536-1) values" ); } From 82131971bb2b0f736b3df9d8663b7c471c807c45 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Wed, 23 Jul 2025 20:53:22 +0200 Subject: [PATCH 4/4] chore: update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f736eebf..ed199904 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- MSRV bumped to 1.85 ([#503]) + +[#503]: https://github.com/recmo/uint/pull/503 + ## [1.16.0] - 2025-08-04 ### Added