Rust 1.97: схема манглинга v0 по умолчанию, видимый вывод линкера и ворнинги под контролем Cargo

9 июля вышел Rust 1.97.0. Компилятор перешёл на Rust-специфичную схему манглинга символов v0, сообщения линкера больше не прячутся, а уровнем ворнингов можно управлять через переменную окружения без инвалидации кеша сборки.

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

9 июля вышел Rust 1.97.0 — релиз без громких синтаксических новинок, но с одним изменением, которое почувствуют все, кто хоть раз читал бэктрейс или профилировал бинарь.

Компилятор по умолчанию перешёл на схему манглинга символов v0. Раньше Rust пользовался схемой, унаследованной от Itanium ABI, которая не была рассчитана на язык с дженериками: инстанциации обобщённых параметров в имени символа не сохранялись, вместо них стоял хеш. Из-за этого два разных Vec<T> в бэктрейсе выглядели одинаково безлико, а инструменты угадывали связь между символом и кодом. Схема v0 разработана специально под Rust и сохраняет инстанциации параметров прямо в имени. Практический эффект — читаемые бэктрейсы, вменяемые отчёты профилировщиков и меньше коллизий в отладочной информации.

Второе изменение — сообщения линкера теперь показываются по умолчанию, как диагностика уровня warning. Раньше линкер мог ворчать в пустоту, и предупреждение о, скажем, подозрительной секции или дублирующемся символе просто не доходило до разработчика. Кому шум мешает — подавляется через конфигурацию линтов.

Третье — управление ворнингами через Cargo: переменная CARGO_BUILD_WARNINGS принимает значения allow, warn (по умолчанию) и deny. Важная деталь: смена значения не инвалидирует кеш сборки, в отличие от привычного трюка с RUSTFLAGS="-D warnings", который заставляет пересобирать всё заново. Из стабилизированных API — набор битовых методов для целочисленных типов и NonZero: isolate_highest_one(), isolate_lowest_one(), highest_one(), lowest_one(), bit_width(); также Default для RepeatN, Copy для ffi::FromBytesUntilNulError, а char::is_control() теперь работает в const-контексте.

Что делать. Обновление обычное — rustup update stable. Но перед тем как катить 1.97 в CI, проверьте всё, что завязано на формат имён символов: кастомные скрипты разбора бэктрейсов, интеграции с профилировщиками (perf, Instruments, pprof-обвязки), символизаторы в вашем крэш-репортере, а также FFI-слои, где чужой код ищет символы Rust по имени. Инструменты вроде rustfilt и свежих addr2line/llvm-symbolizer схему v0 понимают, а вот самописный regexp по старому формату — нет, и сломается он молча, оставив вам нечитаемые стеки в проде. Второе: в CI имеет смысл сразу перевести ворнинги на CARGO_BUILD_WARNINGS=deny вместо RUSTFLAGS — билд-кеш скажет спасибо и время сборки на pull request заметно упадёт.

Комментарии