← Back to all releases

Rust 1.87.0

Released on May 15, 2025

What's Changed

Full Changelog

Language

--------

- Stabilize asm_goto feature

- Allow parsing open beginning ranges (..EXPR) after unary operators !, -, and *.

- Don't require method impls for methods with Self: Sized bounds in impls for unsized types

- Stabilize feature(precise_capturing_in_traits) allowing use<...> bounds on return position impl Trait in traits

Compiler

--------

- x86: make SSE2 required for i686 targets and use it to pass SIMD types

Platform Support

----------------

- Remove i586-pc-windows-msvc target

Refer to Rust's [platform support page][platform-support-doc]

for more information on Rust's tiered platform support.

[platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html

Libraries

---------

- Stabilize the anonymous pipe API

- Add support for unbounded left/right shift operations

- Print pointer metadata in Debug impl of raw pointers

- Vec::with_capacity guarantees it allocates with the amount requested, even if Vec::capacity returns a different number.

- Most std::arch intrinsics which don't take pointer arguments can now be called from safe code if the caller has the appropriate target features already enabled (https://github.com/rust-lang/stdarch/pull/1714, https://github.com/rust-lang/stdarch/pull/1716, https://github.com/rust-lang/stdarch/pull/1717)

- Undeprecate env::home_dir

- Denote ControlFlow as #[must_use]

- Macros such as assert_eq! and vec! now support const {...} expressions

Stabilized APIs

---------------

- Vec::extract_if

- vec::ExtractIf

- LinkedList::extract_if

- linked_list::ExtractIf

- <[T]>::split_off

- <[T]>::split_off_mut

- <[T]>::split_off_first

- <[T]>::split_off_first_mut

- <[T]>::split_off_last

- <[T]>::split_off_last_mut

- String::extend_from_within

- os_str::Display

- OsString::display

- OsStr::display

- io::pipe

- io::PipeReader

- io::PipeWriter

- impl From for OwnedHandle

- impl From for OwnedHandle

- impl From for Stdio

- impl From for Stdio

- impl From for OwnedFd

- impl From for OwnedFd

- Box>::write

- impl TryFrom> for String

- <*const T>::offset_from_unsigned

- <*const T>::byte_offset_from_unsigned

- <*mut T>::offset_from_unsigned

- <*mut T>::byte_offset_from_unsigned

- NonNull::offset_from_unsigned

- NonNull::byte_offset_from_unsigned

- ::cast_signed

- NonZero::::cast_signed.

- ::cast_unsigned.

- NonZero::::cast_unsigned.

- ::is_multiple_of

- ::unbounded_shl

- ::unbounded_shr

- ::unbounded_shl

- ::unbounded_shr

- ::midpoint

- ::from_utf8

- ::from_utf8_mut

- ::from_utf8_unchecked

- ::from_utf8_unchecked_mut

These previously stable APIs are now stable in const contexts:

- core::str::from_utf8_mut

- <[T]>::copy_from_slice

- SocketAddr::set_ip

- SocketAddr::set_port,

- SocketAddrV4::set_ip

- SocketAddrV4::set_port,

- SocketAddrV6::set_ip

- SocketAddrV6::set_port

- SocketAddrV6::set_flowinfo

- SocketAddrV6::set_scope_id

- char::is_digit

- char::is_whitespace

- [<[[T; N]]>::as_flattened](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_flattened)

- [<[[T; N]]>::as_flattened_mut](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_flattened_mut)

- String::into_bytes

- String::as_str

- String::capacity

- String::as_bytes

- String::len

- String::is_empty

- String::as_mut_str

- String::as_mut_vec

- Vec::as_ptr

- Vec::as_slice

- Vec::capacity

- Vec::len

- Vec::is_empty

- Vec::as_mut_slice

- Vec::as_mut_ptr

Cargo

-----

- Add terminal integration via ANSI OSC 9;4 sequences

- chore: bump openssl to v3

- feat(package): add --exclude-lockfile flag

Compatibility Notes

-------------------

- Rust now raises an error for macro invocations inside the #![crate_name] attribute

- Unstable fields are now always considered to be inhabited

- Macro arguments of unary operators followed by open beginning ranges may now be matched differently

- Make Debug impl of raw pointers print metadata if present

- Warn against function pointers using unsupported ABI strings in dependencies

- Associated types on dyn types are no longer deduplicated

- Forbid attributes on .. inside of struct patterns (let Struct { #[attribute] .. }) =

- Make ptr_cast_add_auto_to_object lint into hard error

- Many std::arch intrinsics are now safe to call in some contexts, there may now be new unused_unsafe warnings in existing codebases.

- Limit width and precision formatting options to 16 bits on all targets

- Turn order dependent trait objects future incompat warning into a hard error

- Denote ControlFlow as #[must_use]

- Windows: The standard library no longer links advapi32, except on win7. Code such as C libraries that were relying on this assumption may need to explicitly link advapi32.

- Proc macros can no longer observe expanded cfg(true) attributes.

- Start changing the internal representation of pasted tokens. Certain invalid declarative macros that were previously accepted in obscure circumstances are now correctly rejected by the compiler. Use of a tt fragment specifier can often fix these macros.

- Don't allow flattened format_args in const.

Internal Changes

----------------

These changes do not affect any public interfaces of Rust, but they represent

significant improvements to the performance or internals of rustc and related

tools.

- Update to LLVM 20