Вышла новая версия языка программирования Rust, Rust 1.59.0. В этой версии стабилизированы следующие возможности:
Встроенный ассемблер
Теперь можно внедрять инструкции языка ассемблера непосредственно в исходный код и писать низкоуровневый код с доступом к специализированным машинным инструкциям:
use std::arch::asm;
// Multiply x by 6 using shifts and adds
let mut x: u64 = 4;
unsafe {
asm!(
"mov {tmp}, {x}",
"shl {tmp}, 1",
"shl {x}, 2",
"add {x}, {tmp}",
x = inout(reg) x,
tmp = out(reg) _,
);
}
assert_eq!(x, 4 * 6);
Встроенный ассемблер стабилизирован для следующих архитектур: x86 и x86-64, ARM, AArch64, RISC-V.
Деструктурирующие присваивания
Теперь можно использовать кортежи, срезы и шаблоны структур в левой части присваивания:
let (a, b, c, d, e);
(a, b) = (1, 2);
[c, .., d, _] = [1, 2, 3, 4, 5];
Struct { e, .. } = Struct { e: 5, f: 3 };
assert_eq!([1, 2, 1, 4, 5], [a, b, c, d, e]);
Примечание: деструктурирующие присваивания с такими операторами как +=
запрещены.
Значения по умолчанию для константных дженериков и чередование типов параметра
Универсальные типы теперь могут указывать значения по умолчанию для своих универсальных констант:
struct ArrayStorage<T, const N: usize = 2> {
arr: [T; N],
}
impl<T> ArrayStorage<T> {
fn new(a: T, b: T) -> ArrayStorage<T> {
ArrayStorage {
arr: [a, b],
}
}
}
Раньше параметры типа должны были стоять перед всеми константными параметрами. Это ограничение было ослаблено и теперь их можно чередовать:
fn cartesian_product<
T, const N: usize,
U, const M: usize,
V, F
>(a: [T; N], b: [U; M], f: F) -> [[V; N]; M]
where
F: FnMut(&T, &U) -> V
{
// ...
}
Предупреждения о несовместимости в будущем
Теперь Cargo будет показывать предупреждение, если та или иная зависимость будет отклонена в будущих версиях Rust. После выполнения команд cargo build
или cargo check
, можно увидеть примерно такое предупреждение:
warning: the following packages contain code that will be rejected by a future version of Rust: old_dep v0.1.0
note: to see what the problems were, use the option `--future-incompat-report`, or run `cargo report future-incompatibilities --id 1`
При помощи команды cargo report
можно увидеть полный отчёт по коду, который будет отклонён.
Создание урезанных бинарников
Теперь Rust поддерживает удаление отладочной информации во время компоновки. Для этого в Cargo.toml
надо добавить строку strip
:
[profile.release]
strip = "debuginfo"
Можно также указать symbols
или просто true
для удаления всей символьной информации там, где это поддерживается.
Инкрементальная компиляция отключена по умолчанию
Из-за возможности возникновения ошибок десериализации (и паник) в этой версии отключена поддержка инкрементальной компиляции (можно принудительно включить через переменную среды RUSTC_FORCE_INCREMENTAL=1
). Исправление уже присутствует в бета-версии Rust 1.60; если до релиза не будут найдены другие ошибки, связанные с этой проблемой, инкрементальная компиляция будет включена обратно.
Стабилизированные API
- std::thread::available_parallelism
- Result::copied
- Result::cloned
- arch::asm!
- arch::global_asm!
- ops::ControlFlow::is_break
- ops::ControlFlow::is_continue
- TryFrom for u8
- char::TryFromCharError implementing Clone, Debug, Display, PartialEq, Copy, Eq, Error
- iter::zip
- NonZeroU8::is_power_of_two
- NonZeroU16::is_power_of_two
- NonZeroU32::is_power_of_two
- NonZeroU64::is_power_of_two
- NonZeroU128::is_power_of_two
- DoubleEndedIterator for ToLowercase
- DoubleEndedIterator for ToUppercase
- TryFrom<&mut [T]> for [T; N]
- UnwindSafe for Once
- RefUnwindSafe for Once
- armv8 neon intrinsics for aarch64
Следующие стабильные функции теперь являются const
:
- mem::MaybeUninit::as_ptr
- mem::MaybeUninit::assume_init
- mem::MaybeUninit::assume_init_ref
- ffi::CStr::from_bytes_with_nul_unchecked
Другие изменения
Все остальные изменения и новшества можно увидеть по ссылке: https://blog.rust-lang.org/2022/02/24/Rust-1.59.0.html
Более подробный список изменений доступен по ссылке: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1590-2022-02-24