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

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

$ rustup update stable

Если Rust ещё не установлен, вы можете получить rustup на соответствующей странице нашего сайта и ознакомиться с подробными release notes для 1.98.0.

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

Что нового в stable 1.98.0

Алгебраические методы для чисел с плавающей точкой

Типы с плавающей точкой f32 и f64 теперь имеют «алгебраические» методы для сложения, вычитания, умножения, деления и взятия остатка. Они позволяют оптимизировать эти операции, используя алгебраические свойства действительных чисел, хотя эти свойства не выполняются с учётом ограничений представления чисел с плавающей точкой. Точный набор оптимизаций не специфицирован, но может быть похож на оптимизации, которые вы видите с опцией -ffast-math в других языках.

Например, сложение чисел с плавающей точкой не ассоциативно, поэтому сумму вида a + b + c + d необходимо вычислять в левоассоциативном порядке, в котором она разобрана парсером, то есть ((a + b) + c) + d. Если записать ту же сумму как цепочку вызовов algebraic_add, компилятор может свободно менять порядок вычислений, например (a + b) + (c + d), чтобы вычислять частичные суммы одновременно. Использование этих алгебраических методов также часто включает более широкую векторизацию циклов.

Эти методы недетерминированы, поскольку компилятор может выбирать разные оптимизации, но они никогда не приводят к неопределённому поведению. Подробнее см. в документации библиотеки и в исходном предложении об изменении API.

Буферизованное форматирование целых чисел

Все примитивные целочисленные типы теперь имеют метод format_into, принимающий параметр &mut NumBuffer<Self> — буфер, достаточно большой для хранения десятичного представления любого значения этого типа. Сам буфер непрозрачен, но метод возвращает отформатированную строку &str с временем жизни, заимствованным из этого буфера.

Этот метод также обходит большую часть динамической диспетчеризации, которую вы получили бы при буферизованном форматировании через write!, что может существенно повысить производительность. Репозиторий itoa-benchmark теперь показывает, что format_into работает сопоставимо с самим itoa, так что этот метод может служить стандартной заменой этой зависимости и подобных ей.

Исправление взаимодействия между ManuallyDrop и Box

До Rust 1.96.0 в компиляторе Rust была ошибка, из-за которой следующий код приводил к неопределённому поведению:

let mut x = ManuallyDrop::new(Box::new(1));
unsafe { ManuallyDrop::drop(&mut x) };
let x = x; // UB!

Это происходит потому, что компилятор считает неопределённым поведением перемещение Box, который уже был освобождён (deallocated), и ManuallyDrop ранее распространял это свойство, так что перемещение ManuallyDrop<Box<_>>, где box уже освобождён, также считалось UB.

В Rust 1.96.0 мы исправили это, и этот код больше не является UB. В этом релизе мы обновили документацию ManuallyDrop, дав стабильную гарантию, что этот код и в будущем не будет UB. Подробнее см. в документации ManuallyDrop и в связанном RFC 3336.

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

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

Ознакомьтесь со всем, что изменилось в Rust, Cargo и Clippy.

Участники релиза 1.98.0

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