(в силу непонятных причин я почему-то полностью пропустил этот релиз, который был аж 28 мая)
Вышла версия Rust 1.96.0! Как всегда, тут только избранные части, а всё целиком в детальных заметках о релизе.
▪️До стабильной версии дошли
Range, RangeFrom и RangeInclusive из core::range. В отличие от существующих типов диапазонов, эти типы реализуют IntoIterator, но не Iterator. Это позволяет им быть Copy и иметь публичные поля без подводных камней, присущих неявно копируемым итераторам. Как вы могли заметить, в этот список не входят RangeTo и RangeFull, но они и так не могли быть итераторами и потому реализовывали Copy. В следующей edition планируют переключить синтаксис диапазонов на создание этих новых типов. До этого переключение между типами облегчено за счёт реализаций From между новыми и старыми типами.▪️Стабилизировали макросы
assert_matches! и debug_assert_matches!, которые проверяют не на равенство, а на соответствие паттерну (и потому могут дать более внятное сообщение об ошибке, чем assert_eq!. Пример из блога:use core::assert_matches;
/// [Random Number](https://xkcd.com/221/)
fn get_random_number() -> u32 {
// chosen by a fair dice roll.
// guaranteed to be random.
4
}
fn main() {
assert_matches!(get_random_number(), 1..=6);
}
Пример сообщения об ошибке:
use core::assert_matches;
fn main() {
let x = ('a', None::<i32>);
assert_matches!(x, ('a' | 'b' | 'c', Some(42)));
}
⬇️
thread 'main' (31) panicked at src/main.rs:5:5:
assertion `left matches right` failed
left: ('a', None)
right: ('a' | 'b' | 'c', Some(42))
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Как и другие
assert*-макросы, туда можно добавить аргументы для дополнительного форматирования при панике.Как вы могли заметить, в коде есть явные импорты этого макроса. К сожалению, в прелюдию их не добавили, поскольку уже есть широко используемый сторонний крейт с этими макросами, и такое добавление создало бы конфликты имён в большом количестве кода.
▪️Теперь можно итерироваться по диапазонам из беззнаковых `NonZero` чисел.
▪️Определение "valid to read/write" для сырых указателей теперь явно исключает null. Некоторые функции, тем не менее, всё ещё позволяют пользоваться null-указателями для доступов нулевого размера, но теперь это исключения из общего правила.
(согласно CAD97 — члену команды операционной семантики — такое поведение было и раньше, просто теперь оно задокументировано)
▪️Манифесты для cargo теперь поддерживают назначение флагов для rustdoc в зависимости от cfg-предикатов.
▪️rustdoc теперь не вырезает <p>-теги из сообщений о устаревании (deprecation).
▪️rustdoc теперь разделяет функции на типе в боковой панели на ассоциированные функции (которые нельзя вызвать через точку) и методы. Полезно, но терминология, на мой взгляд, неудачная: методы тоже являются ассоциированными функциями.
▪️
repr(Int) меняет представление enum-ов, делая явный дискриминант всегда существующим... По крайне мере, в теории. Оказалось, что ранее для ненаселённого типа включались оптимизации раскладки, которые меняли размер таких типов в ноль, вопреки тому, что обещала документация. Теперь это пофиксили.▪️Приватные типы в RPITIT ("return position impl trait impl trait") теперь являются ошибкой компиляции.