-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Do not materialise X in [X; 0] when X is unsizing a const #145277
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Do not materialise X in [X; 0] when X is unsizing a const #145277
Conversation
r? @nnethercote rustbot has assigned @nnethercote. Use |
This comment has been minimized.
This comment has been minimized.
6a64501
to
b7b9519
Compare
A question to @traviscross ... Should we also need to run this through |
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 |
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. |
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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Renamed.
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. |
b7b9519
to
c1ab3ed
Compare
@bors try |
This comment has been minimized.
This comment has been minimized.
…<try> Do not materialise X in [X; 0] when X is unsizing a const
Okay, I will request a crater run ahead of the next meeting. |
I will push a commit to include the second test cases. |
Hello team. I would like to request
for a quick triage. 🙇 |
Let's do the top 1000, just for more coverage :) @craterbot run mode=build-and-test crates=top-1000 |
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
I found some similar-ish behavior with |
@theemathas @traviscross @RalfJung It seems that an explicit cast in the language That has the following definition. rust/compiler/rustc_middle/src/thir.rs Lines 358 to 364 in 4056082
How shall we interpret this? I read this as "disregard whether this could be a constant, build it as a value anyway." Specifically for our example, it is lowered into
The consequence is that a drop will happen. |
Constants are values, so I can't make sense of "treat as value not constant". |
Signed-off-by: Ding Xiang Fei <dingxiangfei2009@protonmail.ch> Co-authored-by: Theemathas Chirananthavat <theemathas@gmail.com>
8444dde
to
b77de83
Compare
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. |
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. |
@rustbot ready I have added a test and additional predicates on the repeated expression. |
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 |
Once you have made the PR, please link to it from here. Otherwise, I think this has been discussed sufficiently. @bors r+ |
…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!
Let's move discussion on a proper and comprehensive fix to the next issue #147021 |
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
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!
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
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
Fix #143671
It turns out that MIR builder materialise
X
in[X; 0]
into a temporary local whenX
is unsizing aconst
. This led to a confusing call to destructor ofX
when such a destructor is declared. PlaygroundThis patch may miss out other cases that we should avoid materialisation in case of
[X; 0]
. Suggestions to include is most welcome!