inline assembler, destructuring assignment, disable incremental compilation
The Rust team publishes a new version of the language – 1.59.0. Rust is a programming language that allows anyone to create reliable and efficient software.
[политическое сообщение удалено из-за правил хабра]
If you have a previous version of Rust installed via rustup
then to upgrade to version 1.59.0 you just need to run the command:
rustup update stable
If you don’t already have rustup
then you can install it with pages on our website, as well as detailed release notes for 1.59.0 on GitHub.
What is stabilized in 1.59.0
Inline assembler
The Rust language now supports inline assembly, allowing you to create applications that require the most low-level control over their execution or access to specialized machine instructions.
For example, when compiling for x86-64, you can now write:
use std::arch::asm;
// Умножить x на 6 с помощью сдвигов и сложений
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);
String formatting syntax used for naming registers in macros asm!
And global_asm!
used in the usual string formatting Rust, so it should be familiar to Rust programmers.
The assembly language and instructions available for inline assembler differ depending on the target architecture. Today, the stable Rust compiler supports inline building on the following architectures:
x86 and x86-64
ARM
AArch64
RISC-V
You can see more examples of inline assembler at Rust By Exampleand more detailed documentation can be found in reference book.
Destructuring assignment
You can now use tuples, slices, and struct patterns on the left side of the assignment.
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]);
This makes assignments more consistent with bindings. let
, who have supported this for a long time. Note that destructuring assignment is not allowed in statements such as +=
.
Default Values for Constant Generics and Interleaving
Generic types can now be given default values for their const generics. For example, now you can write the following:
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],
}
}
}
Previously, type parameters had to be written before all const parameters. This limitation has been relaxed and you can now alternate between them.
fn cartesian_product<
T, const N: usize,
U, const M: usize,
V, F
>(a: [T; N], b: [U; M]) -> [[V; N]; M]
where
F: FnMut(&T, &U) -> V
{
// ...
}
Future incompatibility warnings
Sometimes bugs in the Rust compiler cause it to accept code that shouldn’t be accepted. An example of this was borrowing fields from a boxed structureallowed in secure code.
Although this happens very rarely, this behavior can be quite destructive – when there is code in the crate used by your project that will no longer be allowed. You may not even notice this until your project inexplicably stops building!
Cargo now shows you warnings when a dependency is deprecated by a future version of Rust. After launch cargo build
or cargo check
you will be able to see:
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`
You can run the command cargo report
mentioned in the warning to see a full report of the code that will be rejected. This gives you time to update your dependency before it breaks the entire build.
Creating stripped down binaries
Often stripping information, such as debug information, from the binaries you supply will reduce their size.
This can be done manually at any time after creating the binary, but cargo and rustc now support truncation at the linking stage. To enable this functionality, add Cargo.toml
following:
[profile.release]
strip = "debuginfo"
This will strip debug information from release builds. You can also put "symbols"
or simply true
to strip out all the character information that is possible.
The standard library usually comes with debug symbols and debug information, so Rust binaries built without debug information include default library debug information by default. Using the option strip
allows you to remove this extra information to create more compact binaries.
For more information see Cargo documentation.
Incremental compilation is disabled by default
Version 1.59.0 disables incremental mode by default (unless explicitly requested via environment variable RUSTC_FORCE_INCREMENTAL=1
). This mitigates the effects of a known error #94124which can cause deserialization errors (and panics) during compilation with incremental compilation enabled.
Special fix for #94124 appeared and is currently in beta version 1.60, which will be released in six weeks. At this time, we are not aware of other issues that would prompt the decision to disable incremental compilation in the 1.60 stable release, and if they do not occur, it is likely that incremental compilation will be enabled again in the 1.60 stable release. Incremental compilation remains enabled by default in beta and nightly channels.
As always, we encourage users to test the nightly and beta channels and report any issues they find, especially regarding additional bugs. This is the best way to make sure the Rust team can assess if there is a break and how many users it affects.
Stabilized APIs
The following trait methods and implementations have been stabilized:
std::thread::available_parallelism
Result::copied
Result::cloned
arch::asm!
arch::global_asm!
ops::ControlFlow::is_break
ops::ControlFlow::is_continue
TryFrom<char> для u8
char::TryFromCharError
implementingClone
,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 для ToLowercase
DoubleEndedIterator для ToUppercase
TryFrom<&mut [T]> for [T; N]
UnwindSafe для Once
RefUnwindSafe для Once
The following previously stabilized APIs became const
:
mem::MaybeUninit::as_ptr
mem::MaybeUninit::assume_init
mem::MaybeUninit::assume_init_ref
ffi::CStr::from_bytes_with_nul_unchecked
Other changes
IN syntax, Cargo package manager And clippy analyzer some changes have also been made.
Members 1.59.0
A lot of people came together to create Rust 1.59.0. We couldn’t have done this without all of you. Thanks!
From translators
For any questions about the Rust language, we can help you with Russian-language Telegram chat or in a similar chat for newbie questions. If you have questions about translations or want to help with them, please contact translators chat. You can also support us on OpenCollective.
This translation was published by @belanchuk, @TelegaOvoshey, @funkill, @ozkriff and @MaybeWaffle.