|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Announcing Rust 1.59.0" |
| 4 | +author: The Rust Team |
| 5 | +release: true |
| 6 | +--- |
| 7 | + |
| 8 | +The Rust team has published a new version of Rust, 1.59.0. Rust is a programming |
| 9 | +language that is empowering everyone to build reliable and efficient software. |
| 10 | + |
| 11 | +--- |
| 12 | + |
| 13 | +Today's release falls on the day in which the world is captured by the sudden |
| 14 | +invasion of Ukraine by Putin's forces. Before going into the details of the new |
| 15 | +Rust release, we'd like to state that we stand in solidarity with the people of |
| 16 | +Ukraine and express our support for all people affected by this conflict. |
| 17 | + |
| 18 | +---- |
| 19 | + |
| 20 | +If you have a previous version of Rust installed via rustup, you can get 1.59.0 |
| 21 | +with: |
| 22 | + |
| 23 | +```console |
| 24 | +rustup update stable |
| 25 | +``` |
| 26 | + |
| 27 | +If you don't have it already, you can [get `rustup`][install] |
| 28 | +from the appropriate page on our website, and check out the |
| 29 | +[detailed release notes for 1.59.0][notes] on GitHub. |
| 30 | + |
| 31 | +[install]: https://www.rust-lang.org/install.html |
| 32 | +[notes]: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1590-2022-02-24 |
| 33 | + |
| 34 | +## What's in 1.59.0 stable |
| 35 | + |
| 36 | +### Inline assembly |
| 37 | + |
| 38 | +The Rust language now supports inline assembly. This enables many applications |
| 39 | +that need very low-level control over their execution, or access to |
| 40 | +specialized machine instructions. |
| 41 | + |
| 42 | +When compiling for x86-64 targets, for instance, you can now write: |
| 43 | + |
| 44 | +```rust |
| 45 | +use std::arch::asm; |
| 46 | + |
| 47 | +// Multiply x by 6 using shifts and adds |
| 48 | +let mut x: u64 = 4; |
| 49 | +unsafe { |
| 50 | + asm!( |
| 51 | + "mov {tmp}, {x}", |
| 52 | + "shl {tmp}, 1", |
| 53 | + "shl {x}, 2", |
| 54 | + "add {x}, {tmp}", |
| 55 | + x = inout(reg) x, |
| 56 | + tmp = out(reg) _, |
| 57 | + ); |
| 58 | +} |
| 59 | +assert_eq!(x, 4 * 6); |
| 60 | +``` |
| 61 | + |
| 62 | +The format string syntax used to name registers in the `asm!` and `global_asm!` |
| 63 | +macros is the same used in Rust [format strings], so it should feel quite familiar |
| 64 | +to Rust programmers. |
| 65 | + |
| 66 | +The assembly language and instructions available with inline assembly vary |
| 67 | +according to the target architecture. Today, the stable Rust compiler supports |
| 68 | +inline assembly on the following architectures: |
| 69 | + |
| 70 | +* x86 and x86-64 |
| 71 | +* ARM |
| 72 | +* AArch64 |
| 73 | +* RISC-V |
| 74 | + |
| 75 | +You can see more examples of inline assembly in [Rust By Example][asm-example], |
| 76 | +and find more detailed documentation in the [reference][asm-reference]. |
| 77 | + |
| 78 | +[asm-example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html |
| 79 | +[asm-reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html |
| 80 | +[format strings]: https://doc.rust-lang.org/stable/std/fmt/ |
| 81 | + |
| 82 | +### Destructuring assignments |
| 83 | + |
| 84 | +You can now use tuple, slice, and struct patterns as the left-hand side of an |
| 85 | +assignment. |
| 86 | + |
| 87 | +```rust |
| 88 | +let (a, b, c, d, e); |
| 89 | + |
| 90 | +(a, b) = (1, 2); |
| 91 | +[c, .., d, _] = [1, 2, 3, 4, 5]; |
| 92 | +Struct { e, .. } = Struct { e: 5, f: 3 }; |
| 93 | + |
| 94 | +assert_eq!([1, 2, 1, 4, 5], [a, b, c, d, e]); |
| 95 | +``` |
| 96 | + |
| 97 | +This makes assignment more consistent with `let` bindings, which have long |
| 98 | +supported the same thing. Note that destructuring assignments with operators |
| 99 | +such as `+=` are not allowed. |
| 100 | + |
| 101 | +### Const generics defaults and interleaving |
| 102 | + |
| 103 | +Generic types can now specify default values for their const generics. For |
| 104 | +example, you can now write the following: |
| 105 | + |
| 106 | +```rust |
| 107 | +struct ArrayStorage<T, const N: usize = 2> { |
| 108 | + arr: [T; N], |
| 109 | +} |
| 110 | + |
| 111 | +impl<T> ArrayStorage<T> { |
| 112 | + fn new(a: T, b: T) -> ArrayStorage<T> { |
| 113 | + ArrayStorage { |
| 114 | + arr: [a, b], |
| 115 | + } |
| 116 | + } |
| 117 | +} |
| 118 | +``` |
| 119 | + |
| 120 | +Previously, type parameters were required to come before all const parameters. |
| 121 | +That restriction has been relaxed and you can now interleave them. |
| 122 | + |
| 123 | +```rust |
| 124 | +fn cartesian_product< |
| 125 | + T, const N: usize, |
| 126 | + U, const M: usize, |
| 127 | + V, F |
| 128 | +>(a: [T; N], b: [U; M]) -> [[V; N]; M] |
| 129 | +where |
| 130 | + F: FnMut(&T, &U) -> V |
| 131 | +{ |
| 132 | + // ... |
| 133 | +} |
| 134 | +``` |
| 135 | + |
| 136 | +### Future incompatibility warnings |
| 137 | + |
| 138 | +Sometimes bugs in the Rust compiler cause it to accept code that should not |
| 139 | +have been accepted. An example of this was [borrows of packed struct |
| 140 | +fields][packed_borrows] being allowed in safe code. |
| 141 | + |
| 142 | +[packed_borrows]: https://github.com/rust-lang/rust/issues/46043 |
| 143 | + |
| 144 | +While this happens very rarely, it can be quite disruptive when a crate used by |
| 145 | +your project has code that will no longer be allowed. In fact, you might not |
| 146 | +notice until your project inexplicably stops building! |
| 147 | + |
| 148 | +Cargo now shows you warnings when a dependency will be rejected by a future |
| 149 | +version of Rust. After running `cargo build` or `cargo check`, you might see: |
| 150 | + |
| 151 | +``` |
| 152 | +warning: the following packages contain code that will be rejected by a future version of Rust: old_dep v0.1.0 |
| 153 | +note: to see what the problems were, use the option `--future-incompat-report`, or run `cargo report future-incompatibilities --id 1` |
| 154 | +``` |
| 155 | + |
| 156 | +You can run the `cargo report` command mentioned in the warning to see a full |
| 157 | +report of the code that will be rejected. This gives you time to upgrade your |
| 158 | +dependency before it breaks your build. |
| 159 | + |
| 160 | +### Creating stripped binaries |
| 161 | + |
| 162 | +It's often useful to strip unnecessary information like debuginfo from binaries |
| 163 | +you distribute, making them smaller. |
| 164 | + |
| 165 | +While it has always been possible to do this manually after the binary is |
| 166 | +created, cargo and rustc now support stripping when the binary is linked. To |
| 167 | +enable this, add the following to your `Cargo.toml`: |
| 168 | + |
| 169 | +```toml |
| 170 | +[profile.release] |
| 171 | +strip = "debuginfo" |
| 172 | +``` |
| 173 | + |
| 174 | +This causes debuginfo to be stripped from release binaries. You can also supply |
| 175 | +`"symbols"` or just `true` to strip all symbol information where supported. |
| 176 | + |
| 177 | +The standard library typically ships with debug symbols and line-level |
| 178 | +debuginfo, so Rust binaries built without debug symbols enabled still include |
| 179 | +the debug information from the standard library by default. Using the `strip` |
| 180 | +option allows you to remove this extra information, producing smaller Rust |
| 181 | +binaries. |
| 182 | + |
| 183 | +See [Cargo's documentation][cargo-docs] for more details. |
| 184 | + |
| 185 | +[cargo-docs]: https://doc.rust-lang.org/beta/cargo/reference/profiles.html#strip |
| 186 | + |
| 187 | +### Incremental compilation off by default |
| 188 | + |
| 189 | +The 1.59.0 release disables incremental by default (unless explicitly asked for |
| 190 | +by via an environment variable: `RUSTC_FORCE_INCREMENTAL=1`). This mitigates a |
| 191 | +the effects of a known bug, [#94124], which can cause deserialization errors (and panics) during compilation |
| 192 | +with incremental compilation turned on. |
| 193 | + |
| 194 | +The specific fix for [#94124] has landed and is currently in the 1.60 beta, |
| 195 | +which will ship in six weeks. We are not presently aware of other issues that |
| 196 | +would encourage a decision to disable incremental in 1.60 stable, and if none |
| 197 | +arise it is likely that 1.60 stable will re-enable incremental compilation |
| 198 | +again. Incremental compilation remains on by default in the beta and nightly |
| 199 | +channels. |
| 200 | + |
| 201 | +As always, we encourage users to test on the nightly and beta channels and |
| 202 | +report issues you find: particularly for incremental bugs, this is the best way |
| 203 | +to ensure the Rust team can judge whether there is breakage and the number of |
| 204 | +users it affects. |
| 205 | + |
| 206 | +[#94124]: https://github.com/rust-lang/rust/issues/94124 |
| 207 | + |
| 208 | +### Stabilized APIs |
| 209 | + |
| 210 | +The following methods and trait implementations are now stabilized: |
| 211 | + |
| 212 | +- [`std::thread::available_parallelism`][available_parallelism] |
| 213 | +- [`Result::copied`][result-copied] |
| 214 | +- [`Result::cloned`][result-cloned] |
| 215 | +- [`arch::asm!`][asm] |
| 216 | +- [`arch::global_asm!`][global_asm] |
| 217 | +- [`ops::ControlFlow::is_break`][is_break] |
| 218 | +- [`ops::ControlFlow::is_continue`][is_continue] |
| 219 | +- [`TryFrom<char> for u8`][try_from_char_u8] |
| 220 | +- [`char::TryFromCharError`][try_from_char_err] |
| 221 | + implementing `Clone`, `Debug`, `Display`, `PartialEq`, `Copy`, `Eq`, `Error` |
| 222 | +- [`iter::zip`][zip] |
| 223 | +- [`NonZeroU8::is_power_of_two`][is_power_of_two8] |
| 224 | +- [`NonZeroU16::is_power_of_two`][is_power_of_two16] |
| 225 | +- [`NonZeroU32::is_power_of_two`][is_power_of_two32] |
| 226 | +- [`NonZeroU64::is_power_of_two`][is_power_of_two64] |
| 227 | +- [`NonZeroU128::is_power_of_two`][is_power_of_two128] |
| 228 | +- [`DoubleEndedIterator for ToLowercase`][lowercase] |
| 229 | +- [`DoubleEndedIterator for ToUppercase`][uppercase] |
| 230 | +- [`TryFrom<&mut [T]> for [T; N]`][tryfrom_ref_arr] |
| 231 | +- [`UnwindSafe for Once`][unwindsafe_once] |
| 232 | +- [`RefUnwindSafe for Once`][refunwindsafe_once] |
| 233 | +- [armv8 neon intrinsics for aarch64][stdarch/1266] |
| 234 | + |
| 235 | +The following previously stable functions are now `const`: |
| 236 | + |
| 237 | +- [`mem::MaybeUninit::as_ptr`][muninit_ptr] |
| 238 | +- [`mem::MaybeUninit::assume_init`][muninit_init] |
| 239 | +- [`mem::MaybeUninit::assume_init_ref`][muninit_init_ref] |
| 240 | +- [`ffi::CStr::from_bytes_with_nul_unchecked`][cstr_from_bytes] |
| 241 | + |
| 242 | +### Other changes |
| 243 | + |
| 244 | +There are other changes in the Rust 1.59.0 release. Check out what changed in |
| 245 | +[Rust](https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1590-2022-02-24), |
| 246 | +[Cargo](https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-159-2022-02-24), |
| 247 | +and [Clippy](https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-159). |
| 248 | + |
| 249 | +### Contributors to 1.59.0 |
| 250 | + |
| 251 | +Many people came together to create Rust 1.59.0. |
| 252 | +We couldn't have done it without all of you. |
| 253 | +[Thanks!](https://thanks.rust-lang.org/rust/1.59.0/) |
| 254 | + |
| 255 | +[cstr_from_bytes]: https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#method.from_bytes_with_nul_unchecked |
| 256 | +[muninit_ptr]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.as_ptr |
| 257 | +[muninit_init]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init |
| 258 | +[muninit_init_ref]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init_ref |
| 259 | +[unwindsafe_once]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#impl-UnwindSafe |
| 260 | +[refunwindsafe_once]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#impl-RefUnwindSafe |
| 261 | +[tryfrom_ref_arr]: https://doc.rust-lang.org/stable/std/convert/trait.TryFrom.html#impl-TryFrom%3C%26%27_%20mut%20%5BT%5D%3E |
| 262 | +[lowercase]: https://doc.rust-lang.org/stable/std/char/struct.ToLowercase.html#impl-DoubleEndedIterator |
| 263 | +[uppercase]: https://doc.rust-lang.org/stable/std/char/struct.ToUppercase.html#impl-DoubleEndedIterator |
| 264 | +[try_from_char_err]: https://doc.rust-lang.org/stable/std/char/struct.TryFromCharError.html |
| 265 | +[available_parallelism]: https://doc.rust-lang.org/stable/std/thread/fn.available_parallelism.html |
| 266 | +[result-copied]: https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.copied |
| 267 | +[result-cloned]: https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.cloned |
| 268 | +[option-copied]: https://doc.rust-lang.org/stable/std/result/enum.Option.html#method.copied |
| 269 | +[option-cloned]: https://doc.rust-lang.org/stable/std/result/enum.Option.html#method.cloned |
| 270 | +[asm]: https://doc.rust-lang.org/stable/core/arch/macro.asm.html |
| 271 | +[global_asm]: https://doc.rust-lang.org/stable/core/arch/macro.global_asm.html |
| 272 | +[is_break]: https://doc.rust-lang.org/stable/std/ops/enum.ControlFlow.html#method.is_break |
| 273 | +[is_continue]: https://doc.rust-lang.org/stable/std/ops/enum.ControlFlow.html#method.is_continue |
| 274 | +[try_from_char_u8]: https://doc.rust-lang.org/stable/std/primitive.char.html#impl-TryFrom%3Cchar%3E |
| 275 | +[zip]: https://doc.rust-lang.org/stable/std/iter/fn.zip.html |
| 276 | +[is_power_of_two8]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU8.html#method.is_power_of_two |
| 277 | +[is_power_of_two16]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU16.html#method.is_power_of_two |
| 278 | +[is_power_of_two32]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU32.html#method.is_power_of_two |
| 279 | +[is_power_of_two64]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU64.html#method.is_power_of_two |
| 280 | +[is_power_of_two128]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU128.html#method.is_power_of_two |
| 281 | +[stdarch/1266]: https://github.com/rust-lang/stdarch/pull/1266 |
0 commit comments