Команда 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. Без вас мы бы не справились. Спасибо!

