March 5, 2026·4 min read·engineeringrustiteratorscargoconfiguration

Rust 1.94 puts slice window length into the type

Fixed-size overlapping windows let consumers destructure data without a separate length check. Cargo's include support and TOML update also change how projects express shared configuration and parser requirements.

A slice window can have a length known to the programmer but absent from its type. Rust 1.94 closes that gap with array_windows, which yields references to arrays of a constant size. The March 5 announcement illustrates how an argument pattern can even supply the length through inference. The operation gives the consumer the structural fact it needs before the consumer starts examining elements.

The same release adds configuration inclusion in Cargo and support for TOML 1.1. Those changes concern different kinds of structure, but both remove local workarounds for expressing information the tool can understand directly. I find Rust most convincing when its additional type information makes the ordinary implementation shorter and more explicit. Fixed-size windows are a small example with a clear practical effect.

Overlapping arrays retain their size

The versioned slice documentation defines array_windows as a const-generic iterator over overlapping windows of N elements. It returns no windows when N exceeds the slice length. A zero value for N panics. Each yielded item has type &[T; N], preserving the size as part of the borrowed value.

For an input containing four elements and a window length of two, the windows cover positions zero and one, then one and two, then two and three. Adjacent windows overlap. This is a scan over neighboring relationships, not a partition into disjoint blocks. That distinction makes it useful for local patterns whose occurrence can begin at any position.

The release announcement's example detects an ASCII ABBA pattern through a four-element destructuring pattern. Its ASCII assumption matters because the input is a byte slice. A window of bytes is not automatically a window of Unicode characters. The iterator preserves element count, while the caller chooses what each element represents.

That separation is valuable in protocol and parser code. A consumer that requires exactly a fixed number of elements can receive that fact in its parameter type. It does not need to infer it from the location of an earlier windows call. The array reference also makes destructuring possible without inventing fallback behavior for shorter windows that the iterator never yields.

Existing window operations may already optimize well in a particular context. The stronger reason to choose the new iterator is that the source expresses the relationship between the window and the consumer. Compiler optimization then has the same structural information instead of recovering it from separate operations.

Borrowing is part of that representation too. Two adjacent windows can refer to some of the same elements, and the iterator returns shared references. A caller can retain one window while examining another without interpreting the overlap as ownership transfer. Each consumer receives a view into the original sequence whose extent is already known. Changing the pattern length changes a type parameter instead of requiring the consumer to defend itself against arbitrary slice lengths. A fixed-size parameter can also express this requirement when the pattern check lives in a separate function.

Cargo configuration can compose named files

The Cargo 1.94 configuration reference documents a top-level include key. Paths are relative to the including configuration file and must end in .toml. They can be plain strings or tables carrying a path and an optional flag. Missing optional files are skipped, while required files produce an error when absent.

include = [
    "shared.toml",
    { path = "local.toml", optional = true },
]

That syntax distinguishes a missing configuration error from an intentional local override that may not exist. A shared project configuration can therefore describe both dependencies without requiring every machine to create an empty placeholder file. Optionality belongs to the inclusion decision, where another reader can see it.

The reference also defines ordering. Cargo loads included files from left to right, with later files taking precedence, and then merges the including file's own values on top. Inclusion can recurse. The local file's position in the example therefore matters, and values in the containing configuration retain the highest precedence within that inclusion sequence.

This is useful configuration behavior because the file graph now describes the composition. A script that concatenates files would otherwise need its own rules for ordering and failure. Moving the operation into Cargo gives those rules a documented meaning. It also creates a reason to keep the include list short enough that a maintainer can understand where a setting originates.

The optional-file distinction remains a policy choice. A required build setting should not disappear silently just because the syntax permits optional inclusion. Conversely, a developer-specific setting should not require a checked-in empty file merely to satisfy the loader. The mechanism supports both cases without treating them as the same kind of dependency.

TOML syntax has its own minimum tool version

Cargo now accepts TOML 1.1 in manifests and configuration. The TOML 1.1 specification permits inline tables across multiple lines, including a trailing comma. That allows a dependency's fields to stay grouped while receiving separate lines for editing.

[dependencies]
serde = {
    version = "1.0",
    features = ["derive"],
}

The specification also adds the \e and \xHH escapes. The latter represents a Unicode character in the U+00HH range, not an arbitrary raw byte. TOML strings remain Unicode text. That distinction matters when a configuration generator starts using the shorter escape form and a reader assumes it is a binary representation.

The Rust announcement distinguishes the version needed to develop a crate from the version its users need. Using new manifest syntax requires a Cargo parser that understands it, including third-party tools that read the source manifest. Cargo rewrites manifests during publication to preserve compatibility with older parsers. A source checkout and a published package can consequently have different parser requirements.

That is a useful distinction for my own preference for explicit dependencies. A crate's Rust source compatibility does not fully describe the toolchain needed to work on its repository. The manifest itself is an input language with a version. Rust 1.94 gives maintainers more expressive source configuration, while publication normalization preserves a separate compatibility path for consumers of the packaged crate.