⬆️ ⬇️

Release Rust 1.16

The Rust team is pleased to present the release of Rust 1.16.0. Rust is a system programming language aimed at security, speed, and parallel code execution.



If you have a previous version of Rust installed, then it’s enough to upgrade:



$ rustup update stable 


If you have not yet installed Rust, then you can rustup from the corresponding page of our website and read the detailed release notes for 1.16.0 on GitHub.



What is included in the stable version 1.16.0



The biggest addition to Rust 1.16 is the cargo check team. This new subcommand in most cases should speed up the development process.



What she does? Let's go back a bit and talk about how rustc compiles your code. Compilation takes place in several "passes". This means that the compiler performs many different steps before a binary file is created from your source code. You can see each of these stages (and how much time and memory they take) by passing the -Z time-passes parameter to the compiler (only for nightly):





 rustc .\hello.rs -Z time-passes time: 0.003; rss: 16MB parsing time: 0.000; rss: 16MB recursion limit time: 0.000; rss: 16MB crate injection time: 0.000; rss: 16MB plugin loading time: 0.000; rss: 16MB plugin registration time: 0.049; rss: 34MB expansion <snip> 


A lot of them. However, you can divide them into two big steps. First, rustc performs all security checks and syntax correctness. Second: after making sure that everything is in order, it will create a binary file, which you will eventually run.



As you can see, the second stage takes a lot of time. And in most cases it is not necessary. Many developers work on Rust projects like this:



  1. Write some code.
  2. Run cargo build to make sure it compiles.
  3. Repeat the first two steps as necessary.
  4. Run the cargo test to make sure that the tests run successfully.
  5. Go to the first step.


In the second step, you never run your code. You are only interested in messages from the compiler. cargo check solves this particular problem: it runs all compiler checks, but does not create a binary file.



So what kind of acceleration do you actually get? As with most performance issues, the answer is "when, how." Here are some very unscientific tests:



initial assemblyinitial checkaccelerationreassemblyretestacceleration
thanks134.75s50.88s2.64815.97s2.9s5.506
cargo236.78s148.52s1.59464.34s9.29s6.925
diesel15.27s12.81s0.01513.54s12.3s1.100


The 'initial' category is the first build after a project was cloned. For the category 'repeated', one empty line was added to the beginning of the src\lib.rs , after which the command was executed again. That is why the initial build looks more sad; besides the project itself, the command is executed for all its dependencies. As you can see, a large project with a lot of dependencies will see noticeable improvements, but for small ones there is almost no difference.



We are also still working on improving the compilation time as a whole, although now we cannot boast of anything concrete.



Other improvements



To support cargo check , rustc learned to generate a new kind of file: .rmeta . This file contains only metadata about a particular container. cargo check uses this for your dependencies so that the compiler can check types and the like. This is also useful for the Rust Language Server and possibly other tools that will appear later.



Another important change is the removal of a long-time diagnostic: consider using an explicit lifetime parameter . This diagnostic worked every time you had an incorrect annotation of the lifetime, and the compiler thinks you meant something else. Consider the following code:



 use std::str::FromStr; pub struct Name<'a> { name: &'a str, } impl<'a> FromStr for Name<'a> { type Err = (); fn from_str(s: &str) -> Result<Name, ()> { Ok(Name { name: s }) } } 


Here Rust is not sure what to do with the lifetime; This code does not guarantee that s will live as long as Name . In this case, s necessary for the Name be valid. Let's try to compile this code in Rust 1.15.1:



 > rustc +1.15.1 foo.rs --crate-type=lib error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in generic type due to conflicting requirements --> .\foo.rs:10:5 | 10 | fn from_str(s: &str) -> Result<Name, ()> { | _____^ starting here... 11 | | Ok(Name { name: s }) 12 | | } | |_____^ ...ending here | help: consider using an explicit lifetime parameter as shown: fn from_str(s: &'a str) -> Result<Name, ()> --> .\foo.rs:10:5 | 10 | fn from_str(s: &str) -> Result<Name, ()> { | _____^ starting here... 11 | | Ok(Name { name: s }) 12 | | } | |_____^ ...ending here 


The compiler explains the problem and gives useful advice. Well, let's try to use it. Modify the code by adding 'a , and try compiling again.



 > rustc +1.15.1 .\foo.rs --crate-type=lib error[E0308]: method not compatible with trait --> .\foo.rs:10:5 | 10 | fn from_str(s: &'a str) -> Result<Name, ()> { | _____^ starting here... 11 | | Ok(Name { name: s }) 12 | | } | |_____^ ...ending here: lifetime mismatch | <snip> help: consider using an explicit lifetime parameter as shown: fn from_str(s: &'a str) -> Result<Name<'a>, ()> --> .\foo.rs:10:5 | 10 | fn from_str(s: &'a str) -> Result<Name, ()> { | _____^ starting here... 11 | | Ok(Name { name: s }) 12 | | } | |_____^ ...ending here 


It still does not work. The advice was not that helpful. Now he suggests adding another lifetime, this time for Name . If we do this ...



 > rustc +1.15.1 .\foo.rs --crate-type=lib <snip> help: consider using an explicit lifetime parameter as shown: fn from_str(s: &'a str) -> Result<Name<'a>, ()> --> .\foo.rs:10:5 


... I've already watched this movie ... Compiler ?!



This diagnosis had good intentions, but, as can be seen from this example, when she was wrong, she was wrong very much . Sometimes she even suggested incorrect syntax for Rust! Moreover, the more experienced programmers at Rust do not really need this hint, but beginners took them on faith, and went into the wilds. Because of this, we decided to completely remove this message . Perhaps we will return it in the future, but only if we can limit the false positives.



Of the other diagnostic changes, the previous version of Rust tried to suggest corrections for typos:



 let foo = 5; println!("{}", ffo); 


The code above caused the following error:



 error[E0425]: cannot find value `ffo` in this scope --> foo.rs:4:20 | 4 | println!("{}", ffo); | ^^^ did you mean `foo`? 


However, this could happen only in certain circumstances: sometimes for local variables and for structure fields. Now it works almost everywhere . In combination with some other relevant improvements, this leads to a significant improvement in these types of diagnostics.



See the release notes for details.



Library stabilization



21 new interfaces have been stabilized:





In addition, a number of minor improvements were made to existing functions. For example, writeln! , just like println! , can now take one argument . As a result, he writes only a newline character, but this is a beautiful symmetry.



Now all structures in the standard library Debug .



Improved error message when getting a &str slice. For example, for this code:



 &"abcαβγ"[..4] 


The following error will be displayed:



 thread 'str::test_slice_fail_boundary_1' panicked at 'byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5) of `abcαβγ`' 


Parts after ; was not there before.



See the release notes for details.



Cargo features



In addition to cargo check , Cargo and crates.io have several new features. For example, cargo build and cargo doc now accept the - all flag to build and document all containers in your workspace.



Cargo now has a --version --verbose flag, similar to rustc .



Crates.io can now display TravisCI or AppVeyor icons for your container.



Both Cargo and crates.io now understand the categories . Unlike keywords that can be specified in free form, categories are supervised. Keywords, unlike categories, are used for search. In other words, categories are meant to help you browse the catalog, and keywords are meant to be searched.



You can browse containers by category here .



See the release notes for details.



Developers version 1.16.0



In the last issue, we introduced thanks.rust-lang.org . We do some refactoring to add other projects besides Rust itself. We hope to introduce this in the next issue.



137 people contributed to Rust 1.16. Thank!



Translated by Sergey Veselkov



')

Source: https://habr.com/ru/post/324448/



All Articles