about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorStuart Cook <Zalathar@users.noreply.github.com>2025-09-25 20:31:52 +1000
committerGitHub <noreply@github.com>2025-09-25 20:31:52 +1000
commit21b0e12e0140604150e5a2d4cf93fe2cac8f552f (patch)
treebdfe395a169999271d6aecbf12d8c59db207469b /tests
parent2acd80cfa928c1371d2c60149b3febe66c9e6637 (diff)
parentb77de834c031890c048f8164d4b5979d2511c00e (diff)
downloadrust-21b0e12e0140604150e5a2d4cf93fe2cac8f552f.tar.gz
rust-21b0e12e0140604150e5a2d4cf93fe2cac8f552f.zip
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 rust-lang/rust#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!
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs46
1 files changed, 46 insertions, 0 deletions
diff --git a/tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs b/tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs
new file mode 100644
index 00000000000..38479d9070b
--- /dev/null
+++ b/tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs
@@ -0,0 +1,46 @@
+//@ run-pass
+
+#![feature(unsize)]
+#![feature(coerce_unsized)]
+
+use std::fmt::Display;
+use std::marker::Unsize;
+use std::ops::CoerceUnsized;
+use std::rc::Weak;
+
+#[repr(transparent)]
+struct X<'a, T: ?Sized> {
+    f: &'a T,
+}
+
+impl<'a, T: ?Sized> Drop for X<'a, T> {
+    fn drop(&mut self) {
+        panic!()
+    }
+}
+
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<X<'a, U>> for X<'a, T> where
+    &'a T: CoerceUnsized<&'a U>
+{
+}
+
+const Y: X<'static, i32> = X { f: &0 };
+
+fn main() {
+    let _: [X<'static, dyn Display>; 0] = [Y; 0];
+    coercion_on_weak_in_const();
+    coercion_on_weak_as_cast();
+}
+
+fn coercion_on_weak_in_const() {
+    const X: Weak<i32> = Weak::new();
+    const Y: [Weak<dyn Send>; 0] = [X; 0];
+    let _ = Y;
+}
+
+fn coercion_on_weak_as_cast() {
+    const Y: X<'static, i32> = X { f: &0 };
+    // What happens in the following code is that
+    // a constant is explicitly coerced into
+    let _a: [X<'static, dyn Display>; 0] = [Y as X<'static, dyn Display>; 0];
+}