The Rust team is happy to announce a new version of Rust, 1.36.0. Rust is a programming language that is empowering everyone to build reliable and efficient software.
If you have a previous version of Rust installed via rustup, getting Rust 1.36.0 is as easy as:
rustup update stable
If you don't have it already, you can get rustup
from the appropriate page on our website,
and check out the detailed release notes for 1.36.0 on GitHub.
What's in 1.36.0 stable
This release brings many changes, including the stabilization of the Future
trait,
the alloc
crate, the MaybeUninit<T>
type, NLL for Rust 2015,
a new HashMap<K, V>
implementation, and --offline
support in Cargo.
Read on for a few highlights, or see the detailed release notes for additional information.
Future
is here!
The In Rust 1.36.0 the long awaited Future
trait has been stabilized!
With this stabilization, we hope to give important crates, libraries,
and the ecosystem time to prepare for async
/ .await
,
which we'll tell you more about in the future.
alloc
crate is stable
The Before 1.36.0, the standard library consisted of the crates std
, core
, and proc_macro
.
The core
crate provided core functionality such as Iterator
and Copy
and could be used in #![no_std]
environments since it did not impose any requirements.
Meanwhile, the std
crate provided types like Box<T>
and OS functionality
but required a global allocator and other OS capabilities in return.
Starting with Rust 1.36.0, the parts of std
that depend on a global allocator, e.g. Vec<T>
,
are now available in the alloc
crate. The std
crate then re-exports these parts.
While #![no_std]
binaries using alloc
still require nightly Rust,
#![no_std]
library crates can use the alloc
crate in stable Rust.
Meanwhile, normal binaries, without #![no_std]
, can depend on such library crates.
We hope this will facilitate the development of a #![no_std]
compatible ecosystem of libraries
prior to stabilizing support for #![no_std]
binaries using alloc
.
If you are the maintainer of a library that only relies on some allocation primitives to function,
consider making your library #[no_std]
compatible by using the following at the top of your lib.rs
file:
#![no_std]
extern crate alloc;
use alloc::vec::Vec;
MaybeUninit<T>
instead of mem::uninitialized
In previous releases of Rust, the mem::uninitialized
function has allowed you to bypass Rust's
initialization checks by pretending that you've initialized a value at type T
without doing anything.
One of the main uses of this function has been to lazily allocate arrays.
However, mem::uninitialized
is an incredibly dangerous operation that essentially
cannot be used correctly as the Rust compiler assumes that values are properly initialized.
For example, calling mem::uninitialized::<bool>()
causes instantaneous undefined behavior
as, from Rust's point of view, the uninitialized bits are neither 0
(for false
)
nor 1
(for true
) - the only two allowed bit patterns for bool
.
To remedy this situation, in Rust 1.36.0, the type MaybeUninit<T>
has been stabilized.
The Rust compiler will understand that it should not assume that a MaybeUninit<T>
is a properly initialized T
.
Therefore, you can do gradual initialization more safely and eventually use .assume_init()
once you are certain that maybe_t: MaybeUninit<T>
contains an initialized T
.
As MaybeUninit<T>
is the safer alternative, starting with Rust 1.39,
the function mem::uninitialized
will be deprecated.
To find out more about uninitialized memory, mem::uninitialized
,
and MaybeUninit<T>
, read Alexis Beingessner's blog post.
The standard library also contains extensive documentation about MaybeUninit<T>
.
NLL for Rust 2015
In the announcement for Rust 1.31.0, we told you about NLL (Non-Lexical Lifetimes), an improvement to the language that makes the borrow checker smarter and more user friendly. For example, you may now write:
fn main() {
let mut x = 5;
let y = &x;
let z = &mut x; // This was not allowed before 1.31.0.
}
In 1.31.0 NLL was stabilized only for Rust 2018, with a promise that we would backport it to Rust 2015 as well. With Rust 1.36.0, we are happy to announce that we have done so! NLL is now available for Rust 2015.
With NLL on both editions, we are closer to removing the old borrow checker. However, the old borrow checker unfortunately accepted some unsound code it should not have. As a result, NLL is currently in a "migration mode" wherein we will emit warnings instead of errors if the NLL borrow checker rejects code the old AST borrow checker would accept. Please see this list of public crates that are affected.
To find out more about NLL, MIR, the story around fixing soundness holes, and what you can do about the warnings if you have them, read Felix Klock's blog post.
HashMap<K, V>
implementation
A new In Rust 1.36.0, the HashMap<K, V>
implementation has been replaced
with the one in the hashbrown
crate which is based on the SwissTable design.
While the interface is the same, the HashMap<K, V>
implementation is now
faster on average and has lower memory overhead.
Note that unlike the hashbrown
crate,
the implementation in std
still defaults to the SipHash 1-3 hashing algorithm.
--offline
support in Cargo
During most builds, Cargo doesn't interact with the network. Sometimes, however, Cargo has to. Such is the case when a dependency is added and the latest compatible version needs to be downloaded. At times, network access is not an option though, for example on an airplane or in isolated build environments.
In Rust 1.36, a new Cargo flag has been stabilized: --offline
.
The flag alters Cargo's dependency resolution algorithm to only use locally cached dependencies.
When the required crates are not available offline, and a network access would be required,
Cargo will exit with an error.
To prepopulate the local cache in preparation for going offline,
use the cargo fetch
command, which downloads all the required dependencies for a project.
To find out more about --offline
and cargo fetch
, read Nick Cameron's blog post.
For information on other changes to Cargo, see the detailed release notes.
Library changes
The dbg!
macro now supports multiple arguments.
Additionally, a number of APIs have been made const
:
New APIs have become stable, including:
task::Waker
andtask::Poll
VecDeque::rotate_left
andVecDeque::rotate_right
Read::read_vectored
andWrite::write_vectored
Iterator::copied
BorrowMut<str> for String
str::as_mut_ptr
Other library changes are available in the detailed release notes.
Other changes
Detailed 1.36.0 release notes are available for Rust, Cargo, and Clippy.
Contributors to 1.36.0
Many people came together to create Rust 1.36.0. We couldn't have done it without all of you. Thanks!