Skip to content

Don't allow flattened format_args in const. #139624

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 2 commits into from
Apr 30, 2025

Conversation

m-ou-se
Copy link
Member

@m-ou-se m-ou-se commented Apr 10, 2025

Fixes #139136

Fixes #139621

We allow format_args!("a") in const, but don't allow any format_args with arguments in const, such as format_args!("{}", arg).

However, we accidentally allow format_args!("hello {}", "world") in const, as it gets flattened to format_args!("hello world").

This also applies to panic in const.

This wasn't supposed to happen. I added protection against this in the format args flattening code, but I accidentally marked a function as const that shouldn't have been const but this was removed in #135139.

This is a breaking change. The crater found no breakage, however.

This breaks things like:

const _: () = if false { panic!("a {}", "a") };

and

const F: std::fmt::Arguments<'static> = format_args!("a {}", "a");

@rustbot

This comment was marked as outdated.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Apr 10, 2025
@m-ou-se m-ou-se assigned m-ou-se and unassigned Mark-Simulacrum Apr 10, 2025
@m-ou-se
Copy link
Member Author

m-ou-se commented Apr 10, 2025

@bors try

bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 10, 2025
Don't allow flattened format_args in const.

Fixes rust-lang#139136 and rust-lang#139621 by breaking the 'flattened format_args' cases.

This is a breaking change.

Let's try a crater run.
@bors
Copy link
Collaborator

bors commented Apr 10, 2025

⌛ Trying commit cc791eb with merge 6619027...

@m-ou-se m-ou-se added S-experimental Status: Ongoing experiment that does not require reviewing and won't be merged in its current state. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 10, 2025
@m-ou-se m-ou-se mentioned this pull request Apr 7, 2025
29 tasks
@bors
Copy link
Collaborator

bors commented Apr 10, 2025

☀️ Try build successful - checks-actions
Build commit: 6619027 (6619027b13a87a3597115f2c8231f107bf3a7a5f)

@m-ou-se
Copy link
Member Author

m-ou-se commented Apr 10, 2025

@craterbot check

@craterbot
Copy link
Collaborator

👌 Experiment pr-139624 created and queued.
🤖 Automatically detected try build 6619027
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-experimental Status: Ongoing experiment that does not require reviewing and won't be merged in its current state. labels Apr 10, 2025
@craterbot
Copy link
Collaborator

🚧 Experiment pr-139624 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Collaborator

🎉 Experiment pr-139624 is completed!
📊 3 regressed and 5 fixed (612545 total)
📰 Open the full report.

⚠️ If you notice any spurious failure please add them to the denylist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Apr 11, 2025
@RalfJung
Copy link
Member

These all seem spurious.

Landing this requires FCP, but I'm not sure which team -- lang and/or libs-api?

@m-ou-se m-ou-se added T-lang Relevant to the language team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. and removed T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Apr 11, 2025
@m-ou-se m-ou-se marked this pull request as ready for review April 11, 2025 12:05
@m-ou-se
Copy link
Member Author

m-ou-se commented Apr 11, 2025

@rfcbot merge

@rfcbot
Copy link
Collaborator

rfcbot commented Apr 11, 2025

Team member @m-ou-se has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns.
See this document for info about what commands tagged team members can give me.

@m-ou-se m-ou-se added the beta-accepted Accepted for backporting to the compiler in the beta channel. label Apr 23, 2025
@rfcbot rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. to-announce Announce this issue on triage meeting and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Apr 26, 2025
@rfcbot
Copy link
Collaborator

rfcbot commented Apr 26, 2025

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

This will be merged soon.

@jhpratt
Copy link
Member

jhpratt commented Apr 26, 2025

r=me with a test added per Ralf's suggestion.

@m-ou-se
Copy link
Member Author

m-ou-se commented Apr 30, 2025

@bors r=jhpratt

@bors
Copy link
Collaborator

bors commented Apr 30, 2025

📌 Commit 56426db has been approved by jhpratt

It is now in the queue for this repository.

@bors bors added the S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. label Apr 30, 2025
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 30, 2025
…iaskrgr

Rollup of 9 pull requests

Successful merges:

 - rust-lang#134232 (Share the naked asm impl between cg_ssa and cg_clif)
 - rust-lang#139624 (Don't allow flattened format_args in const.)
 - rust-lang#140090 (Check bare function idents for non snake-case name)
 - rust-lang#140203 (Issue an error when using `no_mangle` on language items)
 - rust-lang#140450 (ast: Remove token visiting from AST visitor)
 - rust-lang#140498 (Misc tweaks to HIR typeck (mostly w.r.t. checking calls))
 - rust-lang#140504 (transmutability: ensure_sufficient_stack when answering query)
 - rust-lang#140506 (unstable-book: fix capitalization)
 - rust-lang#140516 (Replace use of rustc_type_ir by rustc_middle)

Failed merges:

 - rust-lang#140374 (Resolve instance for SymFn in global/naked asm)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit bc99a04 into rust-lang:master Apr 30, 2025
6 checks passed
@rustbot rustbot added this to the 1.88.0 milestone Apr 30, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Apr 30, 2025
Rollup merge of rust-lang#139624 - m-ou-se:unconst-format-args, r=jhpratt

Don't allow flattened format_args in const.

Fixes rust-lang#139136

Fixes rust-lang#139621

We allow `format_args!("a")` in const, but don't allow any format_args with arguments in const, such as `format_args!("{}", arg)`.

However, we accidentally allow `format_args!("hello {}", "world")` in const, as it gets flattened to `format_args!("hello world")`.

This also applies to panic in const.

This wasn't supposed to happen. I added protection against this in the format args flattening code, ~~but I accidentally marked a function as const that shouldn't have been const~~ but this was removed in rust-lang#135139.

This is a breaking change. The crater found no breakage, however.

This breaks things like:

```rust
const _: () = if false { panic!("a {}", "a") };
```

and

```rust
const F: std::fmt::Arguments<'static> = format_args!("a {}", "a");
```
@m-ou-se m-ou-se deleted the unconst-format-args branch May 1, 2025 09:18
@cuviper cuviper mentioned this pull request May 2, 2025
@cuviper cuviper modified the milestones: 1.88.0, 1.87.0 May 2, 2025
@cuviper cuviper removed the beta-nominated Nominated for backporting to the compiler in the beta channel. label May 2, 2025
bors added a commit to rust-lang-ci/rust that referenced this pull request May 3, 2025
[beta] backports

- Don't allow flattened format_args in const. rust-lang#139624
- set subsections_via_symbols for ld64 helper sections rust-lang#139752
- Fix detection of `main` function if there are expressions around it rust-lang#140220
- rustdoc: Fix doctest heuristic for main fn wrapping rust-lang#140420
- extend the list of registered dylibs on `test::prepare_cargo_test` rust-lang#140563

r? cuviper
@jieyouxu jieyouxu removed needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. I-lang-easy-decision Issue: The decision needed by the team is conjectured to be easy; this does not imply nomination labels May 3, 2025
github-actions bot pushed a commit to model-checking/verify-rust-std that referenced this pull request May 9, 2025
…ratt

Don't allow flattened format_args in const.

Fixes rust-lang#139136

Fixes rust-lang#139621

We allow `format_args!("a")` in const, but don't allow any format_args with arguments in const, such as `format_args!("{}", arg)`.

However, we accidentally allow `format_args!("hello {}", "world")` in const, as it gets flattened to `format_args!("hello world")`.

This also applies to panic in const.

This wasn't supposed to happen. I added protection against this in the format args flattening code, ~~but I accidentally marked a function as const that shouldn't have been const~~ but this was removed in rust-lang#135139.

This is a breaking change. The crater found no breakage, however.

This breaks things like:

```rust
const _: () = if false { panic!("a {}", "a") };
```

and

```rust
const F: std::fmt::Arguments<'static> = format_args!("a {}", "a");
```
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request May 19, 2025
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [rust](https://github.com/rust-lang/rust) | minor | `1.86.0` -> `1.87.0` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>rust-lang/rust (rust)</summary>

### [`v1.87.0`](https://github.com/rust-lang/rust/blob/HEAD/RELEASES.md#Version-1870-2025-05-15)

[Compare Source](rust-lang/rust@1.86.0...1.87.0)

\==========================

<a id="1.87.0-Language"></a>

## Language

-   [Stabilize `asm_goto` feature](rust-lang/rust#133870)
-   [Allow parsing open beginning ranges (`..EXPR`) after unary operators `!`, `-`, and `*`](rust-lang/rust#134900).
-   [Don't require method impls for methods with `Self: Sized` bounds in `impl`s for unsized types](rust-lang/rust#135480)
-   [Stabilize `feature(precise_capturing_in_traits)` allowing `use<...>` bounds on return position `impl Trait` in `trait`s](rust-lang/rust#138128)

<a id="1.87.0-Compiler"></a>

## Compiler

-   [x86: make SSE2 required for i686 targets and use it to pass SIMD types](rust-lang/rust#135408)

<a id="1.87.0-Platform-Support"></a>

## Platform Support

-   [Remove `i586-pc-windows-msvc` target](rust-lang/rust#137957)

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

<a id="1.87.0-Libraries"></a>

## Libraries

-   [Stabilize the anonymous pipe API](rust-lang/rust#127154)
-   [Add support for unbounded left/right shift operations](rust-lang/rust#129375)
-   [Print pointer metadata in `Debug` impl of raw pointers](rust-lang/rust#135080)
-   [`Vec::with_capacity` guarantees it allocates with the amount requested, even if `Vec::capacity` returns a different number.](rust-lang/rust#135933)
-   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 (rust-lang/stdarch#1714, rust-lang/stdarch#1716, rust-lang/stdarch#1717)
-   [Undeprecate `env::home_dir`](rust-lang/rust#137327)
-   [Denote `ControlFlow` as `#[must_use]`](rust-lang/rust#137449)
-   [Macros such as `assert_eq!` and `vec!` now support `const {...}` expressions](rust-lang/rust#138162)

<a id="1.87.0-Stabilized-APIs"></a>

## Stabilized APIs

-   [`Vec::extract_if`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.extract_if)
-   [`vec::ExtractIf`](https://doc.rust-lang.org/stable/std/vec/struct.ExtractIf.html)
-   [`LinkedList::extract_if`](https://doc.rust-lang.org/stable/std/collections/struct.LinkedList.html#method.extract_if)
-   [`linked_list::ExtractIf`](https://doc.rust-lang.org/stable/std/collections/linked_list/struct.ExtractIf.html)
-   [`<[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_within`](https://doc.rust-lang.org/stable/alloc/string/struct.String.html#method.extend_from_within)
-   [`os_str::Display`](https://doc.rust-lang.org/stable/std/ffi/os_str/struct.Display.html)
-   [`OsString::display`](https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.display)
-   [`OsStr::display`](https://doc.rust-lang.org/stable/std/ffi/struct.OsStr.html#method.display)
-   [`io::pipe`](https://doc.rust-lang.org/stable/std/io/fn.pipe.html)
-   [`io::PipeReader`](https://doc.rust-lang.org/stable/std/io/struct.PipeReader.html)
-   [`io::PipeWriter`](https://doc.rust-lang.org/stable/std/io/struct.PipeWriter.html)
-   [`impl From<PipeReader> for OwnedHandle`](https://doc.rust-lang.org/stable/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeReader%3E-for-OwnedHandle)
-   [`impl From<PipeWriter> for OwnedHandle`](https://doc.rust-lang.org/stable/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeWriter%3E-for-OwnedHandle)
-   [`impl From<PipeReader> for Stdio`](https://doc.rust-lang.org/stable/std/process/struct.Stdio.html)
-   [`impl From<PipeWriter> for Stdio`](https://doc.rust-lang.org/stable/std/process/struct.Stdio.html#impl-From%3CPipeWriter%3E-for-Stdio)
-   [`impl From<PipeReader> for OwnedFd`](https://doc.rust-lang.org/stable/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeReader%3E-for-OwnedFd)
-   [`impl From<PipeWriter> for OwnedFd`](https://doc.rust-lang.org/stable/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeWriter%3E-for-OwnedFd)
-   [`Box<MaybeUninit<T>>::write`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.write)
-   [`impl TryFrom<Vec<u8>> for String`](https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-TryFrom%3CVec%3Cu8%3E%3E-for-String)
-   [`<*const T>::offset_from_unsigned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from_unsigned)
-   [`<*const T>::byte_offset_from_unsigned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.byte_offset_from_unsigned)
-   [`<*mut T>::offset_from_unsigned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from_unsigned-1)
-   [`<*mut T>::byte_offset_from_unsigned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.byte_offset_from_unsigned-1)
-   [`NonNull::offset_from_unsigned`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.offset_from_unsigned)
-   [`NonNull::byte_offset_from_unsigned`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.byte_offset_from_unsigned)
-   [`<uN>::cast_signed`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.cast_signed)
-   [`NonZero::<uN>::cast_signed`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.cast_signed-5).
-   [`<iN>::cast_unsigned`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.cast_unsigned).
-   [`NonZero::<iN>::cast_unsigned`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.cast_unsigned-5).
-   [`<uN>::is_multiple_of`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.is_multiple_of)
-   [`<uN>::unbounded_shl`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.unbounded_shl)
-   [`<uN>::unbounded_shr`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.unbounded_shr)
-   [`<iN>::unbounded_shl`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.unbounded_shl)
-   [`<iN>::unbounded_shr`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.unbounded_shr)
-   [`<iN>::midpoint`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.midpoint)
-   [`<str>::from_utf8`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.from_utf8)
-   [`<str>::from_utf8_mut`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.from_utf8\_mut)
-   [`<str>::from_utf8_unchecked`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.from_utf8\_unchecked)
-   [`<str>::from_utf8_unchecked_mut`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.from_utf8\_unchecked_mut)

These previously stable APIs are now stable in const contexts:

-   [`core::str::from_utf8_mut`](https://doc.rust-lang.org/stable/std/str/fn.from_utf8\_mut.html)
-   [`<[T]>::copy_from_slice`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.copy_from_slice)
-   [`SocketAddr::set_ip`](https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.set_ip)
-   [`SocketAddr::set_port`](https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.set_port),
-   [`SocketAddrV4::set_ip`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV4.html#method.set_ip)
-   [`SocketAddrV4::set_port`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV4.html#method.set_port),
-   [`SocketAddrV6::set_ip`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.set_ip)
-   [`SocketAddrV6::set_port`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.set_port)
-   [`SocketAddrV6::set_flowinfo`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.set_flowinfo)
-   [`SocketAddrV6::set_scope_id`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.set_scope_id)
-   [`char::is_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_digit)
-   [`char::is_whitespace`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.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`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.into_bytes)
-   [`String::as_str`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_str)
-   [`String::capacity`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.capacity)
-   [`String::as_bytes`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_bytes)
-   [`String::len`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.len)
-   [`String::is_empty`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.is_empty)
-   [`String::as_mut_str`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_mut_str)
-   [`String::as_mut_vec`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_mut_vec)
-   [`Vec::as_ptr`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_ptr)
-   [`Vec::as_slice`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_slice)
-   [`Vec::capacity`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.capacity)
-   [`Vec::len`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.len)
-   [`Vec::is_empty`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.is_empty)
-   [`Vec::as_mut_slice`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_mut_slice)
-   [`Vec::as_mut_ptr`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_mut_ptr)

<a id="1.87.0-Cargo"></a>

## Cargo

-   [Add terminal integration via ANSI OSC 9;4 sequences](rust-lang/cargo#14615)
-   [chore: bump openssl to v3](rust-lang/cargo#15232)
-   [feat(package): add --exclude-lockfile flag](rust-lang/cargo#15234)

<a id="1.87.0-Compatibility-Notes"></a>

## Compatibility Notes

-   [Rust now raises an error for macro invocations inside the `#![crate_name]` attribute](rust-lang/rust#127581)
-   [Unstable fields are now always considered to be inhabited](rust-lang/rust#133889)
-   [Macro arguments of unary operators followed by open beginning ranges may now be matched differently](rust-lang/rust#134900)
-   [Make `Debug` impl of raw pointers print metadata if present](rust-lang/rust#135080)
-   [Warn against function pointers using unsupported ABI strings in dependencies](rust-lang/rust#135767)
-   [Associated types on `dyn` types are no longer deduplicated](rust-lang/rust#136458)
-   [Forbid attributes on `..` inside of struct patterns (`let Struct { #[attribute] .. }) =`](rust-lang/rust#136490)
-   [Make `ptr_cast_add_auto_to_object` lint into hard error](rust-lang/rust#136764)
-   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](rust-lang/rust#136932)
-   [Turn order dependent trait objects future incompat warning into a hard error](rust-lang/rust#136968)
-   [Denote `ControlFlow` as `#[must_use]`](rust-lang/rust#137449)
-   [Windows: The standard library no longer links `advapi32`, except on win7.](rust-lang/rust#138233) 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.](rust-lang/rust#138844)
-   [Start changing the internal representation of pasted tokens](rust-lang/rust#124141). 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.](rust-lang/rust#139624)

<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.

-   [Update to LLVM 20](rust-lang/rust#135763)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC4xMS4xOSIsInVwZGF0ZWRJblZlciI6IjQwLjExLjE5IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiXX0=-->
wip-sync pushed a commit to NetBSD/pkgsrc-wip that referenced this pull request May 20, 2025
Pkgsrc changes:
 * patches adjustments to adapt to upstream changes & new versions
   of included crates
 * associated checksums++

Upstream changes relative to 1.86.0:

Version 1.87.0 (2025-05-15)
==========================

Language
--------
- [Stabilize `asm_goto` feature]
  (rust-lang/rust#133870)
- [Allow parsing open beginning ranges (`..EXPR`) after unary
  operators `!`, `~`, `-`, and `*`}]
  (rust-lang/rust#134900).
- [Don't require method impls for methods with `Self: Sized` bounds
  in `impl`s for unsized types]
  (rust-lang/rust#135480)
- [Stabilize `feature(precise_capturing_in_traits)` allowing
  `use<...>` bounds on return position `impl Trait` in `trait`s]
  (rust-lang/rust#138128)

Compiler
--------
- [x86: make SSE2 required for i686 targets and use it to pass SIMD types]
  (rust-lang/rust#135408)

Platform Support
----------------
- [Remove `i586-pc-windows-msvc` target]
  (rust-lang/rust#137957)

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]
  (rust-lang/rust#127154)
- [Add support for unbounded left/right shift operations]
  (rust-lang/rust#129375)
- [Print pointer metadata in `Debug` impl of raw pointers]
  (rust-lang/rust#135080)
- [`Vec::with_capacity` guarantees it allocates with the amount
  requested, even if `Vec::capacity` returns a different number.]
  (rust-lang/rust#135933)
- 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
  (rust-lang/stdarch#1714,
  rust-lang/stdarch#1716,
  rust-lang/stdarch#1717)
- [Undeprecate `env::home_dir`]
  (rust-lang/rust#137327)
- [Denote `ControlFlow` as `#[must_use]`]
  (rust-lang/rust#137449)
- [Macros such as `assert_eq!` and `vec!` now support `const {...}` expressions]
  (rust-lang/rust#138162)

Stabilized APIs
---------------

- [`Vec::extract_if`]
  (https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.extract_if)
- [`vec::ExtractIf`]
  (https://doc.rust-lang.org/stable/std/vec/struct.ExtractIf.html)
- [`LinkedList::extract_if`]
  (https://doc.rust-lang.org/stable/std/collections/struct.LinkedList.html#method.extract_if)
- [`linked_list::ExtractIf`]
  (https://doc.rust-lang.org/stable/std/collections/linked_list/struct.ExtractIf.html)
- [`<[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_within`]
  (https://doc.rust-lang.org/stable/alloc/string/struct.String.html#method.extend_from_within)
- [`os_str::Display`]
  (https://doc.rust-lang.org/stable/std/ffi/os_str/struct.Display.html)
- [`OsString::display`]
  (https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.display)
- [`OsStr::display`]
  (https://doc.rust-lang.org/stable/std/ffi/struct.OsStr.html#method.display)
- [`io::pipe`]
  (https://doc.rust-lang.org/stable/std/io/fn.pipe.html)
- [`io::PipeReader`]
  (https://doc.rust-lang.org/stable/std/io/struct.PipeReader.html)
- [`io::PipeWriter`]
  (https://doc.rust-lang.org/stable/std/io/struct.PipeWriter.html)
- [`impl From<PipeReader> for OwnedHandle`]
  (https://doc.rust-lang.org/stable/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeReader%3E-for-OwnedHandle)
- [`impl From<PipeWriter> for OwnedHandle`]
  (https://doc.rust-lang.org/stable/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeWriter%3E-for-OwnedHandle)
- [`impl From<PipeReader> for Stdio`]
  (https://doc.rust-lang.org/stable/std/process/struct.Stdio.html)
- [`impl From<PipeWriter> for Stdio`]
  (https://doc.rust-lang.org/stable/std/process/struct.Stdio.html#impl-From%3CPipeWriter%3E-for-Stdio)
- [`impl From<PipeReader> for OwnedFd`]
  (https://doc.rust-lang.org/stable/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeReader%3E-for-OwnedFd)
- [`impl From<PipeWriter> for OwnedFd`]
  (https://doc.rust-lang.org/stable/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeWriter%3E-for-OwnedFd)
- [`Box<MaybeUninit<T>>::write`]
  (https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.write)
- [`impl TryFrom<Vec<u8>> for String`]
  (https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-TryFrom%3CVec%3Cu8%3E%3E-for-String)
- [`<*const T>::offset_from_unsigned`]
  (https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from_unsigned)
- [`<*const T>::byte_offset_from_unsigned`]
  (https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.byte_offset_from_unsigned)
- [`<*mut T>::offset_from_unsigned`]
  (https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from_unsigned-1)
- [`<*mut T>::byte_offset_from_unsigned`]
  (https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.byte_offset_from_unsigned-1)
- [`NonNull::offset_from_unsigned`]
  (https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.offset_from_unsigned)
- [`NonNull::byte_offset_from_unsigned`]
  (https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.byte_offset_from_unsigned)
- [`<uN>::cast_signed`]
  (https://doc.rust-lang.org/stable/std/primitive.usize.html#method.cast_signed)
- [`NonZero::<uN>::cast_signed`]
  (https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.cast_signed-5).
- [`<iN>::cast_unsigned`]
  (https://doc.rust-lang.org/stable/std/primitive.isize.html#method.cast_unsigned).
- [`NonZero::<iN>::cast_unsigned`]
  (https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.cast_unsigned-5).
- [`<uN>::is_multiple_of`]
  (https://doc.rust-lang.org/stable/std/primitive.usize.html#method.is_multiple_of)
- [`<uN>::unbounded_shl`]
  (https://doc.rust-lang.org/stable/std/primitive.usize.html#method.unbounded_shl)
- [`<uN>::unbounded_shr`]
  (https://doc.rust-lang.org/stable/std/primitive.usize.html#method.unbounded_shr)
- [`<iN>::unbounded_shl`]
  (https://doc.rust-lang.org/stable/std/primitive.isize.html#method.unbounded_shl)
- [`<iN>::unbounded_shr`]
  (https://doc.rust-lang.org/stable/std/primitive.isize.html#method.unbounded_shr)
- [`<iN>::midpoint`]
  (https://doc.rust-lang.org/stable/std/primitive.isize.html#method.midpoint)
- [`<str>::from_utf8`]
  (https://doc.rust-lang.org/stable/std/primitive.str.html#method.from_utf8)
- [`<str>::from_utf8_mut`]
  (https://doc.rust-lang.org/stable/std/primitive.str.html#method.from_utf8_mut)
- [`<str>::from_utf8_unchecked`]
  (https://doc.rust-lang.org/stable/std/primitive.str.html#method.from_utf8_unchecked)
- [`<str>::from_utf8_unchecked_mut`]
  (https://doc.rust-lang.org/stable/std/primitive.str.html#method.from_utf8_unchecked_mut)

These previously stable APIs are now stable in const contexts:

- [`core::str::from_utf8_mut`]
  (https://doc.rust-lang.org/stable/std/str/fn.from_utf8_mut.html)
- [`<[T]>::copy_from_slice`]
  (https://doc.rust-lang.org/stable/std/primitive.slice.html#method.copy_from_slice)
- [`SocketAddr::set_ip`]
  (https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.set_ip)
- [`SocketAddr::set_port`]
  (https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.set_port),
- [`SocketAddrV4::set_ip`]
  (https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV4.html#method.set_ip)
- [`SocketAddrV4::set_port`]
  (https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV4.html#method.set_port),
- [`SocketAddrV6::set_ip`]
  (https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.set_ip)
- [`SocketAddrV6::set_port`]
  (https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.set_port)
- [`SocketAddrV6::set_flowinfo`]
  (https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.set_flowinfo)
- [`SocketAddrV6::set_scope_id`]
  (https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.set_scope_id)
- [`char::is_digit`]
  (https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_digit)
- [`char::is_whitespace`]
  (https://doc.rust-lang.org/stable/std/primitive.char.html#method.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`]
  (https://doc.rust-lang.org/stable/std/string/struct.String.html#method.into_bytes)
- [`String::as_str`]
  (https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_str)
- [`String::capacity`]
  (https://doc.rust-lang.org/stable/std/string/struct.String.html#method.capacity)
- [`String::as_bytes`]
  (https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_bytes)
- [`String::len`]
  (https://doc.rust-lang.org/stable/std/string/struct.String.html#method.len)
- [`String::is_empty`]
  (https://doc.rust-lang.org/stable/std/string/struct.String.html#method.is_empty)
- [`String::as_mut_str`]
  (https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_mut_str)
- [`String::as_mut_vec`]
  (https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_mut_vec)
- [`Vec::as_ptr`]
  (https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_ptr)
- [`Vec::as_slice`]
  (https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_slice)
- [`Vec::capacity`]
  (https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.capacity)
- [`Vec::len`]
  (https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.len)
- [`Vec::is_empty`]
  (https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.is_empty)
- [`Vec::as_mut_slice`]
  (https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_mut_slice)
- [`Vec::as_mut_ptr`]
  (https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_mut_ptr)

Cargo
-----
- [Add terminal integration via ANSI OSC 9;4 sequences]
  (rust-lang/cargo#14615)
- [chore: bump openssl to v3]
  (rust-lang/cargo#15232)
- [feat(package): add --exclude-lockfile flag]
  (rust-lang/cargo#15234)

Compatibility Notes
-------------------
- [Rust now raises an error for macro invocations inside the
  `#![crate_name]` attribute]
  (rust-lang/rust#127581)
- [Unstable fields are now always considered to be inhabited]
  (rust-lang/rust#133889)
- [Macro arguments of unary operators followed by open beginning
  ranges may now be matched differently]
  (rust-lang/rust#134900)
- [Make `Debug` impl of raw pointers print metadata if present]
  (rust-lang/rust#135080)
- [Warn against function pointers using unsupported ABI strings in dependencies]
  (rust-lang/rust#135767)
- [Associated types on `dyn` types are no longer deduplicated]
  (rust-lang/rust#136458)
- [Forbid attributes on `..` inside of struct patterns (`let Struct
  { #[attribute] .. }) =`]
  (rust-lang/rust#136490)
- [Make `ptr_cast_add_auto_to_object` lint into hard error]
  (rust-lang/rust#136764)
- 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]
  (rust-lang/rust#136932)
- [Turn order dependent trait objects future incompat warning into a hard error]
  (rust-lang/rust#136968)
- [Denote `ControlFlow` as `#[must_use]`]
  (rust-lang/rust#137449)
- [Windows: The standard library no longer links `advapi32`, except
  on win7.] (rust-lang/rust#138233)
  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.](rust-lang/rust#138844)
- [Start changing the internal representation of pasted tokens]
  (rust-lang/rust#124141). 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.]
  (rust-lang/rust#139624)

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]
  (rust-lang/rust#135763)
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
beta-accepted Accepted for backporting to the compiler in the beta channel. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. S-waiting-on-fcp Status: PR is in FCP and is awaiting for FCP to complete. T-lang Relevant to the language team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. to-announce Announce this issue on triage meeting
Projects
None yet
Development

Successfully merging this pull request may close these issues.

panic!() with formatting arguments sometimes accepted in const Inlining/flattening of format_args!() accidentally exposed as stable through const