Rust versions / 1.87
Rust release · May 15, 2025
Rust 1.87: what's new, what was stabilized
Short answerRust 1.87 was released on May 15, 2025: 2 language stabilizations (Stabilize asm_goto feature); 74 newly stable APIs (Vec::extract_if, vec::ExtractIf, LinkedList::extract_if, linked_list::ExtractIf, ...); 16 compatibility notes that can affect existing code.
← Rust 1.86All versionsRust 1.88 →
Language features stabilized
- Stabilize asm_goto feature
- Stabilize feature(precise_capturing_in_traits) allowing use<...> bounds on return position impl Trait in traits
74 APIs stabilized
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<PipeReader> for OwnedHandle, impl From<PipeWriter> for OwnedHandle, impl From<PipeReader> for Stdio, impl From<PipeWriter> for Stdio, impl From<PipeReader> for OwnedFd, impl From<PipeWriter> for OwnedFd, Box<MaybeUninit<T>>::write, impl TryFrom<Vec<u8>> 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, <uN>::cast_signed, NonZero::<uN>::cast_signed, <iN>::cast_unsigned, NonZero::<iN>::cast_unsigned, <uN>::is_multiple_of, <uN>::unbounded_shl, <uN>::unbounded_shr, <iN>::unbounded_shl, <iN>::unbounded_shr, <iN>::midpoint, <str>::from_utf8, <str>::from_utf8_mut, <str>::from_utf8_unchecked, <str>::from_utf8_unchecked_mut, 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, <[[T; N]]>::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
Can it break my build?
The release lists these compatibility notes. Most only affect rare code, but read them before you raise your toolchain in CI:
- [Rust now raises an error for macro invocations inside the
#![crate_name]attribute](https://github.com/rust-lang/rust/pull/127581) - 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
Debugimpl of raw pointers print metadata if present - Warn against function pointers using unsupported ABI strings in dependencies
- Associated types on
dyntypes are no longer deduplicated - [Forbid attributes on
..inside of struct patterns (let Struct { #[attribute] .. }) =](https://github.com/rust-lang/rust/pull/136490) - Make
ptr_cast_add_auto_to_objectlint into hard error - Many
std::archintrinsics are now safe to call in some contexts, there may now be newunused_unsafewarnings in existing codebases. - Limit
widthandprecisionformatting options to 16 bits on all targets - Turn order dependent trait objects future incompat warning into a hard error
- [Denote
ControlFlowas#[must_use]](https://github.com/rust-lang/rust/pull/137449) - 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
ttfragment specifier can often fix these macros. - Don't allow flattened format_args in const.
Use it
rustup update stable # get the newest release
rustup install 1.87 # or exactly this one
rustup override set 1.87 # pin a project to itTo require at least this version from users of your crate, set rust-version = "1.87" under [package] in Cargo.toml. Cargo then refuses to build it on older compilers with a clear message, and with resolver 3 (the default on the 2024 edition, Rust 1.85+) it also prefers dependency versions that support it.
Full release notes
Language
- Stabilize
asm_gotofeature - Allow parsing open beginning ranges (
..EXPR) after unary operators!,-, and*. - Don't require method impls for methods with
Self: Sizedbounds inimpls for unsized types - Stabilize
feature(precise_capturing_in_traits)allowinguse<...>bounds on return positionimpl Traitintraits
<a id="1.87.0-Compiler"></a>
Compiler
<a id="1.87.0-Platform-Support"></a>
Platform Support
Refer to Rust's platform support page for more information on Rust's tiered platform support.
<a id="1.87.0-Libraries"></a>
Libraries
- Stabilize the anonymous pipe API
- Add support for unbounded left/right shift operations
- Print pointer metadata in
Debugimpl of raw pointers Vec::with_capacityguarantees it allocates with the amount requested, even ifVec::capacityreturns a different number.- Most
std::archintrinsics 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
ControlFlowas#[must_use]](https://github.com/rust-lang/rust/pull/137449) - Macros such as
assert_eq!andvec!now supportconst {...}expressions
<a id="1.87.0-Stabilized-APIs"></a>
Stabilized APIs
Vec::extract_ifvec::ExtractIfLinkedList::extract_iflinked_list::ExtractIf- [
<[T]>::split_off](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off) - [
<[T]>::split_off_mut](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_mut) - [
<[T]>::split_off_first](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_first) - [
<[T]>::split_off_first_mut](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_first_mut) - [
<[T]>::split_off_last](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_last) - [
<[T]>::split_off_last_mut](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_last_mut) String::extend_from_withinos_str::DisplayOsString::displayOsStr::displayio::pipeio::PipeReaderio::PipeWriterimpl From<PipeReader> for OwnedHandleimpl From<PipeWriter> for OwnedHandleimpl From<PipeReader> for Stdioimpl From<PipeWriter> for Stdioimpl From<PipeReader> for OwnedFdimpl From<PipeWriter> for OwnedFdBox<MaybeUninit<T>>::writeimpl TryFrom<Vec<u8>> for String<*const T>::offset_from_unsigned<*const T>::byte_offset_from_unsigned<*mut T>::offset_from_unsigned<*mut T>::byte_offset_from_unsignedNonNull::offset_from_unsignedNonNull::byte_offset_from_unsigned<uN>::cast_signedNonZero::<uN>::cast_signed.<iN>::cast_unsigned.NonZero::<iN>::cast_unsigned.<uN>::is_multiple_of<uN>::unbounded_shl<uN>::unbounded_shr<iN>::unbounded_shl<iN>::unbounded_shr<iN>::midpoint<str>::from_utf8<str>::from_utf8_mut<str>::from_utf8_unchecked<str>::from_utf8_unchecked_mut
These previously stable APIs are now stable in const contexts:
core::str::from_utf8_mut- [
<[T]>::copy_from_slice](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.copy_from_slice) SocketAddr::set_ipSocketAddr::set_port,SocketAddrV4::set_ipSocketAddrV4::set_port,SocketAddrV6::set_ipSocketAddrV6::set_portSocketAddrV6::set_flowinfoSocketAddrV6::set_scope_idchar::is_digitchar::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_bytesString::as_strString::capacityString::as_bytesString::lenString::is_emptyString::as_mut_strString::as_mut_vecVec::as_ptrVec::as_sliceVec::capacityVec::lenVec::is_emptyVec::as_mut_sliceVec::as_mut_ptr
<a id="1.87.0-Cargo"></a>
Cargo
- Add terminal integration via ANSI OSC 9;4 sequences
- chore: bump openssl to v3
- feat(package): add --exclude-lockfile flag
<a id="1.87.0-Compatibility-Notes"></a>
Compatibility Notes
- [Rust now raises an error for macro invocations inside the
#![crate_name]attribute](https://github.com/rust-lang/rust/pull/127581) - 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
Debugimpl of raw pointers print metadata if present - Warn against function pointers using unsupported ABI strings in dependencies
- Associated types on
dyntypes are no longer deduplicated - [Forbid attributes on
..inside of struct patterns (let Struct { #[attribute] .. }) =](https://github.com/rust-lang/rust/pull/136490) - Make
ptr_cast_add_auto_to_objectlint into hard error - Many
std::archintrinsics are now safe to call in some contexts, there may now be newunused_unsafewarnings in existing codebases. - Limit
widthandprecisionformatting options to 16 bits on all targets - Turn order dependent trait objects future incompat warning into a hard error
- [Denote
ControlFlowas#[must_use]](https://github.com/rust-lang/rust/pull/137449) - 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
ttfragment specifier can often fix these macros. - Don't allow flattened format_args in const.
<a id="1.87.0-Internal-Changes"></a>
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.
Release notes from the Rust project's RELEASES.md (MIT or Apache-2.0); summaries above are ours.
Up next
Next releaseRust 1.88Released Jun 26, 2025.Read it next →Also worth your time
Did this answer your question?