#979

fix(monty): crate 1.1.0 fails to compile on its declared rust-version 1.96

Opencoygeekopened 24d ago

Summary

The published monty 1.1.0 crate declares rust-version = "1.96" (inherited from [workspace.package] in the root Cargo.toml, and shown as rust_version: "1.96" on crates.io), but cargo check fails on rustc 1.96, 1.97 and 1.98 with E0277 in src/modules/json/string_cache.rs. The crate compiles on rustc 1.99. Downstream users on any toolchain from 1.96 through 1.98 cannot build it. Because the declared rust-version is satisfied on those toolchains, Cargo's MSRV-aware dependency resolution would also select monty 1.1.0 for projects whose own rust-version falls in that range.

Runtime or environment

  • monty 1.1.0 from crates.io (released 2026-10-05), which matches tag v1.1.0 and main at commit 591527397445bf734873252d1ee20c1b6308fe7f
  • Official Docker images rust:1.96 (rustc 1.96.1 31fca3adb 2026-06-26), rust:1.97 (rustc 1.97.1 8bab26f4f 2026-07-14), rust:1.98 (rustc 1.98.1 48a229cea 2026-09-01) and rust:1.99 (rustc 1.99.0 b940084d7 2026-09-28), aarch64-unknown-linux-gnu

Steps to reproduce

  1. Create a binary crate with this Cargo.toml and an empty fn main() {} in src/main.rs:
[package]
name = "msrv-probe"
version = "0.1.0"
edition = "2021"

[dependencies]
monty = "=1.1.0"
  1. Run cargo check in the rust:1.96 image, for example docker run --rm -v "$PWD":/w -w /w rust:1.96 cargo check.
  2. Repeat with rust:1.97, rust:1.98 and rust:1.99.

Expected behavior

Cargo documents rust-version as the minimum Rust toolchain version the package supports, so monty 1.1.0 should compile on rustc 1.96 and every later toolchain, including 1.98.

Actual behavior

In the rust:1.96, rust:1.97 and rust:1.98 images, cargo check exits with status 101 after monty-macros and monty-types 1.1.0 build without errors:

    Checking monty v1.1.0
error[E0277]: `[std::option::Option<(u64, Box<str>, value::Value)>; 16384]` is not an iterator
  --> /usr/local/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/monty-1.1.0/src/modules/json/string_cache.rs:98:26
   |
98 |             for entry in &mut inner.entries {
   |                          ^^^^^^^^^^^^^^^^^^ `[std::option::Option<(u64, Box<str>, value::Value)>; 16384]` is not an iterator
   |
   = help: the trait `std::iter::Iterator` is not implemented for `[std::option::Option<(u64, Box<str>, value::Value)>; 16384]`
   = help: the following other types implement trait `IntoIterator`:
             &Box<[I], A>
             &Box<ruff_python_ast::Parameters>
             &mut Box<[I], A>
             Box<[I], A>
             Box<indexmap::map::Slice<K, V>>
             Box<indexmap::set::Slice<T>>
   = note: required for `Box<[std::option::Option<(u64, Box<str>, value::Value)>; 16384]>` to implement `std::iter::Iterator`
   = note: 1 redundant requirement hidden
   = note: required for `&mut Box<[std::option::Option<(u64, Box<str>, value::Value)>; 16384]>` to implement `std::iter::Iterator`
   = note: required for `&mut Box<[std::option::Option<(u64, Box<str>, value::Value)>; 16384]>` to implement `IntoIterator`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `monty` (lib) due to 1 previous error

In the rust:1.99 image, the same project finishes cargo check with exit status 0.

Evidence

  • Expected source: Cargo reference, "The rust-version field" (https://doc.rust-lang.org/cargo/reference/rust-version.html), applied to rust-version = "1.96" in the root Cargo.toml and rust-version = { workspace = true } in crates/monty/Cargo.toml.
  • Failure source: local cargo check runs of the probe project above in the rust:1.96, rust:1.97 and rust:1.98 images, error at crates/monty/src/modules/json/string_cache.rs line 98.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

inner.entries has type Box<[CacheEntry; CAPACITY]> (string_cache.rs line 70). Rust 1.99.0 release notes list "IntoIterator for &mut Box<[T; N]>" as newly stabilized. The line changed from inner.entries.iter_mut() to &mut inner.entries in #960 ("ci: fix lints for rust 1.99", merge commit 505f10448282c991ea1ab362d6f078c6b548af87), after monty 1.0.0 was published. Control runs: monty 1.0.0 with monty-types pinned to 1.0.0 finishes cargo check in the rust:1.96 image, and the probe project patched (via [patch.crates-io]) to use a local copy of the 1.1.0 source with only line 98 changed back to inner.entries.iter_mut() finishes cargo check in the same image, so that line is the only error in the monty library on 1.96 (the crate's own tests were not checked). CI in .github/workflows/ci.yml uses only stable and nightly toolchains and has no job that builds on the declared rust-version, so it does not exercise this case.

Restoration check

With the probe project above, cargo check on rustc 1.96 currently fails with the E0277 error at string_cache.rs:98. The contract is restored when a published monty release compiles on every toolchain from its declared rust-version onward, checked on that exact declared version (and on 1.98 when the declared version is 1.98 or lower). Either keeping 1.96 and building on it or declaring an accurate rust-version satisfies this; the release on crates.io must reflect the result.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: Building the core monty crate fails for every user on rustc 1.96 through 1.98, toolchains the crate declares as supported, while rustc 1.99 and later build it and host-side crates that depend only on monty-types are unaffected.
  • Workaround status: available
  • Workaround basis: Affected users can upgrade to rustc 1.99 or later, or pin monty and monty-types to =1.0.0, both of which compiled in the control runs; the pin forgoes 1.1.0 changes.

Activity

0

No activity yet.