Команда Rust рада сообщить о новой версии языка — 1.84.0. Rust — это язык программирования, позволяющий каждому создавать надёжное и эффективное программное обеспечение.
Если у вас есть предыдущая версия Rust, установленная через rustup
, то для обновления до версии 1.84.0 вам достаточно выполнить команду:
$ rustup update stable
Если у вас ещё не установлен rustup
, вы можете установить его с соответствующей страницы нашего веб-сайта, а также посмотреть подробные примечания к выпуску на GitHub.
Если вы хотите помочь нам протестировать будущие выпуски, вы можете использовать канал beta (rustup default beta
) или nightly (rustup default nightly
). Пожалуйста, сообщайте обо всех встреченных вами ошибках.
Что стабилизировано в 1.84.0
Cargo учитывает версию Rust при выборе версии зависимости
В 1.84.0 стабилизирован резолвер, учитывающий минимально поддерживаемую версию Rust (MSRV), который предпочитает те версии зависимости, которые совместимы с указанной в проекте MSRV. С учитывающим MSRV выбором версий пакетов снижается сложность поддержки старых наборов тулчейнов. Это происходит за счёт того, что для каждой зависимости больше не приходится выбирать старую версию вручную.
Вы можете включить новый резолвер через .cargo/config.toml
:
[resolver]
incompatible-rust-versions = "fallback"
И при добавлении зависимости:
$ cargo add clap
Updating crates.io index
warning: ignoring clap@4.5.23 (which requires rustc 1.74) to maintain demo's rust-version of 1.60
Adding clap v4.0.32 to dependencies
Updating crates.io index
Locking 33 packages to latest Rust 1.60 compatible versions
Adding clap v4.0.32 (available: v4.5.23, requires Rust 1.74)
Можно переопределить это поведение при проверке зависимостей в CI:
$ CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS=allow cargo update
Updating crates.io index
Locking 12 packages to latest compatible versions
Updating clap v4.0.32 -> v4.5.23
Вы также можете включить такое поведение, установив package.resolver = "3"
в файле Cargo.toml, но для этого потребуется повысить вашу MSRV до 1.84. Новый резолвер будет включён по умолчанию для проектов, использующих редакцию 2024 (которая будет стабилизирована в Rust 1.85).
Это даёт авторам библиотек больше гибкости при принятии решения о внедрении новых версий языка Rust. Ранее библиотека, использующая новую версию Rust, заставляла пользователей, использующих более старую, либо обновлять её для всего проекта, либо вручную выбирать такую версию библиотеки, которая будет совместима с текущей версией Rust (и избегать запуска cargo update
). Теперь эти пользователи смогут автоматически использовать старые версии библиотек.
Смотрите документацию для более подробного понимания политик MSRV.
Начало миграции на новый резолвер трейтов
Компилятор Rust находится в процессе перехода к новой реализации резолвера трейтов. Резолвер трейтов следующего поколения представляет собой новую реализацию основного компонента системы типов Rust. Он не только отвечает за проверку соответствия границ трейта, например Vec<T>: Clone
, но также используется многими другими частями системы типов, такими как нормализация (определение базового типа <Vec<T> as IntoIterator>::Item
) и сравнения идентичности типов (совпадают ли T
и U
).
В Rust 1.84 новый резолвер используется для проверки согласованности реализаций трейтов. На высоком уровне согласованность отвечает за то, чтобы при рассмотрении ещё не написанного или не видимого из других крейтов кода присутствовало не более одной реализации трейта для данного типа.
Таким образом мы устраняем сразу несколько проблем, связанных с корректностью старого резолвера (в основном теоретических), которые могли привести к потенциальным ошибкам вида "conflicting implementations of trait ..." — о которых, впрочем, ранее не сообщалось. Мы ожидаем, что объём затронутого этим изменением кода будет минимален, основываясь на оценке доступного кода с помощью Crater. Также теперь мы будем уверены, что реализации не перекрываются, что расширяет возможности по написанию кода.
Чтобы получить больше информации, смотрите предыдущий пост в блоге и отчёт о стабилизации.
API строгого происхождения
В Rust указатели — это не просто число или адрес. Для примера, "использование после освобождения" — это неопределённое поведение, даже если вам повезёт и освобождённая память будет реаллоцирована до того, как вы запишете её или прочтёте. В качестве другого примера, запись через указатель, полученный из ссылки &i32
, также является неопределённым поведением, даже если запись в тот же адрес с помощью другого указателя разрешена. Основная закономерность здесь заключается в том, что имеет значение способ вычисления указателя, а не только адрес, который является результатом этого вычисления. По этой причине мы говорим, что указатели имеют происхождение: чтобы полностью охарактеризовать неопределённое поведение, связанное с указателями в Rust, мы должны не только знать адрес, на который указывает указатель, но и отслеживать, от каких других указателей он произошел.
В большинстве случаев программистам не нужно сильно беспокоиться о происхождении указателя, так как вполне понятно, откуда он был получен. Однако при преобразовании указателей в целые числа и обратно происхождение результирующего указателя неопределённо. В этом релизе Rust добавляет набор API, которые во многих случаях могут заменить использование приведения целочисленных указателей и, следовательно, избежать двусмысленностей, присущих таким приведениям. В частности, шаблон использования младших битов выровненного указателя для хранения дополнительной информации теперь может быть реализован без преобразования указателя в целое число или обратно. Это упрощает анализ кода для компилятора, а также даёт преимущества таким инструментам, как Miri, и таким архитектурам, как CHERI, которые предназначены для обнаружения и диагностики неправильного использования указателей.
Для более детальной информации смотрите документацию о происхождении в стандартной библиотеке.
Стабилизированные API
Ipv6Addr::is_unique_local
Ipv6Addr::is_unicast_link_local
core::ptr::with_exposed_provenance
core::ptr::with_exposed_provenance_mut
<ptr>::addr
<ptr>::expose_provenance
<ptr>::with_addr
<ptr>::map_addr
<int>::isqrt
<int>::checked_isqrt
<uint>::isqrt
NonZero::isqrt
core::ptr::without_provenance
core::ptr::without_provenance_mut
core::ptr::dangling
core::ptr::dangling_mut
Pin::as_deref_mut
Следующие API теперь можно использовать в контексте const
:
AtomicBool::from_ptr
AtomicPtr::from_ptr
AtomicU8::from_ptr
AtomicU16::from_ptr
AtomicU32::from_ptr
AtomicU64::from_ptr
AtomicUsize::from_ptr
AtomicI8::from_ptr
AtomicI16::from_ptr
AtomicI32::from_ptr
AtomicI64::from_ptr
AtomicIsize::from_ptr
<ptr>::is_null
<ptr>::as_ref
<ptr>::as_mut
Pin::new
Pin::new_unchecked
Pin::get_ref
Pin::into_ref
Pin::get_mut
Pin::get_unchecked_mut
Pin::static_ref
Pin::static_mut
Прочие изменения
Проверьте всё, что изменилось в Rust, Cargo и Clippy.
Кто работал над 1.84.0
Многие люди собрались вместе, чтобы создать Rust 1.84.0. Без вас мы бы не справились. Спасибо!
От переводчиков
С любыми вопросами по языку Rust вам смогут помочь в русскоязычном Телеграм-чате или же в аналогичном чате для новичковых вопросов. Если у вас есть вопросы по переводам или хотите помогать с ними, то обращайтесь в чат переводчиков.