Команда 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
Стабилизированы следующие методы и реализации типажей:
Arc::new_cyclic
Rc::new_cyclic
slice::EscapeAscii
<[u8]>::escape_ascii
u8::escape_ascii
Vec::spare_capacity_mut
MaybeUninit::assume_init_drop
MaybeUninit::assume_init_read
i8::abs_diff
i16::abs_diff
i32::abs_diff
i64::abs_diff
i128::abs_diff
isize::abs_diff
u8::abs_diff
u16::abs_diff
u32::abs_diff
u64::abs_diff
u128::abs_diff
usize::abs_diff
Display for io::ErrorKind
From<u8> for ExitCode
Not for !
(Тип "never")OpAssign<$t> for Wrapping<$t>
arch::is_aarch64_feature_detected!
Прочие изменения
В выпуске Rust 1.60.0 есть и другие изменения: узнайте, что изменилось в Rust, Cargo и Clippy.
Участники 1.60.0
Многие люди собрались вместе, чтобы создать Rust 1.60.0. Без вас мы бы не справились. Спасибо!
От переводчиков
С любыми вопросами по языку Rust вам смогут помочь в русскоязычном Телеграм-чате или же в аналогичном чате для новичковых вопросов. Если у вас есть вопросы по переводам или хотите помогать с ними, то обращайтесь в чат переводчиков.
Данную статью совместными усилиями перевели belanchuk, andreevlex, TelegaOvoshey и funkill.