diff --git a/ru/announcements/2025-01-09-Rust-1.84.0.md b/ru/announcements/2025-01-09-Rust-1.84.0.md index 5e74874..be5e873 100644 --- a/ru/announcements/2025-01-09-Rust-1.84.0.md +++ b/ru/announcements/2025-01-09-Rust-1.84.0.md @@ -21,7 +21,7 @@ $ rustup update stable ### Cargo учитывает версию Rust при выборе версии зависимости -В 1.84.0 стабилизирован резолвер, учитывающий минимально поддерживаемую версию Rust (MSRV), который отдаёт предпочтение версии зависимости, указанной в проекте [MSRV](https://doc.rust-lang.org/cargo/reference/rust-version.html). С выбором версий пакетов, учитывающим MSRV, снижается сложность поддержки старых наборов тулчейнов за счёт того, что не приходится вручную выбирать старую версию для каждой зависимости. +В 1.84.0 стабилизирован резолвер, учитывающий минимально поддерживаемую версию Rust (MSRV), который предпочитает те версии зависимости, которые совместимы с указанной в проекте [MSRV](https://doc.rust-lang.org/cargo/reference/rust-version.html). С учитывающим MSRV выбором версий пакетов снижается сложность поддержки старых наборов тулчейнов. Это происходит за счёт того, что для каждой зависимости больше не приходится выбирать старую версию вручную. Вы можете включить новый резолвер через [`.cargo/config.toml`](https://doc.rust-lang.org/cargo/reference/config.html#resolverincompatible-rust-versions): @@ -53,23 +53,23 @@ $ CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS=allow cargo update Вы также можете включить такое поведение, установив [`package.resolver = "3"`](https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions) в файле Cargo.toml, но для этого потребуется повысить ваш MSRV до 1,84. Новый резолвер будет включён по умолчанию для проектов, использующих редакцию 2024 (которая будет стабилизирована в Rust 1.85). -Это дает авторам библиотек больше гибкости при принятии решения о внедрении новых Rust. Ранее библиотека, использующая новую версию Rust, заставляла пользователей, использующих более старую версия Rust, либо обновлять её для всего проекта, либо вручную выбирать старую версию библиотеки, совместимую с прошлой версией Rust (и избегать запуска `cargo update`). Теперь эти пользователи смогут автоматически использовать старые версии библиотек. +Это дает авторам библиотек больше гибкости при принятии решения о внедрении новых версий языка Rust. Ранее библиотека, использующая новую версию Rust, заставляла пользователей, использующих более старую, либо обновлять её для всего проекта, либо вручную выбирать такую версию библиотеки, которая будет совместима с текущей версией Rust (и избегать запуска `cargo update`). Теперь эти пользователи смогут автоматически использовать старые версии библиотек. Смотрите [документацию](https://doc.rust-lang.org/cargo/reference/rust-version.html#setting-and-updating-rust-version) для более подробного понимания политик MSRV. ### Начало миграции на новый резолвер трейтов -Компилятор Rust находится в процессе перехода к новой реализации резолвера трейтов. Резолвер трейтов следующего поколения представляет собой новую реализацию основного компонента системы типов Rust. Он не только отвечает за проверку соответствия границ трейта, например `Vec: Clone`, но также используется многими другими частями системы типов, такими как нормализация (определение базового типа ` as IntoIterator>::Item`) и сравнения идентичности типов (проверка, совпадают ли `T` и `U`). +Компилятор Rust находится в процессе перехода к новой реализации резолвера трейтов. Резолвер трейтов следующего поколения представляет собой новую реализацию основного компонента системы типов Rust. Он не только отвечает за проверку соответствия границ трейта, например `Vec: Clone`, но также используется многими другими частями системы типов, такими как нормализация (определение базового типа ` as IntoIterator>::Item`) и сравнения идентичности типов (совпадают ли `T` и `U`). -В Rust 1.84 новый резолвер используется для проверки согласованности реализаций трейтов. На высоком уровне согласованность отвечает за то, чтобы при рассмотрении еще не написанного или не видимого из других крейтов кода присутствовало не более одной реализации трейта для данного типа. +В Rust 1.84 новый резолвер используется для проверки согласованности реализаций трейтов. На высоком уровне согласованность отвечает за то, чтобы при рассмотрении ещё не написанного или не видимого из других крейтов кода присутствовало не более одной реализации трейта для данного типа. -Таким образом мы устраняем сразу несколько проблем, связанных с корректностью старого резолвера (в основном теоритческих), которые могли привести к потенциальным ошибкам вида "conflicting implementations of trait ...", о которых, впрочем, ранее не сообщалось. Мы ожидаем, что объем затронутого этим изменением кода будет минимален, основываясь на оценке доступного кода с помощью [Crater]. Также теперь мы будем уверены, что реализации *не перекрываются*, что расширяет наши возможности по написанию кода. +Таким образом мы устраняем сразу несколько проблем, связанных с корректностью старого резолвера (в основном теоритческих), которые могли привести к потенциальным ошибкам вида "conflicting implementations of trait ..." — о которых, впрочем, ранее не сообщалось. Мы ожидаем, что объем затронутого этим изменением кода будет минимален, основываясь на оценке доступного кода с помощью [Crater]. Также теперь мы будем уверены, что реализации *не перекрываются*, что расширяет возможности по написанию кода. Чтобы получить больше информации, смотрите [предыдущий пост в блоге](https://blog.rust-lang.org/inside-rust/2024/12/04/trait-system-refactor-initiative.html) и [отчёт о стабилизации](https://github.com/rust-lang/rust/pull/130654). ### API строгого происхождения -В Rust [указатели — это не просто число или адрес](https://rust-lang.github.io/rfcs/3559-rust-has-provenance.html). Для примера, "использование после освобождения" — это неопределённое поведение, даже если вам повезёт и освобождённая память будет реаллоцирована до того, как вы запишете ее или прочтёте. В качестве другого примера, запись через указатель, полученный из ссылки `&i32`, также является неопределённым поведением, даже если запись в тот же адрес с помощью другого указателя разрешена. Основная закономерность здесь заключается в том, что *имеет значение способ вычисления указателя*, а не только адрес, который является результатом этого вычисления. По этой причине мы говорим, что указатели имеют ** происхождение**: чтобы полностью охарактеризовать неопределённое поведение, связанное с указателями в Rust, мы должны знать не только адрес, на который указывает указатель, но и отслеживать, от каких других указателей он получен. +В Rust [указатели — это не просто число или адрес](https://rust-lang.github.io/rfcs/3559-rust-has-provenance.html). Для примера, "использование после освобождения" — это неопределённое поведение, даже если вам повезёт и освобождённая память будет реаллоцирована до того, как вы запишете ее или прочтёте. В качестве другого примера, запись через указатель, полученный из ссылки `&i32`, также является неопределённым поведением, даже если запись в тот же адрес с помощью другого указателя разрешена. Основная закономерность здесь заключается в том, что *имеет значение способ вычисления указателя*, а не только адрес, который является результатом этого вычисления. По этой причине мы говорим, что указатели имеют ** происхождение**: чтобы полностью охарактеризовать неопределённое поведение, связанное с указателями в Rust, мы должны не только знать адрес, на который указывает указатель, но и отслеживать, от каких других указателей он получен. В большинстве случаев программистам не нужно сильно беспокоиться о происхождении указателя, так как вполне понятно, откуда он был получен. Однако при преобразовании указателей в целые числа и обратно происхождение результирующего указателя неопределённо. В этом релизе Rust добавляет набор API, которые во многих случаях могут заменить использование приведения целочисленных указателей и, следовательно, избежать двусмысленностей, присущих таким приведениям. В частности, шаблон использования младших битов выровненного указателя для хранения дополнительной информации теперь может быть реализован без преобразования указателя в целое число или обратно. Это упрощает анализ кода для компилятора, а также даёт преимущества таким инструментам, как [Miri](https://github.com/rust-lang/miri), и таким архитектурам, как [CHERI](https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/), которые предназначены для обнаружения и диагностики неправильного использования указателей.