The Rust team is happy to announce a new version of Rust, 1.50.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.50.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.50.0 on GitHub.
What's in 1.50.0 stable
For this release, we have improved array indexing, expanded safe access to union fields, and added to the standard library. See the detailed release notes to learn about other changes not covered by this post.
Const-generic array indexing
Continuing the march toward stable const generics, this release adds
implementations of ops::Index and IndexMut for arrays [T; N] for
any length of const N. The indexing operator [] already worked on
arrays through built-in compiler magic, but at the type level, arrays
didn't actually implement the library traits until now.
fn second<C>(container: &C) -> &C::Output
where
C: std::ops::Index<usize> + ?Sized,
{
&container[1]
}
fn main() {
let array: [i32; 3] = [1, 2, 3];
assert_eq!(second(&array[..]), &2); // slices worked before
assert_eq!(second(&array), &2); // now it also works directly
}
const value repetition for arrays
Arrays in Rust can be written either as a list [a, b, c] or a repetition [x; N].
For lengths N greater than one, repetition has only been allowed for xs that are Copy,
and RFC 2203 sought to allow any const expression there. However,
while that feature was unstable for arbitrary expressions, its implementation
since Rust 1.38 accidentally allowed stable use of const values in array
repetition.
fn main() {
// This is not allowed, because `Option<Vec<i32>>` does not implement `Copy`.
let array: [Option<Vec<i32>>; 10] = [None; 10];
const NONE: Option<Vec<i32>> = None;
const EMPTY: Option<Vec<i32>> = Some(Vec::new());
// However, repeating a `const` value is allowed!
let nones = [NONE; 10];
let empties = [EMPTY; 10];
}
In Rust 1.50, that stabilization is formally acknowledged. In the future, to avoid such "temporary" named
constants, you can look forward to inline const expressions per RFC 2920.
Safe assignments to ManuallyDrop<T> union fields
Rust 1.49 made it possible to add ManuallyDrop<T> fields to a union as part
of allowing Drop for unions at all. However, unions don't drop old values
when a field is assigned, since they don't know which variant was formerly
valid, so safe Rust previously limited this to Copy types only, which never Drop.
Of course, ManuallyDrop<T> also doesn't need to Drop, so now Rust 1.50
allows safe assignments to these fields as well.
A niche for File on Unix platforms
Some types in Rust have specific limitations on what is considered a
valid value, which may not cover the entire range of possible memory
values. We call any remaining invalid value a niche, and this space
may be used for type layout optimizations. For example, in Rust 1.28
we introduced NonZero integer types (like NonZeroU8) where 0 is a niche, and this allowed
Option<NonZero> to use 0 to represent None with no extra memory.
On Unix platforms, Rust's File is simply made of the system's integer
file descriptor, and this happens to have a possible niche
as well because it can never be -1! System calls which return a file
descriptor use -1 to indicate that an error occurred (check errno)
so it's never possible for -1 to be a real file descriptor. Starting
in Rust 1.50 this niche is added to the type's definition so it can be
used in layout optimizations too. It follows that Option<File> will
now have the same size as File itself!
Library changes
In Rust 1.50.0, there are nine new stable functions:
bool::thenbtree_map::Entry::or_insert_with_keyf32::clampf64::clamphash_map::Entry::or_insert_with_keyOrd::clampRefCell::takeslice::fillUnsafeCell::get_mut
And quite a few existing functions were made const:
IpAddr::is_ipv4IpAddr::is_ipv6Layout::sizeLayout::alignLayout::from_size_alignpowfor all integer types.checked_powfor all integer types.saturating_powfor all integer types.wrapping_powfor all integer types.next_power_of_twofor all unsigned integer types.checked_power_of_twofor all unsigned integer types.
See the detailed release notes to learn about other changes.
Other changes
There are other changes in the Rust 1.50.0 release: check out what changed in Rust, Cargo, and Clippy.
Contributors to 1.50.0
Many people came together to create Rust 1.50.0. We couldn't have done it without all of you. Thanks!