Skip to content

Conversation

@dingxiangfei2009
Copy link
Contributor

@dingxiangfei2009 dingxiangfei2009 commented Aug 11, 2025

Fix #143671

It turns out that MIR builder materialise X in [X; 0] into a temporary local when X is unsizing a const. This led to a confusing call to destructor of X when such a destructor is declared. Playground

This patch may miss out other cases that we should avoid materialisation in case of [X; 0]. Suggestions to include is most welcome!

@rustbot
Copy link
Collaborator

rustbot commented Aug 11, 2025

r? @nnethercote

rustbot has assigned @nnethercote.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 11, 2025
@rust-log-analyzer

This comment has been minimized.

@dingxiangfei2009 dingxiangfei2009 force-pushed the fold-coercion-into-const branch from 6a64501 to b7b9519 Compare August 11, 2025 22:54
@dingxiangfei2009
Copy link
Contributor Author

A question to @traviscross ...

Should we also need to run this through t-lang as well? It is hard to imagine that anything would rely on destructor called in this way, but I am not sure.

@traviscross traviscross added T-lang Relevant to the language team and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 11, 2025
@traviscross
Copy link
Contributor

A question to @traviscross ...

Should we also need to run this through t-lang as well? It is hard to imagine that anything would rely on destructor called in this way, but I am not sure.

Well, let's see. It looks like this issue does affect the user-visible stable behavior of the language:

use core::{mem, ptr, sync::atomic::{AtomicU64, Ordering}};

static COUNT: AtomicU64 = AtomicU64::new(0);

struct S;
impl Drop for S {
    fn drop(&mut self) {
        COUNT.fetch_add(1, Ordering::Relaxed);
    }
}
trait Tr {}
impl Tr for S {}

const X: Box<dyn Tr> = unsafe {
    mem::transmute::<_, Box<S>>(ptr::dangling_mut::<S>())
};

fn main() {
    assert_eq!(0, COUNT.load(Ordering::Relaxed));
    let _a: &'static [Box<dyn Tr>; 0] = &[X; 0];
    assert_eq!(1, COUNT.load(Ordering::Relaxed));
    //~^ Drop was run.
    let _b = [X; 0];
    assert_eq!(1, COUNT.load(Ordering::Relaxed));
    //~^ Drop wasn't run.
}

So, yes, it's ours to fix via FCP.

Anyone think we need a crater run? For my part, I could go either way on that, and I do want us to fix this, so let's:

@rfcbot fcp merge

@rustbot labels +I-lang-nominated +needs-fcp

cc @rust-lang/lang @rust-lang/lang-advisors

@rfcbot
Copy link

rfcbot commented Aug 11, 2025

Team member @traviscross 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.

@rfcbot rfcbot added the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label Aug 11, 2025
@rustbot rustbot added I-lang-nominated Nominated for discussion during a lang team meeting. needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. labels Aug 11, 2025
@rfcbot rfcbot added the disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. label Aug 11, 2025
@theemathas
Copy link
Contributor

theemathas commented Aug 12, 2025

Another fun edge case where this change is visible in user code: This code compiles with this PR, but fails on nightly due to dropping in const

use std::rc::Weak;

const X: Weak<i32> = Weak::new();
const Y: [Weak<dyn Send>; 0] = [X; 0];


/// Recursively inspect a THIR expression and probe through unsizing
/// operations that can be const-folded today.
fn check_constness(&self, mut ek: &'a ExprKind<'tcx>) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/ek/kind/

I've never seen ek used for an ExprKind, kind is the normal name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Renamed.

@traviscross traviscross added the P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang label Aug 12, 2025
@nnethercote
Copy link
Contributor

The code changes seem fine, speaking as a reviewer who is not at all familiar with the MIR building and relevant lang details. The example from @theemathas might be worth adding to the test case.

@dingxiangfei2009
Copy link
Contributor Author

@bors try

@rust-bors

This comment has been minimized.

rust-bors bot added a commit that referenced this pull request Aug 12, 2025
…<try>

Do not materialise X in [X; 0] when X is unsizing a const
@dingxiangfei2009
Copy link
Contributor Author

Okay, I will request a crater run ahead of the next meeting.

@dingxiangfei2009
Copy link
Contributor Author

I will push a commit to include the second test cases.

@rust-bors
Copy link

rust-bors bot commented Aug 12, 2025

☀️ Try build successful (CI)
Build commit: 981ca44 (981ca440e18f6cc4bc9026d4be8ddb1ca8378af7, parent: a1531335fe2807715fff569904d99602022643a7)

@dingxiangfei2009
Copy link
Contributor Author

dingxiangfei2009 commented Aug 12, 2025

Hello team. I would like to request

@ craterbot run mode=build-and-test crates=top-100

for a quick triage. 🙇

@nnethercote
Copy link
Contributor

Let's do the top 1000, just for more coverage :)

@craterbot run mode=build-and-test crates=top-1000

@craterbot
Copy link
Collaborator

👌 Experiment pr-145277 created and queued.
🤖 Automatically detected try build 981ca44
⚠️ Try build based on commit c1ab3ed, but latest commit is 8444dde. Did you forget to make a new try build?
🔍 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

@rustbot
Copy link
Collaborator

rustbot commented Sep 24, 2025

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@dingxiangfei2009
Copy link
Contributor Author

dingxiangfei2009 commented Sep 24, 2025

I will open an issue for discussion on a future fix plan. The categorisation of the repeated operand could use some better, thorough analysis from the compiler, so that we can have a consistent evaluation strategy.

@dingxiangfei2009
Copy link
Contributor Author

@rustbot ready

I have added a test and additional predicates on the repeated expression.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Sep 24, 2025
@traviscross
Copy link
Contributor

traviscross commented Sep 24, 2025

We talked about this in the lang/RfL call with most of us who had checked a box present and agreed that this caveat about as casts doesn't disturb our FCP as long as landing this doesn't make it harder to fix that case as well.

@nnethercote
Copy link
Contributor

I will open an issue for discussion on a future fix plan. The categorisation of the repeated operand could use some better, thorough analysis from the compiler, so that we can have a consistent evaluation strategy.

Once you have made the PR, please link to it from here. Otherwise, I think this has been discussed sufficiently.

@bors r+

@bors
Copy link
Collaborator

bors commented Sep 24, 2025

📌 Commit b77de83 has been approved by nnethercote

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 24, 2025
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Sep 25, 2025
…o-const, r=nnethercote

Do not materialise X in [X; 0] when X is unsizing a const

Fix rust-lang#143671

It turns out that MIR builder materialise `X` in `[X; 0]` into a temporary local when `X` is unsizing a `const`. This led to a confusing call to destructor of `X` when such a destructor is declared. [Playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=8dfc933af89efeb89c881bc77498ba63)

This patch may miss out other cases that we should avoid materialisation in case of `[X; 0]`. Suggestions to include is most welcome!
@dingxiangfei2009
Copy link
Contributor Author

Let's move discussion on a proper and comprehensive fix to the next issue #147021

bors added a commit that referenced this pull request Sep 25, 2025
Rollup of 14 pull requests

Successful merges:

 - #145067 (RawVecInner: add missing `unsafe` to unsafe fns)
 - #145277 (Do not materialise X in [X; 0] when X is unsizing a const)
 - #145973 (Add `std` support for `armv7a-vex-v5`)
 - #146667 (Add an attribute to check the number of lanes in a SIMD vector after monomorphization)
 - #146735 (unstably constify float mul_add methods)
 - #146737 (f16_f128: enable some more tests in Miri)
 - #146766 (Add attributes for #[global_allocator] functions)
 - #146905 (llvm: update remarks support on LLVM 22)
 - #146982 (Remove erroneous normalization step in `tests/run-make/linker-warning`)
 - #147005 (Small string formatting cleanup)
 - #147007 (Explicitly note `&[SocketAddr]` impl of `ToSocketAddrs`)
 - #147008 (bootstrap.py: Respect build.jobs while building bootstrap tool)
 - #147013 (rustdoc: Fix documentation for `--doctest-build-arg`)
 - #147015 (Use `LLVMDisposeTargetMachine`)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 21b0e12 into rust-lang:master Sep 25, 2025
10 checks passed
@rustbot rustbot added this to the 1.92.0 milestone Sep 25, 2025
rust-timer added a commit that referenced this pull request Sep 25, 2025
Rollup merge of #145277 - dingxiangfei2009:fold-coercion-into-const, r=nnethercote

Do not materialise X in [X; 0] when X is unsizing a const

Fix #143671

It turns out that MIR builder materialise `X` in `[X; 0]` into a temporary local when `X` is unsizing a `const`. This led to a confusing call to destructor of `X` when such a destructor is declared. [Playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=8dfc933af89efeb89c881bc77498ba63)

This patch may miss out other cases that we should avoid materialisation in case of `[X; 0]`. Suggestions to include is most welcome!
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Sep 26, 2025
Rollup of 14 pull requests

Successful merges:

 - rust-lang/rust#145067 (RawVecInner: add missing `unsafe` to unsafe fns)
 - rust-lang/rust#145277 (Do not materialise X in [X; 0] when X is unsizing a const)
 - rust-lang/rust#145973 (Add `std` support for `armv7a-vex-v5`)
 - rust-lang/rust#146667 (Add an attribute to check the number of lanes in a SIMD vector after monomorphization)
 - rust-lang/rust#146735 (unstably constify float mul_add methods)
 - rust-lang/rust#146737 (f16_f128: enable some more tests in Miri)
 - rust-lang/rust#146766 (Add attributes for #[global_allocator] functions)
 - rust-lang/rust#146905 (llvm: update remarks support on LLVM 22)
 - rust-lang/rust#146982 (Remove erroneous normalization step in `tests/run-make/linker-warning`)
 - rust-lang/rust#147005 (Small string formatting cleanup)
 - rust-lang/rust#147007 (Explicitly note `&[SocketAddr]` impl of `ToSocketAddrs`)
 - rust-lang/rust#147008 (bootstrap.py: Respect build.jobs while building bootstrap tool)
 - rust-lang/rust#147013 (rustdoc: Fix documentation for `--doctest-build-arg`)
 - rust-lang/rust#147015 (Use `LLVMDisposeTargetMachine`)

r? `@ghost`
`@rustbot` modify labels: rollup
@dingxiangfei2009 dingxiangfei2009 deleted the fold-coercion-into-const branch September 26, 2025 19:06
github-actions bot pushed a commit to model-checking/verify-rust-std that referenced this pull request Oct 9, 2025
Rollup of 14 pull requests

Successful merges:

 - rust-lang#145067 (RawVecInner: add missing `unsafe` to unsafe fns)
 - rust-lang#145277 (Do not materialise X in [X; 0] when X is unsizing a const)
 - rust-lang#145973 (Add `std` support for `armv7a-vex-v5`)
 - rust-lang#146667 (Add an attribute to check the number of lanes in a SIMD vector after monomorphization)
 - rust-lang#146735 (unstably constify float mul_add methods)
 - rust-lang#146737 (f16_f128: enable some more tests in Miri)
 - rust-lang#146766 (Add attributes for #[global_allocator] functions)
 - rust-lang#146905 (llvm: update remarks support on LLVM 22)
 - rust-lang#146982 (Remove erroneous normalization step in `tests/run-make/linker-warning`)
 - rust-lang#147005 (Small string formatting cleanup)
 - rust-lang#147007 (Explicitly note `&[SocketAddr]` impl of `ToSocketAddrs`)
 - rust-lang#147008 (bootstrap.py: Respect build.jobs while building bootstrap tool)
 - rust-lang#147013 (rustdoc: Fix documentation for `--doctest-build-arg`)
 - rust-lang#147015 (Use `LLVMDisposeTargetMachine`)

r? `@ghost`
`@rustbot` modify labels: rollup
@apiraino apiraino removed the to-announce Announce this issue on triage meeting label Nov 27, 2025
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Dec 12, 2025
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [rust](https://github.com/rust-lang/rust) | minor | `1.91.1` -> `1.92.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.92.0`](https://github.com/rust-lang/rust/blob/HEAD/RELEASES.md#Version-1920-2025-12-11)

[Compare Source](rust-lang/rust@1.91.1...1.92.0)

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

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

## Language

- [Document `MaybeUninit` representation and validity](rust-lang/rust#140463)
- [Allow `&raw [mut | const]` for union field in safe code](rust-lang/rust#141469)
- [Prefer item bounds of associated types over where-bounds for auto-traits and `Sized`](rust-lang/rust#144064)
- [Do not materialize `X` in `[X; 0]` when `X` is unsizing a const](rust-lang/rust#145277)
- [Support combining `#[track_caller]` and `#[no_mangle]` (requires every declaration specifying `#[track_caller]` as well)](rust-lang/rust#145724)
- [Make never type lints `never_type_fallback_flowing_into_unsafe` and `dependency_on_unit_never_type_fallback` deny-by-default](rust-lang/rust#146167)
- [Allow specifying multiple bounds for same associated item, except in trait objects](rust-lang/rust#146593)
- [Slightly strengthen higher-ranked region handling in coherence](rust-lang/rust#146725)
- [The `unused_must_use` lint no longer warns on `Result<(), Uninhabited>` (for instance, `Result<(), !>`), or `ControlFlow<Uninhabited, ()>`](rust-lang/rust#147382). This avoids having to check for an error that can never happen.

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

## Compiler

- [Make `mips64el-unknown-linux-muslabi64` link dynamically](rust-lang/rust#146858)
- [Remove current code for embedding command-line args in PDB](rust-lang/rust#147022)
  Command-line information is typically not needed by debugging tools, and the removed code
  was causing problems for incremental builds even on targets that don't use PDB debuginfo.

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

## Libraries

- [Specialize `Iterator::eq{_by}` for `TrustedLen` iterators](rust-lang/rust#137122)
- [Simplify `Extend` for tuples](rust-lang/rust#138799)
- [Added details to `Debug` for `EncodeWide`](rust-lang/rust#140153).
- [`iter::Repeat::last`](rust-lang/rust#147258) and [`count`](rust-lang/rust#146410) will now panic, rather than looping infinitely.

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

## Stabilized APIs

- [`NonZero<u{N}>::div_ceil`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.div_ceil)
- [`Location::file_as_c_str`](https://doc.rust-lang.org/stable/std/panic/struct.Location.html#method.file_as_c_str)
- [`RwLockWriteGuard::downgrade`](https://doc.rust-lang.org/stable/std/sync/struct.RwLockWriteGuard.html#method.downgrade)
- [`Box::new_zeroed`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new_zeroed)
- [`Box::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new_zeroed_slice)
- [`Rc::new_zeroed`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.new_zeroed)
- [`Rc::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.new_zeroed_slice)
- [`Arc::new_zeroed`](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.new_zeroed)
- [`Arc::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.new_zeroed_slice)
- [`btree_map::Entry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/btree_map/enum.Entry.html#method.insert_entry)
- [`btree_map::VacantEntry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/btree_map/struct.VacantEntry.html#method.insert_entry)
- [`impl Extend<proc_macro::Group> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CGroup%3E-for-TokenStream)
- [`impl Extend<proc_macro::Literal> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CLiteral%3E-for-TokenStream)
- [`impl Extend<proc_macro::Punct> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CPunct%3E-for-TokenStream)
- [`impl Extend<proc_macro::Ident> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CIdent%3E-for-TokenStream)

These previously stable APIs are now stable in const contexts:

- [`<[_]>::rotate_left`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.rotate_left)
- [`<[_]>::rotate_right`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.rotate_right)

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

## Cargo

- [Added a new chapter](rust-lang/cargo#16119) to the Cargo book, ["Optimizing Build Performance"](https://doc.rust-lang.org/stable/cargo/guide/build-performance.html).

<a id="1.92.0-Rustdoc"></a>

## Rustdoc

- [If a trait item appears in rustdoc search, hide the corresponding impl items](rust-lang/rust#145898).  Previously a search for "last" would show both `Iterator::last` as well as impl methods like `std::vec::IntoIter::last`.  Now these impl methods will be hidden, freeing up space for inherent methods like `BTreeSet::last`.
- [Relax rules for identifiers in search](rust-lang/rust#147860).  Previously you could only search for identifiers that were valid in rust code, now searches only need to be valid as part of an identifier.  For example, you can now perform a search that starts with a digit.

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

## Compatibility Notes

- [Fix backtraces with `-C panic=abort` on Linux by generating unwind tables by default](rust-lang/rust#143613). Build with `-C force-unwind-tables=no` to keep omitting unwind tables.

* As part of the larger effort refactoring compiler built-in attributes and their diagnostics, [the future-compatibility lint `invalid_macro_export_arguments` is upgraded to deny-by-default and will be reported in dependencies too.](rust-lang/rust#143857)
* [Update the minimum external LLVM to 20](rust-lang/rust#145071)
* [Prevent downstream `impl DerefMut for Pin<LocalType>`](rust-lang/rust#145608)
* [Don't apply temporary lifetime extension rules to the arguments of non-extended `pin!` and formatting macros](rust-lang/rust#145838)

</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:eyJjcmVhdGVkSW5WZXIiOiI0Mi40Ny4wIiwidXBkYXRlZEluVmVyIjoiNDIuNDcuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90Il19-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. relnotes Marks issues that should be documented in the release notes of the next release. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-lang Relevant to the language team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unsize-coercible type causes [SOME_CONST; 0] to execute Drop, but only if type is annotated.