Команда Rust выпустила версию 1.96.0. Главное нововведение — новые типы диапазонов (Range*) из RFC3550. Раньше Range и другие типы из core::ops напрямую реализовывали Iterator, из-за чего их нельзя было сделать Copy — совмещать оба трейта на одном типе опасно. Теперь в core::range появились Range, RangeFrom и RangeInclusive, которые реализуют IntoIterator, а не Iterator, так что их можно копировать. RangeInclusive к тому же сделал поля публичными — в старой версии их прятали, чтобы не показывать состояние «итератор исчерпан», но новому типу это не нужно. В будущем синтаксис 0..1 начнёт создавать именно эти новые типы, а старые переедут в core::range::legacy.
Ещё добавили макросы assert_matches! и debug_assert_matches!. Они проверяют, что значение соответствует шаблону, и паникуют с Debug-представлением, если нет. Работают как assert!(matches!(..)), но выводят больше информации при ошибке. Макросы не включили в прелюдию — слишком много сторонних крейтов уже используют эти же имена. Их надо импортировать вручную из core или std.
WebAssembly-таргеты теперь не передают линковщику флаг --allow-undefined. Раньше неопределённые символы тихо превращались в импорты из модуля "env". Теперь это ошибка линковки, что ловит баги на раннем этапе. Если нужно старое поведение, его можно вернуть через RUSTFLAGS=-Clink-arg=--allow-undefined или атрибутом #[link(wasm_import_module = "env")].
В Cargo исправили две уязвимости, но они касаются только сторонних реестров — пользователи crates.io не затронуты.
Также стабилизировали несколько API, полный список — в релизных заметках. В версии участвовало много контрибьюторов.