|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Announcing Rust 1.50.0" |
| 4 | +author: The Rust Release Team |
| 5 | +release: true |
| 6 | +--- |
| 7 | + |
| 8 | +The Rust team is happy to announce a new version of Rust, 1.50.0. Rust is a |
| 9 | +programming language that is empowering everyone to build reliable and |
| 10 | +efficient software. |
| 11 | + |
| 12 | +If you have a previous version of Rust installed via rustup, getting Rust |
| 13 | +1.50.0 is as easy as: |
| 14 | + |
| 15 | +```console |
| 16 | +rustup update stable |
| 17 | +``` |
| 18 | + |
| 19 | +If you don't have it already, you can [get `rustup`][install] |
| 20 | +from the appropriate page on our website, and check out the |
| 21 | +[detailed release notes for 1.50.0][notes] on GitHub. |
| 22 | + |
| 23 | +[install]: https://www.rust-lang.org/install.html |
| 24 | +[notes]: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1500-2021-02-11 |
| 25 | + |
| 26 | +## What's in 1.50.0 stable |
| 27 | + |
| 28 | +For this release, we have improved array indexing, expanded safe access to union fields, and added to the standard library. |
| 29 | +See the [detailed release notes][notes] to learn about other changes |
| 30 | +not covered by this post. |
| 31 | + |
| 32 | +### Const-generic array indexing |
| 33 | + |
| 34 | +Continuing the march toward stable `const` generics, this release adds |
| 35 | +implementations of `ops::Index` and `IndexMut` for arrays `[T; N]` for |
| 36 | +_any_ length of `const N`. The indexing operator `[]` already worked on |
| 37 | +arrays through built-in compiler magic, but at the type level, arrays |
| 38 | +didn't actually implement the library traits until now. |
| 39 | + |
| 40 | +```rust |
| 41 | +fn second<C>(container: &C) -> &C::Output |
| 42 | +where |
| 43 | + C: std::ops::Index<usize> + ?Sized, |
| 44 | +{ |
| 45 | + &container[1] |
| 46 | +} |
| 47 | + |
| 48 | +fn main() { |
| 49 | + let array: [i32; 3] = [1, 2, 3]; |
| 50 | + assert_eq!(second(&array[..]), &2); // slices worked before |
| 51 | + assert_eq!(second(&array), &2); // now it also works directly |
| 52 | +} |
| 53 | +``` |
| 54 | + |
| 55 | +### `const` value repetition for arrays |
| 56 | + |
| 57 | +Arrays in Rust can be written either as a list `[a, b, c]` or a repetition `[x; N]`. |
| 58 | +For lengths `N` greater than one, repetition has only been allowed for `x`s that are `Copy`, |
| 59 | +and [RFC 2203] sought to allow any `const` expression there. However, |
| 60 | +while that feature was unstable for arbitrary expressions, its implementation |
| 61 | +since Rust 1.38 accidentally allowed stable use of `const` _values_ in array |
| 62 | +repetition. |
| 63 | + |
| 64 | +```rust |
| 65 | +fn main() { |
| 66 | + // This is not allowed, because `Option<Vec<i32>>` does not implement `Copy`. |
| 67 | + let array: [Option<Vec<i32>>; 10] = [None; 10]; |
| 68 | + |
| 69 | + const NONE: Option<Vec<i32>> = None; |
| 70 | + const EMPTY: Option<Vec<i32>> = Some(Vec::new()); |
| 71 | + |
| 72 | + // However, repeating a `const` value is allowed! |
| 73 | + let nones = [NONE; 10]; |
| 74 | + let empties = [EMPTY; 10]; |
| 75 | +} |
| 76 | +``` |
| 77 | + |
| 78 | +In Rust 1.50, that stabilization is formally acknowledged. In the future, to avoid such "temporary" named |
| 79 | +constants, you can look forward to inline `const` expressions per [RFC 2920]. |
| 80 | + |
| 81 | +[RFC 2203]: https://rust-lang.github.io/rfcs/2203-const-repeat-expr.html |
| 82 | +[RFC 2920]: https://rust-lang.github.io/rfcs/2920-inline-const.html |
| 83 | + |
| 84 | +### Safe assignments to `ManuallyDrop<T>` union fields |
| 85 | + |
| 86 | +Rust 1.49 made it possible to add `ManuallyDrop<T>` fields to a `union` as part |
| 87 | +of allowing `Drop` for unions at all. However, unions don't drop old values |
| 88 | +when a field is assigned, since they don't know which variant was formerly |
| 89 | +valid, so safe Rust previously limited this to `Copy` types only, which never `Drop`. |
| 90 | +Of course, `ManuallyDrop<T>` also doesn't need to `Drop`, so now Rust 1.50 |
| 91 | +allows safe assignments to these fields as well. |
| 92 | + |
| 93 | +### A niche for `File` on Unix platforms |
| 94 | + |
| 95 | +Some types in Rust have specific limitations on what is considered a |
| 96 | +valid value, which may not cover the entire range of possible memory |
| 97 | +values. We call any remaining invalid value a [niche], and this space |
| 98 | +may be used for type layout optimizations. For example, in Rust 1.28 |
| 99 | +we introduced `NonZero` integer types (like `NonZeroU8`) where `0` is a niche, and this allowed |
| 100 | +`Option<NonZero>` to use `0` to represent `None` with no extra memory. |
| 101 | + |
| 102 | +On Unix platforms, Rust's `File` is simply made of the system's integer |
| 103 | +file descriptor, and this happens to have a possible niche |
| 104 | +as well because it can never be `-1`! System calls which return a file |
| 105 | +descriptor use `-1` to indicate that an error occurred (check `errno`) |
| 106 | +so it's never possible for `-1` to be a real file descriptor. Starting |
| 107 | +in Rust 1.50 this niche is added to the type's definition so it can be |
| 108 | +used in layout optimizations too. It follows that `Option<File>` will |
| 109 | +now have the same size as `File` itself! |
| 110 | + |
| 111 | +[niche]: https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#niche |
| 112 | + |
| 113 | +### Library changes |
| 114 | + |
| 115 | +In Rust 1.50.0, there are nine new stable functions: |
| 116 | + |
| 117 | +- [`bool::then`] |
| 118 | +- [`btree_map::Entry::or_insert_with_key`] |
| 119 | +- [`f32::clamp`] |
| 120 | +- [`f64::clamp`] |
| 121 | +- [`hash_map::Entry::or_insert_with_key`] |
| 122 | +- [`Ord::clamp`] |
| 123 | +- [`RefCell::take`] |
| 124 | +- [`slice::fill`] |
| 125 | +- [`UnsafeCell::get_mut`] |
| 126 | + |
| 127 | +And quite a few existing functions were made `const`: |
| 128 | + |
| 129 | +- [`IpAddr::is_ipv4`] |
| 130 | +- [`IpAddr::is_ipv6`] |
| 131 | +- [`Layout::size`] |
| 132 | +- [`Layout::align`] |
| 133 | +- [`Layout::from_size_align`] |
| 134 | +- `pow` for all integer types. |
| 135 | +- `checked_pow` for all integer types. |
| 136 | +- `saturating_pow` for all integer types. |
| 137 | +- `wrapping_pow` for all integer types. |
| 138 | +- `next_power_of_two` for all unsigned integer types. |
| 139 | +- `checked_power_of_two` for all unsigned integer types. |
| 140 | + |
| 141 | +See the [detailed release notes][notes] to learn about other changes. |
| 142 | + |
| 143 | +[`IpAddr::is_ipv4`]: https://doc.rust-lang.org/stable/std/net/enum.IpAddr.html#method.is_ipv4 |
| 144 | +[`IpAddr::is_ipv6`]: https://doc.rust-lang.org/stable/std/net/enum.IpAddr.html#method.is_ipv6 |
| 145 | +[`Layout::align`]: https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.align |
| 146 | +[`Layout::from_size_align`]: https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.from_size_align |
| 147 | +[`Layout::size`]: https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.size |
| 148 | +[`Ord::clamp`]: https://doc.rust-lang.org/stable/std/cmp/trait.Ord.html#method.clamp |
| 149 | +[`RefCell::take`]: https://doc.rust-lang.org/stable/std/cell/struct.RefCell.html#method.take |
| 150 | +[`UnsafeCell::get_mut`]: https://doc.rust-lang.org/stable/std/cell/struct.UnsafeCell.html#method.get_mut |
| 151 | +[`bool::then`]: https://doc.rust-lang.org/stable/std/primitive.bool.html#method.then |
| 152 | +[`btree_map::Entry::or_insert_with_key`]: https://doc.rust-lang.org/stable/std/collections/btree_map/enum.Entry.html#method.or_insert_with_key |
| 153 | +[`f32::clamp`]: https://doc.rust-lang.org/stable/std/primitive.f32.html#method.clamp |
| 154 | +[`f64::clamp`]: https://doc.rust-lang.org/stable/std/primitive.f64.html#method.clamp |
| 155 | +[`hash_map::Entry::or_insert_with_key`]: https://doc.rust-lang.org/stable/std/collections/hash_map/enum.Entry.html#method.or_insert_with_key |
| 156 | +[`slice::fill`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.fill |
| 157 | + |
| 158 | +### Other changes |
| 159 | + |
| 160 | +[relnotes-cargo]: https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-150-2021-02-11 |
| 161 | +[relnotes-clippy]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-150 |
| 162 | + |
| 163 | +There are other changes in the Rust 1.50.0 release: check out what changed in |
| 164 | +[Rust][notes], [Cargo][relnotes-cargo], and [Clippy][relnotes-clippy]. |
| 165 | + |
| 166 | +## Contributors to 1.50.0 |
| 167 | + |
| 168 | +Many people came together to create Rust 1.50.0. We couldn't have done it |
| 169 | +without all of you. [Thanks!](https://thanks.rust-lang.org/rust/1.50.0/) |
0 commit comments