Skip to content

Commit 4708afa

Browse files
committed
Announcing Rust 1.89.0
1 parent efcda98 commit 4708afa

File tree

1 file changed

+218
-0
lines changed

1 file changed

+218
-0
lines changed

content/Rust-1.89.0.md

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
+++
2+
path = "2025/08/07/Rust-1.89.0"
3+
title = "Announcing Rust 1.89.0"
4+
authors = ["The Rust Release Team"]
5+
aliases = ["releases/1.89.0"]
6+
7+
[extra]
8+
release = true
9+
+++
10+
11+
The Rust team is happy to announce a new version of Rust, 1.89.0. Rust is a programming language empowering everyone to build reliable and efficient software.
12+
13+
If you have a previous version of Rust installed via `rustup`, you can get 1.89.0 with:
14+
15+
```console
16+
$ rustup update stable
17+
```
18+
19+
If you don't have it already, you can [get `rustup`](https://www.rust-lang.org/install.html) from the appropriate page on our website, and check out the [detailed release notes for 1.89.0](https://doc.rust-lang.org/stable/releases.html#version-1890-2025-08-07).
20+
21+
If you'd like to help us out by testing future releases, you might consider updating locally to use the beta channel (`rustup default beta`) or the nightly channel (`rustup default nightly`). Please [report](https://github.com/rust-lang/rust/issues/new/choose) any bugs you might come across!
22+
23+
## What's in 1.89.0 stable
24+
25+
### Explicitly inferred arguments to const generics
26+
27+
Rust now supports `_` as an argument to const generic parameters, inferring the value from surrounding context:
28+
29+
```rust
30+
pub fn all_false<const LEN: usize>() -> [bool; LEN] {
31+
[false; _]
32+
}
33+
```
34+
35+
Similar to the rules for when `_` is permitted as a type, `_` is not permitted as an argument to const generics when in a signature:
36+
37+
```rust
38+
// This is not allowed
39+
pub const fn all_false<const LEN: usize>() -> [bool; _] {
40+
[false; LEN]
41+
}
42+
43+
// Neither is this
44+
pub const ALL_FALSE: [bool; _] = all_false::<10>();
45+
```
46+
47+
### Mismatched lifetime syntaxes lint
48+
49+
[Lifetime elision][elision] in function signatures is an ergonomic aspect of the Rust language, but it can also be a stumbling point for newcomers and experts alike. This is especially true when lifetimes are inferred in types where it isn't syntactically obvious that a lifetime is even present:
50+
51+
```rust
52+
// The returned type `std::slice::Iter` has a lifetime,
53+
// but there's no visual indication of that.
54+
//
55+
// Lifetime elision infers the lifetime of the return
56+
// type to be the same as that of `scores`.
57+
fn items(scores: &[u8]) -> std::slice::Iter<u8> {
58+
scores.iter()
59+
}
60+
```
61+
62+
Code like this will now produce a warning by default:
63+
64+
```text
65+
warning: hiding a lifetime that's elided elsewhere is confusing
66+
--> src/lib.rs:1:18
67+
|
68+
1 | fn items(scores: &[u8]) -> std::slice::Iter<u8> {
69+
| ^^^^^ -------------------- the same lifetime is hidden here
70+
| |
71+
| the lifetime is elided here
72+
|
73+
= help: the same lifetime is referred to in inconsistent ways, making the signature confusing
74+
= note: `#[warn(mismatched_lifetime_syntaxes)]` on by default
75+
help: use `'_` for type paths
76+
|
77+
1 | fn items(scores: &[u8]) -> std::slice::Iter<'_, u8> {
78+
| +++
79+
```
80+
81+
We [first attempted][elided_lifetime_in_path] to improve this situation back in 2018 as part of the [`rust_2018_idioms`][2018-by-default] lint group, but [strong feedback][bevy] about the `elided_lifetimes_in_paths` lint showed that it was too blunt of a hammer as it warns about lifetimes which don't matter to understand the function:
82+
83+
```rust
84+
use std::fmt;
85+
86+
struct Greeting;
87+
88+
impl fmt::Display for Greeting {
89+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
90+
// -----^^^^^^^^^ expected lifetime parameter
91+
// Knowing that `Formatter` has a lifetime does not help the programmer
92+
"howdy".fmt(f)
93+
}
94+
}
95+
```
96+
97+
We then realized that the confusion we want to eliminate occurs when both
98+
99+
1. lifetime elision inference rules *connect* an input lifetime to an output lifetime
100+
2. it's not syntactically obvious that a lifetime exists
101+
102+
There are two pieces of Rust syntax that indicate that a lifetime exists: `&` and `'`, with `'` being subdivided into the inferred lifetime `'_` and named lifetimes `'a`. When a type uses a named lifetime, lifetime elision will not infer a lifetime for that type. Using these criteria, we can construct three groups:
103+
104+
| Self-evident it has a lifetime | Allow lifetime elision to infer a lifetime | Examples |
105+
|--------------------------------|--------------------------------------------|---------------------------------------|
106+
| No | Yes | `ContainsLifetime` |
107+
| Yes | Yes | `&T`, `&'_ T`, `ContainsLifetime<'_>` |
108+
| Yes | No | `&'a T`, `ContainsLifetime<'a>` |
109+
110+
The `mismatched_lifetime_syntaxes` lint checks that the inputs and outputs of a function belong to the same group. For the initial motivating example above, `&[u8]` falls into the second group while `std::slice::Iter<u8>` falls into the first group. We say that the lifetimes in the first group are *hidden*.
111+
112+
Because the input and output lifetimes belong to different groups, the lint will warn about this function, reducing confusion about when a value has a meaningful lifetime that isn't visually obvious.
113+
114+
The `mismatched_lifetime_syntaxes` lint supersedes the `elided_named_lifetimes` lint, which did something similar for named lifetimes specifically.
115+
116+
Future work on the `elided_lifetimes_in_paths` lint intends to split it into more focused sub-lints with an eye to warning about a subset of them eventually.
117+
118+
[elision]: https://doc.rust-lang.org/1.89/book/ch10-03-lifetime-syntax.html#lifetime-elision
119+
[elided_lifetime_in_path]: https://github.com/rust-lang/rust/pull/46254
120+
[2018-by-default]: https://github.com/rust-lang/rust/issues/54910
121+
[bevy]: https://github.com/rust-lang/rust/issues/131725
122+
123+
### More x86 target features
124+
125+
The `target_feature` attribute now supports the `sha512`, `sm3`, `sm4`, `kl` and `widekl` target features on x86. Additionally a number of `avx512` intrinsics and target features are also supported on x86:
126+
127+
```rust
128+
#[target_feature(enable = "avx512bw")]
129+
pub fn cool_simd_code(/* .. */) -> /* ... */ {
130+
/* ... */
131+
}
132+
133+
```
134+
135+
### Cross-compiled doctests
136+
137+
Doctests will now be tested when running `cargo test --doc --target other_target`, this may result in some amount of breakage due to would-be-failing doctests now being tested.
138+
139+
Failing tests can be disabled by annotating the doctest with `ignore-<target>`:
140+
```rust
141+
/// ```ignore-x86_64
142+
/// panic!("something")
143+
/// ```
144+
pub fn my_function() { }
145+
```
146+
147+
### `i128` and `u128` in `extern "C"` functions
148+
149+
`i128` and `u128` no longer trigger the `improper_ctypes_definitions` lint, meaning these types may be used in `extern "C"` functions without warning. This comes with some caveats:
150+
151+
* The Rust types are ABI- and layout-compatible with (unsigned) `__int128` in C when the type is available.
152+
* On platforms where `__int128` is not available, `i128` and `u128` do not necessarily align with any C type.
153+
* `i128` is _not_ necessarily compatible with `_BitInt(128)` on any platform, because `_BitInt(128)` and `__int128` may not have the same ABI (as is the case on x86-64).
154+
155+
This is the last bit of follow up to the layout changes from last year: https://blog.rust-lang.org/2024/03/30/i128-layout-update/.
156+
157+
### Demoting `x86_64-apple-darwin` to Tier 2 with host tools
158+
159+
GitHub will soon [discontinue][gha-sunset] providing free macOS x86\_64 runners for public repositories. Apple has also announced their [plans][apple] for discontinuing support for the x86\_86 architecture.
160+
161+
In accordance with these changes, the Rust project is in the [process of demoting the `x86_64-apple-darwin` target][rfc] from Tier 1 to Tier 2 with host tools. This means that the target, including tools like `rustc` and `cargo`, will be guaranteed to build but is not guaranteed to pass our automated test suite.
162+
163+
We expect that the RFC for the demotion to Tier 2 with host tools will be accepted between the releases of Rust 1.89 and 1.90, which means that Rust 1.89 will be the last release of Rust where `x86_64-apple-darwin` is a Tier 1 target.
164+
165+
For users, nothing will change. Builds of both the standard library and the compiler will still be distributed by the Rust Project for use via `rustup` or alternative installation methods.
166+
167+
[apple]: https://en.wikipedia.org/wiki/Mac_transition_to_Apple_silicon#Timeline
168+
[gha-sunset]: https://github.blog/changelog/2025-07-11-upcoming-changes-to-macos-hosted-runners-macos-latest-migration-and-xcode-support-policy-updates/#macos-13-is-closing-down
169+
[rfc]: https://github.com/rust-lang/rfcs/pull/3841
170+
171+
### Standards Compliant C ABI on the `wasm32-unknown-unknown` target
172+
173+
`extern "C"` functions on the `wasm32-unknown-unknown` target now have a standards compliant ABI. See this blog post for more information: https://blog.rust-lang.org/2025/04/04/c-abi-changes-for-wasm32-unknown-unknown.
174+
175+
### Platform Support
176+
177+
- [`x86_64-apple-darwin` is in the process of being demoted to Tier 2 with host tools](https://github.com/rust-lang/rfcs/pull/3841)
178+
- [Add new Tier-3 targets `loongarch32-unknown-none` and `loongarch32-unknown-none-softfloat`](https://github.com/rust-lang/rust/pull/142053)
179+
180+
Refer to Rust’s [platform support page][platform_support_page] for more information on Rust’s tiered platform support.
181+
182+
### Stabilized APIs
183+
184+
- [`NonZero<char>`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html)
185+
- Many intrinsics for x86, not enumerated here
186+
- [AVX512 intrinsics](https://github.com/rust-lang/rust/issues/111137)
187+
- [`SHA512`, `SM3` and `SM4` intrinsics](https://github.com/rust-lang/rust/issues/126624)
188+
- [`File::lock`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.lock)
189+
- [`File::lock_shared`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.lock_shared)
190+
- [`File::try_lock`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.try_lock)
191+
- [`File::try_lock_shared`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.try_lock_shared)
192+
- [`File::unlock`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.unlock)
193+
- [`NonNull::from_ref`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.from_ref)
194+
- [`NonNull::from_mut`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.from_mut)
195+
- [`NonNull::without_provenance`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.without_provenance)
196+
- [`NonNull::with_exposed_provenance`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.with_exposed_provenance)
197+
- [`NonNull::expose_provenance`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.expose_provenance)
198+
- [`OsString::leak`](https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.leak)
199+
- [`PathBuf::leak`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.leak)
200+
- [`Result::flatten`](https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.flatten)
201+
- [`std::os::linux::net::TcpStreamExt::quickack`](https://doc.rust-lang.org/stable/std/os/linux/net/trait.TcpStreamExt.html#tymethod.quickack)
202+
- [`std::os::linux::net::TcpStreamExt::set_quickack`](https://doc.rust-lang.org/stable/std/os/linux/net/trait.TcpStreamExt.html#tymethod.set_quickack)
203+
204+
These previously stable APIs are now stable in const contexts:
205+
206+
- [`<[T; N]>::as_mut_slice`](https://doc.rust-lang.org/stable/std/primitive.array.html#method.as_mut_slice)
207+
- [`<[u8]>::eq_ignore_ascii_case`](https://doc.rust-lang.org/stable/std/primitive.slice.html#impl-%5Bu8%5D/method.eq_ignore_ascii_case)
208+
- [`str::eq_ignore_ascii_case`](https://doc.rust-lang.org/stable/std/primitive.str.html#impl-str/method.eq_ignore_ascii_case)
209+
210+
### Other changes
211+
212+
Check out everything that changed in [Rust](https://github.com/rust-lang/rust/releases/tag/1.89.0), [Cargo](https://doc.rust-lang.org/nightly/cargo/CHANGELOG.html#cargo-189-2025-08-07), and [Clippy](https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-189).
213+
214+
## Contributors to 1.89.0
215+
216+
Many people came together to create Rust 1.89.0. We couldn't have done it without all of you. [Thanks!](https://thanks.rust-lang.org/rust/1.89.0/)
217+
218+
[platform_support_page]: https://doc.rust-lang.org/rustc/platform-support.html

0 commit comments

Comments
 (0)