Rust 1.35.0 release

Rust 1.35.0 release


I present to your attention the translation publications about the new version of your favorite programming language Rust .


Introduction


The Rust programming language development team is pleased to announce a new version, 1.35.0. Rust is a programming language that allows everyone to develop reliable and fast software.


If you installed the previous version of Rust using rustup , getting the current version will not be difficult:


  $ rustup update stable  

If you still don’t have rustup , you can get it with the appropriate pages on our site.

What is included in the stable version?


The main innovations of this release are the implementation of FnOnce , FnMut and Fn traits on Box & lt; dyn FnOnce & gt; , Box & lt; dyn FnMut & gt; and Box & lt; dyn Fn & gt; respectively.


As well as embedded functions (closures) can be converted to unsafe function pointers. The dbg! macro entered in Rust 1.32.0 , can now be called without specifying arguments.


Moreover, this release has made many stabilizations of the standard library. Below are the most significant, but detailed analysis is available. these.


Fn * traits are implemented on Box & lt; dyn Fn * & gt;


In Rust 1.35.0, the traits of FnOnce , FnMut , and Fn implemented on Box & lt; dyn FnOnce & gt; , Box & lt; dyn FnMut & gt; and Box & lt; dyn Fn & gt; accordingly.


In the past, if you wanted to call a function encapsulated in the Box , you had to use FnBox because the Box & lt; dyn FnOnce & gt; objects and the like did not implement the corresponding Fn * . It also interfered with the transfer of functions encapsulated in the Box code to the executor of the trait Fn (it was suggested to create temporary embedded functions).


This was caused by the inability of the compiler to detect such implementations. This flaw was removed with the introduction of unsized_locals .


However, now you can use functions that are encapsulated in the Box even in places that are awaiting the implementation of a functional trait. For example, the code below compiles without errors:


  fn foo (x: Box & lt; dyn Fn (u8) - & gt; u8 & gt;) - & gt;  Vec & lt; u8 & gt;  {
  vec! [1, 2, 3, 4] .into_iter (). map (x) .collect ()
 }  

The Box & lt; dyn FnOnce & gt; objects can be invoked without too much fuss:


  fn foo (x: Box & lt; dyn FnOnce () & gt;) {
  x ()
 }  

Converting to unsafe pointers


Since Rust 1.19.0 it has been possible to convert embedded functions without captured the environment in function pointers.For example, you could write:


  fn twice (x: u8, f: fn (u8) - & gt; u8) - & gt;  u8 {
  f (f (x))
 }

 fn main () {
  assert_eq! (42, twice (0, | x | x + 21));
 }  

But unfortunately, this feature has not been extended to unsafe function pointers. This release introduced the changes described above:


 ///Secure invariants passed to `unsafe fn`.
 unsafe fn call_unsafe_fn_ptr (f: unsafe fn ()) {
  f ()
 }

 fn main () {
//SAFETY: there are no invariants
//This function is statically prevented from unsafe
//operations
  unsafe {
  call_unsafe_fn_ptr (|| {
  dbg! ();
  });
  }
 }  

Call dbg! () without arguments


Due to the abundance of println! calls as collective farm debuggers, at Rust 1.32.0 a macro was presented dbg ! . Recall that this macro allows you to quickly capture the result of a certain expression with context:


  fn main () {
  let mut x = 0;

  if dbg! (x == 1) {
  x + = 1;
  }

  dbg! (x);
 }  

The above lines of code will print in the terminal the result of the expression x == 1 and x respectively:


  [src/main.rs: 4] x == 1 = false
 [src/main.rs: 8] x = 0  

As mentioned in the previous section, where the higher-order function call_unsafe_fn_ptr can be called, dbg! () is also to be called without specifying arguments. This can be extremely useful for detecting selected software branches:


  fn main () {
  let condition = true;

  if condition {
  dbg! ();//[src/main.rs: 5]
  }
 }  

Standard Library Stabilization


In Rust 1.35.0, many of the components of the standard library were stabilized. In addition to this, some implementations have been made that you can read about here .


Copy the sign of a floating-point number to another number


With this release, new copysign methods have been added to floating-point primitives (more specifically, f32 and f64 ):



As you might guess from the name of the methods, you can use them to copy the sign of one number to another:


  fn main () {
  assert_eq! (3.5_f32.copysign (-0.42), -3.5);
 }  

Check if the Range contains a certain value


Rust 1.35.0 purchased a couple of new methods on Range * structures:



With these methods, you can easily check if a particular value is in a range. For example, you can write:


  fn main () {
  if (0 .. = 10) .contains (& amp; 5) {
  println! ("5 is in the range [0; 10].");
  }
 }  

Translate (map) and split (split) borrowed RefCell


With the advent of Rust 1.35.0, you can translate and break the borrowed value of RefCell into a set of borrowed values ​​into different components of borrowed data:



Rearrange the value of RefCell via the built-in function


This release represents a convenient replace_with method declared on the RefCell structure:



Hash the pointer or link at


This release introduces the ptr :: hash function A raw pointer for hashing. Using ptr :: hash can prevent hashing of the specified or referenced value instead of the address itself.


Copy content Option & lt; & amp; T & gt;


From the beginning of Rust 1.0.0, the Option :: cloned methods to Option & lt; & amp; T & gt; and Option & lt; & amp; mut T & gt; allowed to clone content if present ( Some (_) ). However, cloning can sometimes be an expensive operation, and opt.cloned () methods do not describe any prompts.


This release contributed:



The opt.copied () functionality is the same as opt.cloned () . However, the method described above requests the conditions T: Copy , the failure of which will cause a compilation error.


Clippy changes


Clippy, a tool that catches frequently encountered imperfections to improve the quality of the code, has acquired drop_bounds . It works in cases where the generic function requests the fulfillment of the condition T: Drop :


  fn foo & lt; T: Drop & gt; (x: T) {}  

This is often an error, as primitives do not implement Drop . Moreover, T: Drop does not cover types like String that do not have any visible destructor behavior, but rather the result of embedded types (like Vec & lt; u8 & gt; ).


In addition to drop_bounds , this the release of part redundant_closure in redundant_closure and redundant_closure_for_method_calls .


You can read the detailed release of Clippy here .


Changes in Cargo


A detailed description of the changes to Cargo is available Members 1.35.0

Many people came together to create Rust 1.35.0. We could not have done this without all of you, thanks !


From the translator


With any questions about the Rust language, they can help you in the Russian-language Telegram Chat , or in a similar chat for newbie questions .

Source text: Rust 1.35.0 release