Skip to content

Commit e96d9c2

Browse files
committed
Announce rust 1.86.0
1 parent b51e346 commit e96d9c2

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed

posts/Rust-1.86.0.md

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
+++
2+
layout = "post"
3+
date = 2025-04-03
4+
title = "Announcing Rust 1.86.0"
5+
author = "The Rust Release Team"
6+
release = true
7+
+++
8+
9+
The Rust team is happy to announce a new version of Rust, 1.86.0. Rust is a programming language empowering everyone to build reliable and efficient software.
10+
11+
If you have a previous version of Rust installed via `rustup`, you can get 1.86.0 with:
12+
13+
```console
14+
$ rustup update stable
15+
```
16+
17+
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.86.0](https://doc.rust-lang.org/stable/releases.html#version-1860-2025-04-03).
18+
19+
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!
20+
21+
## What's in 1.86.0 stable
22+
23+
### Trait upcasting
24+
25+
This release includes a long awaited feature — the ability to upcast trait objects.
26+
If a trait has a [supertrait](https://doc.rust-lang.org/reference/items/traits.html#supertraits) you can coerce a reference to said trait object to a reference to a trait object of the super trait:
27+
28+
```rust
29+
trait Trait: Supertrait {}
30+
trait Supertrait {}
31+
32+
fn upcast(x: &dyn Trait) -> &dyn Supertrait {
33+
x
34+
}
35+
```
36+
37+
The same would work with any other kind of (smart)-pointer, like `Arc<dyn Trait> -> Arc<dyn Supertrait>` or `*const dyn Trait -> *const dyn Supertrait`.
38+
39+
Previously this would require a workaround in the form of an `upcast` method in the `Trait` itself (and that would work only for one kind of reference/pointer). Such workarounds are not necessary anymore.
40+
41+
Note that this adds a new _safety invariant_ to raw pointers — if a pointer points to a trait object, vtable must be valid for that trait. This means that "leaking" a raw pointer to a trait object with an invalid vtable into safe code may lead to undefined behavior.
42+
43+
Trait upcasting may be especially useful with the `Any` trait, as it allows upcasting your trait object to `dyn Any` to call the downcast methods. Whereas before you'd have to write workarounds for this or use external crates.
44+
45+
```rust
46+
use std::any::Any;
47+
48+
trait MyAny: Any {}
49+
50+
impl dyn MyAny {
51+
fn downcast_ref<T>(&self) -> Option<&T> {
52+
(self as &dyn Any).downcast_ref()
53+
}
54+
}
55+
```
56+
57+
You can [learn more about trait upcasting in the Rust reference](https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions).
58+
59+
### `HashMap`s and slices now support indexing multiple elements mutably
60+
61+
The borrow checker will prevent simaltaneous usage of references returned from `get_mut` methods. To get around this the standard library now provides a `get_disjoint_mut` helper on slices and `HashMap` to retrieve mutable references to multiple elements simaltaneously. See the following example taken from the API docs of [`slice::get_disjoint_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.get_disjoint_mut):
62+
```rust
63+
let v = &mut [1, 2, 3];
64+
if let Ok([a, b]) = v.get_disjoint_mut([0, 2]) {
65+
*a = 413;
66+
*b = 612;
67+
}
68+
assert_eq!(v, &[413, 2, 612]);
69+
70+
if let Ok([a, b]) = v.get_disjoint_mut([0..1, 1..3]) {
71+
a[0] = 8;
72+
b[0] = 88;
73+
b[1] = 888;
74+
}
75+
assert_eq!(v, &[8, 88, 888]);
76+
77+
if let Ok([a, b]) = v.get_disjoint_mut([1..=2, 0..=0]) {
78+
a[0] = 11;
79+
a[1] = 111;
80+
b[0] = 1;
81+
}
82+
assert_eq!(v, &[1, 11, 111]);
83+
```
84+
85+
### Allow safe functions to be marked with the #[target_feature] attribute.
86+
87+
Functions marked with `#[target_feature]` are generally considered as unsafe functions: they are unsafe to call, cannot *generally* be assigned to safe function pointers, and don't implement the `Fn*` traits.
88+
89+
However, calling them from other `#[target_feature]` functions with a superset of features is safe.
90+
91+
```rust
92+
// Demonstration function
93+
#[target_feature(enable = "avx2")]
94+
fn avx2() {}
95+
96+
fn foo() {
97+
// Calling `avx2` here is unsafe, as we must ensure
98+
// that AVX is available first.
99+
unsafe {
100+
avx2();
101+
}
102+
}
103+
104+
#[target_feature(enable = "avx2")]
105+
fn bar() {
106+
// Calling `avx2` here is safe.
107+
avx2();
108+
}
109+
```
110+
111+
### Debug assert pointers are non-null when required for soundness
112+
113+
The compiler will now insert checks that a pointer is not null upon non-zero-sized reads and writes, and also when the pointer is reborrowed into a reference. For example, the following code will now produce a non-unwinding panic:
114+
```rust
115+
let _x = *std::ptr::null::<u8>();
116+
let _x = &*std::ptr::null::<u8>();
117+
```
118+
Trivial examples like this have produced a warning since Rust 1.53.0, the new runtime check will detect these scenarios regardless of complexity.
119+
120+
### Make `missing_abi` lint warn by default
121+
122+
Omitting the ABI in extern blocks and functions (e.g. `extern {}` and `extern fn`) will now result in a warning (via the `missing_abi` lint). Omitting the ABI after the `extern` keyword has always implicitly resulted in the `"C"` ABI. It is now recommended to explicitly specify the `"C"` ABI (e.g. `extern "C" {}` and `extern "C" fn`).
123+
124+
### Target deprecation warning for 1.87.0
125+
126+
The target `i586-pc-windows-msvc` will be removed in the next version of Rust, 1.87.0. This is because this target is effectively useless. Its difference to the much more popular `i686-pc-windows-msvc` is that it does not require SSE2 instruction support, but Windows 10, the minimum required OS version of all `windows` targets (except the `win7` targets), requires SSE2 instructions itself, so this target does not fulfill a purpose.
127+
128+
You can check the [Major Change Proposal](https://github.com/rust-lang/compiler-team/issues/840) for more information.
129+
130+
### Stabilized APIs
131+
132+
- [`{float}::next_down`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.next_down)
133+
- [`{float}::next_up`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.next_up)
134+
- [`HashMap::get_disjoint_mut`](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.get_disjoint_mut)
135+
- [`HashMap::get_disjoint_unchecked_mut`](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.get_disjoint_unchecked_mut)
136+
- [`NonZero::count_ones`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.count_ones)
137+
- [`Vec::pop_if`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.pop_if)
138+
- [`sync::Once::wait`](https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.wait)
139+
- [`sync::Once::wait_force`](https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.wait_force)
140+
- [`sync::OnceLock::wait`](https://doc.rust-lang.org/stable/std/sync/struct.OnceLock.html#method.wait)
141+
- [`<[_]>::get_disjoint_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.get_disjoint_mut)
142+
- [`<[_]>::get_disjoint_unchecked_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.get_disjoint_unchecked_mut)
143+
- [`slice::GetDisjointMutError`](https://doc.rust-lang.org/stable/std/slice/enum.GetDisjointMutError.html)
144+
145+
146+
These APIs are now stable in const contexts:
147+
148+
- [`io::Cursor::get_mut`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.get_mut)
149+
- [`io::Cursor::set_position`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.set_position)
150+
- [`str::is_char_boundary`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.is_char_boundary)
151+
- [`str::split_at`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at)
152+
- [`str::split_at_checked`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_checked)
153+
- [`str::split_at_mut`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_mut)
154+
- [`str::split_at_mut_checked`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_mut_checked)
155+
- [`hint::black_box`](https://doc.rust-lang.org/stable/std/hint/fn.black_box.html)
156+
157+
### Other changes
158+
159+
Check out everything that changed in [Rust](https://github.com/rust-lang/rust/releases/tag/1.86.0), [Cargo](https://doc.rust-lang.org/nightly/cargo/CHANGELOG.html#cargo-186-2025-04-03), and [Clippy](https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-186).
160+
161+
## Contributors to 1.86.0
162+
163+
Many people came together to create Rust 1.86.0. We couldn't have done it without all of you. [Thanks!](https://thanks.rust-lang.org/rust/1.86.0/)

0 commit comments

Comments
 (0)