The Rust development team is pleased to announce the release of a new version of Rust, 1.31.0, as well as "Rust 2018". Rust is a programming language that allows everyone to create reliable and efficient software.
If you have a previous version of Rust installed using rustup
, then to update Rust to version 1.31.0, you just need to run:
$ rustup update stable
If you have not yet installed rustup
, you can install it from the corresponding page of our website. Detailed notes for the release of Rust 1.31.0 can be found on GitHub.
Rust 1.31, perhaps the most significant release since Rust 1.0! This release includes the first iteration of the “Rust 2018”, but this is not the only innovation! The review of improvements will be long, so here's the table of contents:
const fn
We wrote about Rust 2018 for the first time in March , and then in July . For details why you need Rust 2018, refer to these publications. In this review, we have so much to tell, so we will focus only on what Rust 2018 is. You can also read about this in a post on Mozilla Hacks ( translation ).
In short, Rust 2018 is an opportunity to combine into a coherent whole all the work we have done in the past three years. Rust 2018 is more than just a set of language enhancements. In addition to them, it includes:
rustfmt
, Clippy)Further we will tell about all this in more detail and about other innovations.
Let's create a new project with Cargo:
$ cargo new foo
Here are the contents of Cargo.toml
:
[package] name = "foo" version = "0.1.0" authors = ["Your Name <you@example.com>"] edition = "2018" [dependencies]
A new key has been added to the [package]
section: edition
. Please note that it is set to 2018
. You can also install it in 2015
- this value will be set by default if the key is missing.
With the use of Rust 2018, some new features will be unlocked that are not allowed in Rust 2015.
It is important to note that each package can be in 2015 or 2018 mode, and they will work together. Your draft 2018 revision can use dependencies of 2015 revision, and the draft 2015 revision can use dependencies 2018 revision. This ensures the integrity of the ecosystem and that all new features will be optional, while maintaining compatibility with existing code. In addition, when you decide to transfer the Rust 2015 code to Rust 2018, changes can be made automatically via cargo fix
.
You may ask: what about the new features themselves? Firstly, they are also added to Rust 2015, if they are compatible with the features of this edition. Thus, most of the language remains the same everywhere. You can view the revision guide to find out the minimum rustc
version for each new feature and its other requirements. However, there are several big innovations that need to be mentioned separately: non-lexical lifetimes and some changes in the module system.
If you have been following the development of Rust over the past few years, then you may occasionally come across the term "NLL" or "non-lexical lifetimes". This is slang, which, to put it in simple terms, means: the borrowing analyzer has become smarter and now accepts some correct code that it had previously rejected. Consider an example:
fn main() { let mut x = 5; let y = &x; let z = &mut x; }
Previously, Rust produced a compilation error:
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable --> src/main.rs:5:18 | 4 | let y = &x; | - immutable borrow occurs here 5 | 6 | let z = &mut x; | ^ mutable borrow occurs here 7 | } | - immutable borrow ends here
This is because the area of link life was defined "lexically"; that is, borrowing y
was considered active until y
went out of scope at the end of main
, even if we never use y
inside the region again. The code above is fine, but the dependency analyzer could not understand it.
Now this code is remarkably compiled.
But what if we used y
? For example:
fn main() { let mut x = 5; let y = &x; let z = &mut x; println!("y: {}", y); }
Rust used to give you this error:
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable --> src/main.rs:5:18 | 4 | let y = &x; | - immutable borrow occurs here 5 | let z = &mut x; | ^ mutable borrow occurs here ... 8 | } | - immutable borrow ends here
In Rust 2018, this error message has improved:
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable --> src/main.rs:5:13 | 4 | let y = &x; | -- immutable borrow occurs here 5 | let z = &mut x; | ^^^^^^ mutable borrow occurs here 6 | 7 | println!("y: {}", y); | - borrow later used here
Instead of indicating where y
goes out of scope, it shows where conflict borrowing occurs. This makes debugging such errors much easier.
In Rust 1.31, this improvement is exclusively for Rust 2018. We plan to add it to Rust 2015 later.
The module system can be a problem for people who study Rust for the first time. Of course, there is always something that takes time to master. But the main reason why the modules so embarrass many - despite the simple and consistent rules that determine the system of modules, the consequences of their application may seem contradictory, mysterious and unnatural.
Therefore, revision 2018 makes some changes in how the paths work, simplifying the system of modules and making it clearer.
Here is a brief summary:
extern crate
no longer required almost anywhere.use
instead of using the #[macro_use]
attribute.crate
keyword refers to the current container.foo.rs
and the subdirectory foo/
can coexist; mod.rs
no longer required when placing submodules in a subdirectory.It looks like an arbitrary set of rules, but on the whole the mental model is now much simpler.
There are many more details, please refer to the editors' manual for all the details.
Let's talk about the improvements available in both editions: we added some additional inference rules for impl
blocks and function definitions. Code like this:
impl<'a> Reader for BufReader<'a> { // }
can now be written like this:
impl Reader for BufReader<'_> { // }
Lifetime '_
still shows that BufReader
takes it as a parameter, but we no longer need to set a name for it.
Lifetimes are still required to be determined in structures. However, we no longer need to write as much template code as before:
// Rust 2015 struct Ref<'a, T: 'a> { field: &'a T } // Rust 2018 struct Ref<'a, T> { field: &'a T }
Dependency : 'a
will be displayed. You can still specify it explicitly if you want. We are considering other possibilities for the conclusion in such places for the future, but so far we have no concrete plans.
const fn
There are several ways to declare a function in Rust: fn
for normal functions, unsafe fn
for unsafe functions, and extern fn
for external functions. This release adds a new way to declare a function: const fn
. It is used like this:
const fn foo(x: i32) -> i32 { x + 1 }
A constant function can be called as a normal function, but beyond that it can be used in any constant context. At the same time, it will be executed at compile time, not at run time. For example:
const SIX: i32 = foo(5);
The foo
function will execute at compile time and SIX
will take the value 6
.
Constant functions cannot do everything that normal functions can do: they must have a deterministic result. This is important for reasons of reliability. In the current form, constant functions can perform a minimal subset of operations. Here are some examples of what you can do in them:
&&
and ||
&
*
linksWe will extend the capabilities of constant functions, but the above set is already enough to use const fn
in practice.
See the handbook for details.
Revision 2018 marks the beginning of a new level of maturity of the Rust. Cargo, Rustdoc and Rustup have been major tools since version 1.0; With edition 2018 comes a new generation of tools that everyone can now use: Clippy, Rustfmt and IDE support.
The clippy
static code analyzer is now available in stable Rust. You can install it through the rustup component add clippy
and run it with the cargo clippy
. Clippy has now received version 1.0 and has the same stability guarantees for static checks as rustc. New checks can be added, or the functionality of old ones can be extended, but old ones cannot be deleted (can only be marked as obsolete). This means that the code that compiles with clippy will continue to compile with clippy (provided that no checks are set to generate
error through deny
), but may issue new warnings.
Rustfmt is a tool for formatting code in Rust. Automatic code formatting will save you time, and it will also bring your code closer to the official Rust style . You can install it through the rustup component add rustfmt
and use the cargo fmt
command.
Current release includes Rustfmt 1.0. From now on, we guarantee backward compatibility for Rustfmt: if you format your code today, the formatting will not change in the future (only for default parameters). Backward compatibility means that it is now practical to run Rustfmt on your CI (use cargo fmt --check
). Try this along with "formatting while saving" in the editor, and your workflow is revolutionized.
IDE support is one of the most requested features of tools for Rust. Now there are several high quality solutions:
The support work in the IDE is not finished. In particular, code completion in RLS based editors is not up to par. However, if you basically want support for types, documentation, and the “transition to definition,” then you will be satisfied.
In Rust 1.30, we stabilized "instrumental attributes", such as #[rustfmt::skip]
. In Rust 1.31, we stabilized something like this: "tool code quality checks" ("tool lints"), such as #[allow(clippy::bool_comparison)]
. This allows you to set namespaces for checks to make it clearer what tools they come from.
If you previously used Clippy checks, you can migrate as follows:
// #![cfg_attr(feature = "cargo-clippy", allow(bool_comparison))] // #![allow(clippy::bool_comparison)]
You no longer need cfg_attr
! You will also now receive alerts that will help you switch to using the new style.
Rustdoc had several improvements this year, and a completely rewritten book, The Rust Programming Language, was released. You can buy a paper copy from No Starch Press !
Previously, it was called the "second edition" of the book, but since it became the first print edition, it caused confusion. After all, the print edition is scheduled to be updated periodically. In the end, after many discussions with No Starch, it was decided to update the book on the website along with each issue, and No Starch would periodically pick up the changes and print them. The book sells pretty well and collects money for the Black Girls Code .
You can find a new version of the book here .
This year we announced the creation of four working groups:
Groups worked very hard to make Rust better in each of these areas. Here are some achievements:
You can learn more about all this on our new website!
Last week we announced a new version of our website. Now it has become the official version of rust-lang.org!
To create it took a year of work of many people. And although there is still much to be done to complete it, we are proud of the work done.
Were added new implementations From
:
u8
now implements From<NonZeroU8>
, similarly for other numeric types and their NonZero
equivalentsOption<&T>
implements From<&Option<T>>
, similarly for &mut
The following functions have also been stabilized:
slice::align_to
and its mutable analogslice::chunks_exact
, as well as its mutable and r
counterparts (such as slice::rchunks_exact_mut
) in all combinationsSee the release notes for details.
Cargo will now load packages in parallel using HTTP / 2.
In addition, since extern crate
is no longer necessary, it would be unpleasant to write extern crate foo as bar;
to rename dependencies. Therefore, you can do this in Cargo.toml
as follows:
[dependencies] baz = { version = "0.1", package = "foo" }
or equivalently:
[dependencies.baz] version = "0.1" package = "foo"
Now the foo
package is available as baz
for use in your code.
See the release notes for details.
Usually at the end of the review, we thank the people who contributed to the preparation of the release . But this time, unlike past ones, this list does not fully cover all those people who helped, and all the amount of work that was done. Each regular release is the result of six weeks of work, but this release is the culmination of three years of effort, reflected in a myriad of repositories made by a huge number of people. We were pleased to work with all of you, and we look forward to the continued development of Rust over the next three years.
From the translator: I express special thanks to the members of the Rustycrate community and personally @dashadee , ozkriff , humbug and mvlabat for their help with translation and proofreading.
Source: https://habr.com/ru/post/432640/
All Articles