• Original address: Announcing Rust 1.51.0
  • By The Rust Release Team
  • The Nuggets translation Project
  • Permanent link to this article: github.com/xitu/gold-m…
  • Translator: Luo Zhu
  • Proofread with: PassionPenguin

The Rust team is pleased to announce the release of Rust V1.51.0. Rust is a programming language that enables anyone to build reliable and efficient software.

If you have installed an older version of Rust through Rustup, you can quickly update to Rust 1.51.0 with the following command:

rustup update stable
Copy the code

If you don’t have Rustup installed, you can get it on our website page. Alternatively, you can check out the full release of V1.51.0 on GitHub.

Contents contained in V1.51.0

This release represents a number of new additions and improvements to Rust and Cargo over a long period of time, stabilizing the simplest possible Const Generics, and Cargo’s new feature parser. So, let’s take a look at these things.

Const Generics MVP (Const generic)

MVP (Minimum Viable Product) is a term used in the development of a new Product. It refers to a Product that has a part of functionality that is just right for the designer to express his core design concept.

Prior to this release, Rust allowed you to parameterize types within the lifecycle or type. For example, if we create a struct and want its data elements to be of a generic type, we can write the following code:

struct FixedArray<T> {
    // Type generic definition
    list: [T; 32]
    // We use it here
}
Copy the code

If we then use FixedArray < U8 >, the compiler will generate a singleton version of FixedArray as follows:

struct FixedArray<u8> {
    list: [u8; 32]}Copy the code

This is a powerful feature that lets you write reusable code with no runtime overhead. However, until this release, you can’t generalize values of these types easily. This is most obvious in arrays, which include length ([T; N]) in their type definition, which you couldn’t generalize before. Now with 1.51.0, you can write code that generics any value of type INTEGER, bool, or CHAR! (Values using struct or enum are still unstable.)

struct Array<T, const LENGTH: usize> {
    // Const generic definition
    list: [T; LENGTH]
    // We use it here
}
Copy the code

Now if we use Array

, the compiler will generate a singleton version of FixedArray as follows:
,>

struct Array<u8.32> {
    list: [u8; 32]}Copy the code

Const generics add an important new tool for library designers to create new, powerful compile-time security apis. If you want to learn more about Const Generics, you can also check out the Const Generics MVP Hits Beta for more information about this feature and its current limitations. We can’t wait to see what new libraries and apis you’ve created!

array::IntoIterStability of the

As part of the stabilization of Const generics, we are also stabilizing its new API, STD :: Array ::IntoIter. IntoIter allows you to create value-by-iterators on any array. Previously, there was no convenient way to go through all the values of a set of numbers, just reference them.

fn main() {
  let array = [1.2.3.4.5];

  / / in the past
  for item in array.iter().copied() {
      println!("{}", item);
  }

  / / now,
  for item in std::array::IntoIter::new(array) {
      println!("{}", item); }}Copy the code

Note that this is added as a separate method, not as a method to add.into_iter() to the array. Due to the introduction of some destructive changes, currently.into_iter() refers to slicing by-reference iterators. We’re exploring ways to make it more ergonomic in the future.

Cargo’s new feature parser

Dependency management is a challenge, and one of the hardest parts of it is choosing which versions of dependencies to use when two different packages depend on it. This includes not only its version number, but also features that are enabled or not enabled for the package. The default behavior of Cargo is to merge functionality when a single package is referenced multiple times in a dependency diagram.

For example, suppose you have A dependency named foo with functions A and B, which is used by the bar and BAz packages, but bar depends on foo+A and baz depends on foo+B. Cargo will merge these two functions and compile Foo as foo+AB. The advantage of this is that you only need to compile Foo once and then reuse it for bar and baz.

But there is a downside. What if the functionality enabled in a build dependency is incompatible with the target to build?

A common example in an ecosystem is the many #! [NO_STD] The optional STD functionality that crate contains, which allows Crate to provide additional functionality when STD is available. Now suppose you want to use #! #! Using foo in the [no_std] binary [no_std] version and use foo when building in build.rs. If your build time dependency depends on foo+ STD, then your binary will now also depend on foo+ STD, which means it will no longer compile because STD is not available for your target platform.

This has been a long-standing problem with Cargo. In this release, there is a new resolver option in your Cargo. Toml, where you can set resolver=”2″ to tell Cargo to try a new way to resolve functionality. You can see RFC 2957 for a detailed description of the behavior, which can be summarized as follows:

  • Dev dependencies: When the package is shared by regular dependency and dev-dependency, dev-dependency is enabled only if the current version includes dev-dependencies.
  • The Host Dependencies: When packages are shared by regular dependency, build-dependency, or proc-macro, the functionality for regular dependency will be independent of build-dependency or proc-macro.
  • Target Dependencies: When packages appear multiple times in the build diagram and one instance is a target-specific dependency, target-specific dependencies are enabled only if the Target is currently being built.

While this may result in some Grates being compiled more than once, it provides a more intuitive development experience when using the functionality with Cargo. For more information, read the Feature Resolver section. We would like to thank Cargo and all the hard work involved in designing and implementing the new parser!

[package]
resolver = "2"
# Or you are using workspace
[workspace]
resolver = "2"
Copy the code

Split debugging Information

Although not often highlighted in releases, the Rust team has been working hard to improve Rust compile times, and this release is one of Rust’s biggest improvements on macOS in a long time. Debugging information maps binary code back to your source code so that the program can provide you with more information about problems at run time. In macOS, previously a tool called dsymutil was used to gather debugging information into a single.dsym folder, which could take some time and take up a lot of disk space.

Gathering all debugging information into this directory helps you look it up at run time, especially if the binaries are moving. The downside is that even if you make minor changes to the program, dsymutil will need to run on the entire final binary to produce the final.dsym folder. This can increase build time, especially for large projects, because all dependencies are always collected, but it is a necessary step because without it Rust’s standard library would not know how to load debugging information on macOS.

More recently, Rust backtracking has switched to using other backends that support loading debugging information without running DSYmutil, and we have stabilized support for skipping dsymutil running. This can significantly speed up builds that contain debugging information and significantly reduce the amount of disk space used. We haven’t run extensive benchmarks yet, but we’ve seen a lot of feedback on people using this behavior to build faster on macOS.

You can unpack in Cargo by setting the -csplit-Debuginfo =unpacked flag when running RUSTC or by setting the split-Debuginfo [profile] option. The unzip option instructs RUSTC to keep the.o object files in the build output directory instead of deleting them, and skip the step of running dsymutil. Rust’s backtracking support is smart enough to know how to find these.o files. Tools such as LLDB also know how to do this. This should work as long as you don’t need to move the binaries to another location while keeping the debugging information.

[profile.dev]
split-debuginfo = "unpacked"
Copy the code

Stability of the API

Overall, this release stabilizes 18 new methods for a variety of types, including Slice and Peekable. Of particular note is PTR ::addr_of! And PTR: : addr_of_mut! They allow you to create raw Pointers to unaligned fields. Previously this was not possible because Rust required &/&mut to be aligned to the initialized data, and &addr as * const _ would result in undefined behavior because &addr needed to be aligned. These macros now allow you to safely create unaligned Pointers.

use std::ptr;

#[repr(packed)]
struct Packed {
    f1: u8,
    f2: u16,}let packed = Packed { f1: 1, f2: 2 };
// '& Packed. F2' will create unaligned references and therefore undefined behavior!
letraw_f2 = ptr::addr_of! (packed.f2);assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);
Copy the code

The following methods have been stabilized:

  • Arc::decrement_strong_count
  • Arc::increment_strong_count
  • Once::call_once_force
  • Peekable::next_if_eq
  • Peekable::next_if
  • Seek::stream_position
  • array::IntoIter
  • panic::panic_any
  • ptr::addr_of!
  • ptr::addr_of_mut!
  • slice::fill_with
  • slice::split_inclusive_mut
  • slice::split_inclusive
  • slice::strip_prefix
  • slice::strip_suffix
  • str::split_inclusive
  • sync::OnceState
  • task::Wake

Other updates

There are other changes in the Rust 1.51.0 release: see Rust, Cargo, and Clippy.

1.51.0 contributors

A lot of good developers came together to create Rust 1.51.0. We couldn’t have done it without your support. Thank you!

If you find any mistakes in your translation or other areas that need to be improved, you are welcome to the Nuggets Translation Program to revise and PR your translation, and you can also get the corresponding reward points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.


The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.