Rust 1.96: диапазоны наконец стали Copy, а сборки под WebAssembly могут сломаться

В релизе 1.96 стабилизированы новые типы диапазонов, макросы assert_matches!, а линкер WebAssembly перестал по умолчанию прощать неопределённые символы. Вместе с релизом закрыты две уязвимости в Cargo.

DB
DBG · по материалам Rust Blog
0

28 мая вышел Rust 1.96.0, и в нём закрыта одна из самых старых бытовых болей языка. Обычные диапазоны (Range, RangeFrom, RangeInclusive) сами реализуют Iterator, а значит по определению не могут быть Copy — итератор хранит состояние. Из-за этого нельзя было просто положить диапазон-срез в Copy-структуру, приходилось разносить start и end по отдельным полям. Теперь в стандартной библиотеке стабилизированы новые типы в модуле core::range: они реализуют IntoIterator, а не Iterator, и поэтому спокойно копируются.

Вторая заметная стабилизация — макросы assert_matches! и debug_assert_matches!. Они проверяют, что значение соответствует паттерну, и при провале печатают внятный диагностический вывод вместо унылого «assertion failed». Нюанс: макросы намеренно не попали в прелюдию — их нужно импортировать вручную, чтобы не столкнуться с одноимёнными макросами из сторонних крейтов, которые за годы ожидания успели расплодиться.

А вот изменение, из-за которого у части команд красный CI. Компилятор больше не передаёт линкеру WebAssembly флаг --allow-undefined по умолчанию. Раньше неопределённый символ молча превращался в импорт wasm-модуля, и проблема всплывала уже в рантайме браузера. Теперь это честная ошибка линковки. Логика правильная — баги ловятся на этапе сборки, — но если ваш wasm-крейт полагался на подтягивание символов извне, сборка упадёт сразу после апгрейда.

Вместе с релизом закрыты две уязвимости в Cargo: CVE-2026-5223 (средняя критичность) — распаковка тарболлов крейтов, содержащих симлинки, и CVE-2026-5222 (низкая) — обработка аутентификации при нормализации URL. Пользователей crates.io ни одна из них не затрагивает: обе актуальны для тех, кто работает с альтернативными и приватными реестрами. Кстати, там же Cargo научился указывать в одной записи зависимости и git-репозиторий, и альтернативный реестр — git-версия используется при локальной разработке, реестровая при публикации.

Что делать практикующему разработчику. Обновляйтесь через rustup update stable, но не в пятницу. Порядок проверки такой: сначала прогоните сборку wasm-таргетов — если увидите undefined symbol, у вас есть два пути: объявить символы явно через extern-блок с корректным #[link] или вернуть старое поведение флагом -C link-arg=--allow-undefined через RUSTFLAGS (это обходной путь, а не решение — символ всё равно надо найти). Дальше: если компания держит приватный registry, апгрейд Cargo обязателен из-за CVE с симлинками — злонамеренный крейт мог писать файлы за пределы каталога распаковки. И последнее: переезжать на core::range прямо сейчас не обязательно, старые диапазоны никуда не делись, но если у вас в коде есть структуры с парой полей start/end и ручной сборкой диапазона на каждом использовании — это ровно тот случай, ради которого фичу и делали.

Комментарии