about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/crashes/74451.rs42
-rw-r--r--tests/ui/coercion/codegen-smart-pointer-with-alias.rs32
2 files changed, 32 insertions, 42 deletions
diff --git a/tests/crashes/74451.rs b/tests/crashes/74451.rs
deleted file mode 100644
index 8f936994678..00000000000
--- a/tests/crashes/74451.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-//@ known-bug: #74451
-//@ compile-flags: -Copt-level=0
-
-#![feature(specialization)]
-#![feature(unsize, coerce_unsized)]
-#![allow(incomplete_features)]
-#![crate_type = "lib"]
-
-use std::ops::CoerceUnsized;
-
-pub struct SmartassPtr<A: Smartass+?Sized>(A::Data);
-
-pub trait Smartass {
-    type Data;
-    type Data2: CoerceUnsized<*const [u8]>;
-}
-
-pub trait MaybeObjectSafe {}
-
-impl MaybeObjectSafe for () {}
-
-impl<T> Smartass for T {
-    type Data = <Self as Smartass>::Data2;
-    default type Data2 = *const [u8; 0];
-}
-
-impl Smartass for () {
-    type Data2 = *const [u8; 1];
-}
-
-impl Smartass for dyn MaybeObjectSafe {
-    type Data = *const [u8];
-    type Data2 = *const [u8; 0];
-}
-
-impl<U: Smartass+?Sized, T: Smartass+?Sized> CoerceUnsized<SmartassPtr<T>> for SmartassPtr<U>
-    where <U as Smartass>::Data: std::ops::CoerceUnsized<<T as Smartass>::Data>
-{}
-
-pub fn conv(s: SmartassPtr<()>) -> SmartassPtr<dyn MaybeObjectSafe> {
-    s // This shouldn't coerce
-}
diff --git a/tests/ui/coercion/codegen-smart-pointer-with-alias.rs b/tests/ui/coercion/codegen-smart-pointer-with-alias.rs
new file mode 100644
index 00000000000..a68952bb70a
--- /dev/null
+++ b/tests/ui/coercion/codegen-smart-pointer-with-alias.rs
@@ -0,0 +1,32 @@
+//@ build-pass
+
+// Regression test for <https://github.com/rust-lang/rust/issues/139812>.
+
+// Make sure that the unsize coercion we collect in mono for `Signal<i32> -> Signal<dyn Any>`
+// doesn't choke on the fact that the inner unsized field of `Signal<T>` is a (trivial) alias.
+// This exercises a normalize call that is necessary since we're getting a type from the type
+// system, which isn't guaranteed to be normalized after substitution.
+
+#![feature(coerce_unsized)]
+
+use std::ops::CoerceUnsized;
+
+trait Mirror {
+    type Assoc: ?Sized;
+}
+impl<T: ?Sized> Mirror for T {
+    type Assoc = T;
+}
+
+trait Any {}
+impl<T> Any for T {}
+
+struct Signal<'a, T: ?Sized>(<&'a T as Mirror>::Assoc);
+
+// This `CoerceUnsized` impl isn't special; it's a bit more restricted than we'd see in the wild,
+// but this ICE also reproduces if we were to make it general over `Signal<T> -> Signal<U>`.
+impl<'a> CoerceUnsized<Signal<'a, dyn Any>> for Signal<'a, i32> {}
+
+fn main() {
+    Signal(&1i32) as Signal<dyn Any>;
+}