Как стать автором
Обновить

Rust 1.60.0: покрытие на основе исходного кода, новый синтаксис условной компиляции в Cargo, инкрементальная компиляция

Время на прочтение6 мин
Количество просмотров6K
Автор оригинала: The Rust Release Team

Команда Rust публикует новую версию языка — 1.60.0. Rust — это язык программирования, позволяющий каждому создавать надёжное и эффективное программное обеспечение.


Если у вас есть предыдущая версия Rust, установленная через rustup, то для обновления до версии 1.60.0 вам достаточно выполнить команду:


rustup update stable

Если у вас ещё нет rustup, то можете установить его со страницы на нашем веб-сайте, а также ознакомиться с подробным описанием выпуска 1.60.0 на GitHub. Если вы хотите помочь нам протестировать будущие выпуски, вы можете использовать beta (rustup default beta) или nightly (rustup default nightly) канал. Пожалуйста, сообщайте обо всех встреченных вами ошибках.


Что стабилизировано в 1.60.0


Покрытие исходного кода


Поддержка инструментов покрытия на основе LLVM стабилизирована в rustc. Вы можете попробовать это на своём коде, перестроив его с помощью -Cinstrument-coverage, например так:


RUSTFLAGS="-C instrument-coverage" cargo build

После этого вы можете запустить полученный двоичный файл, который создаст файл default.profraw в текущем каталоге. (Путь и имя файла могут быть переопределены переменной среды; подробности см. в документации).


Компонент llvm-tools-preview включает llvm-profdata для обработки и слияния необработанных выходных данных профиля (счётчики выполнения области покрытия), а также llvm-cov для генерации отчётов. llvm-cov объединяет обработанный вывод из llvm-profdata и сам двоичный файл, потому что двоичный файл включает сопоставление счётчиков с фактическими областями исходного кода.


rustup component add llvm-tools-preview
$(rustc --print sysroot)/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-profdata merge -sparse default.profraw -o default.profdata
$(rustc --print sysroot)/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-cov show -Xdemangler=rustfilt target/debug/coverage-testing \
    -instr-profile=default.profdata \
    -show-line-counts-or-regions \
    -show-instantiations

Приведённые выше команды в простом двоичном файле helloworld создают этот аннотированный отчёт, показывающий, что каждая строка ввода была обработана.


    1|      1|fn main() {
    2|      1|    println!("Hello, world!");
    3|      1|}

Для получения более подробной информации, пожалуйста, прочитайте документацию в книге rustc. Базовая функциональность стабильна и будет существовать в той или иной форме во всех будущих выпусках Rust, но конкретный формат вывода и инструменты LLVM, которые его производят, могут быть изменены. По этой причине важно убедиться, что вы используете одну и ту же версию как для llvm-tools-preview, так и для двоичного файла rustc, используемого для компиляции вашего кода.


cargo --timings


В Cargo стабилизирована поддержка сбора информации о сборке с помощью флага --timings.


$ cargo build --timings
   Compiling hello-world v0.1.0 (hello-world)
      Timing report saved to target/cargo-timings/cargo-timing-20220318T174818Z.html
    Finished dev [unoptimized + debuginfo] target(s) in 0.98s

Этот отчёт так же сохраняется в target/cargo-timings/cargo-timing.html. Отчёт релизной сборки можно найти здесь. Эти отчёты будут полезны для улучшения производительности сборки. В документации можно найти больше информации об этих отчётах.


Новый синтаксис для свойств Cargo


В этом выпуске представлены два изменения, которые улучшают поддержку свойств Cargo и то, как они взаимодействуют с необязательными зависимостями: пространствами имён зависимостей и слабыми свойствами зависимостей.


У Cargo есть постоянно поддерживаемые свойства и необязательные зависимости, как показано в следующем фрагменте:


[dependencies]
jpeg-decoder = { version = "0.1.20", default-features = false, optional = true }

[features]
# Включает поддержку параллельной обработки при помощи включения функциональности "rayon" у jpeg-decoder.
parallel = ["jpeg-decoder/rayon"]

По этому примеру есть два замечания:


  • Необязательная зависимость jpeg-decoder неявно объявляет свойство с таким же именем. Подключение свойства jpeg-decoder подключит зависимость jpeg-decoder
  • Синтаксис "jpeg-decoder/rayon" подключает зависимость jpeg-decoder и функциональность rayon у зависимости jpeg-decoder.

Пространства имён свойств решают первую задачу. Теперь вы можете использовать префикс dep: в таблице [features] для явной отсылки к необязательной зависимости без неявного создания одноимённого свойства. Это даёт вам больше контроля над тем, как объявленное свойство соотносится с необязательными зависимостями, включая скрытие опциональных зависимостей за более описательными именами.


Свойства (features) слабых зависимостей решают вторую задачу, в которой синтаксис "optional-dependency/feature-name" всегда будет подключать optional-dependency. Однако часто нужно включить свойство необязательной зависимости только если включено некоторое другое свойство опциональной зависимости. Начиная с 1.60 вы можете добавить символ ? — как в "package-name?/feature-name", чтобы показать, что нужно включить данное свойство только если подключена опциональная зависимость.


Например, мы добавим поддержку сериализации в нашу библиотеку, что потребует включить соответствующее свойство в некоторых необязательных зависимостях. Сделать это можно следующим образом:


[dependencies]
serde = { version = "1.0.133", optional = true }
rgb = { version = "0.8.25", optional = true }

[features]
serde = ["dep:serde", "rgb?/serde"]

В этом примере подключение свойства serde подключит зависимость serde. Также она подключит свойство serde пакета rgb, но только в случае, если эта зависимость подключена.


Статус инкрементальной компиляции


Инкрементальная компиляция была снова включена в выпуске 1.60. Команда Rust продолжает работать над исправлением в ней ошибок, но в настоящее время не известно никаких проблем, вызывающих глобальные поломки, так что мы решили вернуть инкрементальную сборку. Дополнительно команда, работающая над компилятором, сейчас продолжает создавать долгосрочную стратегию, чтобы в будущем избежать проблем такого типа. Этот процесс только начался, так что мы пока что не готовы предоставить подробности по этому направлению работы.


Гарантии монотонности Instant


На всех платформах Instant пытается использовать API операционной системы. Это гарантирует монотонное поведение, если оно доступно (которое присутствует на всех платформах 1-го уровня). На практике в редких случаях такие гарантии сломаны аппаратно — виртуализацией или ошибками операционной системы. Чтобы обойти эти ошибки и поддерживать системы без монотонных часов, Instant::duration_since, Instant::elapsed и Instant::sub насыщаются до 0. В предыдущих версиях Rust это приводило бы к панике. Чтобы определить и обработать ситуации, когда монотонность нарушена или Instant вычитается в неправильном порядке, можно использовать Instant::checked_duration_since.


Этот обходной путь скрывает программные ошибки, где более ранний и более поздний моменты времени случайно поменялись местами. По этой причине в будущих версиях Rust может вернуться паника как минимум в таких случаях.


До 1.60 гарантии монотонности были предоставлены через мьютексы или атомики в std, которые давали большие накладные расходы при использовании Instant::now(). К тому же поведение с паникой означало, что программы на Rust могут паниковать на некотором подмножестве окружений, что было в значительной степени нежелательным, так как автор такой программы мог не иметь возможности обновить операционную систему, железо или используемую систему виртуализации. Наконец, введение неожиданной паники для таких окружений делало программы на Rust менее надёжными и переносимыми, что создавало в итоге более важную проблему, чем скучный поиск платформенных ошибок конечными пользователями.


Стабилизированные API


Стабилизированы следующие методы и реализации типажей:



Прочие изменения


В выпуске Rust 1.60.0 есть и другие изменения: узнайте, что изменилось в Rust, Cargo и Clippy.


Участники 1.60.0


Многие люди собрались вместе, чтобы создать Rust 1.60.0. Без вас мы бы не справились. Спасибо!


От переводчиков


С любыми вопросами по языку Rust вам смогут помочь в русскоязычном Телеграм-чате или же в аналогичном чате для новичковых вопросов. Если у вас есть вопросы по переводам или хотите помогать с ними, то обращайтесь в чат переводчиков.


Данную статью совместными усилиями перевели belanchuk, andreevlex, TelegaOvoshey и funkill.

Теги:
Хабы:
Всего голосов 34: ↑34 и ↓0+34
Комментарии3

Публикации

Истории

Работа

Rust разработчик
6 вакансий

Ближайшие события

25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань