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 rustupthen to upgrade to version 1.59.0 you just need to run the command:

rustup update stable

If you don’t already have rustupthen 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 reportmentioned 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 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 для ToLowercase

  • DoubleEndedIterator для ToUppercase

  • TryFrom<&mut [T]> for [T; N]

  • UnwindSafe для Once

  • RefUnwindSafe для Once

  • armv8 neon intrinsics for aarch64

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.

Similar Posts

Leave a Reply