We present to your attention a translation of the publication on the new version of the beloved Rust programming language.
The Rust development team is pleased to announce the release of a new version, 1.37.0. Rust is a programming language that allows everyone to create reliable and efficient software.
If you installed the previous version of Rust using rustup, then to upgrade to version 1.37.0 you just need to run the following command:
$ rustup update stable
If you have not already installed rustup
, you can install it from the corresponding page of our website, as well as see detailed release notes on GitHub.
Major innovations in Rust 1.37.0 include links to enum
options via type aliases, a built-in cargo vendor
, unnamed constants, profile-guided optimization, the default-run
key for Cargo projects and #[repr(align(N))]
for enumerations. See the detailed release notes for more information.
enum
Starting with Rust 1.37.0, it became possible to refer to enum
variants through type aliases:
type ByteOption = Option<u8>; fn increment_or_zero(x: ByteOption) -> u8 { match x { ByteOption::Some(y) => y + 1, ByteOption::None => 0, } }
In impl
blocks Self
acts as an alias of type, therefore in Rust 1.37.0 it became possible to refer to enumeration options using the Self::Variant
syntax:
impl Coin { fn value_in_cents(&self) -> u8 { match self { Self::Penny => 1, Self::Nickel => 5, Self::Dime => 10, Self::Quarter => 25, } } }
More specifically, now Rust allows you to refer to enumeration options via "type-relative resolution" , <MyType<..>>::Variant
. A more detailed description is available in the stabilization report .
After several years of existence as a separate package , the cargo vendor
team is now integrated into Cargo. This command extracts all the dependencies of your project into the vendor/
directory and shows the configuration fragment necessary for using the vendor code during assembly.
cargo vendor
already used in real projects: the rustc
compiler uses it to send all its dependencies to release tarballs, and projects with mono-repositories use it to fix the dependency code in version control.
Now you can create an (unnamed) (const
) by replacing its identifier with underscore ( _
). For example, in the rustc
compiler rustc
we found this code:
/// , /// , - . #[macro_export] macro_rules! static_assert_size { ($ty:ty, $size:expr) => { const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()]; // ^ . } } static_assert_size!(Option<Box<String>>, 8); // 1. static_assert_size!(usize, 8); // 2.
Pay attention to the second static_assert_size!(..)
: thanks to the use of unnamed constants, it became possible to prevent name conflicts when declaring new elements. Earlier you would have to write static_assert_size!(MY_DUMMY_IDENTIFIER, usize, 8);
. With the introduction of unnamed constants, it becomes easier to create ergonomic and reusable declarative and procedural macros for static analysis purposes.
Profile-Guided Optimization (PGO) is now available in the rustc
compiler, which can be enabled through the -C profile-generate
and -C profile-use
compiler flags.
Profile-Guided Optimization is a compiler optimization technique that analyzes test runs instead of source code. It works by compiling a program for optimization in two stages:
rustc
-C profile-generate
rustc
rustc
-C profile-use
For more information on Profile-Guided Optimization, see the corresponding chapter in the rustc compiler book .
cargo run
is a very convenient tool for quickly testing console applications. When several executable files are present in one package, you must explicitly declare the name of the executable file that you want to run using the --bin
flag. This makes cargo run
not as ergonomic as we would like, especially when a particular executable is called more often than others.
Rust 1.37.0 solves this problem by adding a new default-run
key to Cargo.toml
(section [package]
). Thus, if the --bin
flag is not --bin
, Cargo will launch the binary file declared in the configuration.
#[repr(align(N))]
Starting with Rust 1.37.0, the attribute #[repr(align(N))]
can be used to determine the alignment of enumerations in memory (previously this attribute was only allowed for structures ( struct
) and unions ( union
)). For example, an Align16
enumeration will, as expected, have an alignment of 16
bytes, while natural alignment without #[repr(align(16))]
will be 4
:
#[repr(align(16))] enum Align16 { Foo { foo: u32 }, Bar { bar: u32 }, }
The semantics of using #[repr(align(N))
for enumerations is the same as defining a wrapper for an AlignN<T>
structure with this alignment, and then using AlignN<MyEnum>
:
#[repr(align(N))] struct AlignN<T>(T);
Rust 1.37.0 stabilized the following components of the standard library:
BufReader::buffer
BufWriter::buffer
Cell::from_mut
Cell::as_slice_of_cells
DoubleEndedIterator::nth_back
Option::xor
{i,u}{8,16,64,128,size}::reverse_bits
Wrapping::reverse_bits
slice::copy_within
The syntax , the cargo package manager, and the Clippy analyzer have also undergone some changes.
A lot of people came together to create Rust 1.37.0. We could not have done this without all of you, thank you!
We would like to thank the two new Rust infrastructure sponsors who provided the resources needed to build Rust 1.37.0: Amazon Web Services (AWS) and Microsoft Azure:
With any questions on the Rust language, you can be helped in the Russian-language Telegram chat or in a similar chat for newcomers .
This article was jointly translated by andreevlex , ozkriff , funkill and Gymmasssorla .