about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/invalid_dispatch_from_dyn_impls.stderr4
-rw-r--r--tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.rs25
-rw-r--r--tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.stderr16
-rw-r--r--tests/ui/self/dispatch-from-dyn-zst-transmute.rs34
-rw-r--r--tests/ui/self/dispatch-from-dyn-zst-transmute.stderr16
-rw-r--r--tests/ui/self/phantomdata-in-coerce-and-dispatch-impls.rs25
6 files changed, 118 insertions, 2 deletions
diff --git a/tests/ui/invalid_dispatch_from_dyn_impls.stderr b/tests/ui/invalid_dispatch_from_dyn_impls.stderr
index 168ed37d0e6..02718334c73 100644
--- a/tests/ui/invalid_dispatch_from_dyn_impls.stderr
+++ b/tests/ui/invalid_dispatch_from_dyn_impls.stderr
@@ -1,4 +1,4 @@
-error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment, and nothing else
+error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else
   --> $DIR/invalid_dispatch_from_dyn_impls.rs:10:1
    |
 LL | / impl<T, U> DispatchFromDyn<WrapperWithExtraField<U>> for WrapperWithExtraField<T>
@@ -35,7 +35,7 @@ LL | | where
 LL | |     T: Unsize<U>,
    | |_________________^
 
-error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment, and nothing else
+error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else
   --> $DIR/invalid_dispatch_from_dyn_impls.rs:46:1
    |
 LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<OverAligned<U>> for OverAligned<T>
diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.rs b/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.rs
new file mode 100644
index 00000000000..71f198f7dc7
--- /dev/null
+++ b/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.rs
@@ -0,0 +1,25 @@
+// We used to allow erroneous `DispatchFromDyn` impls whose RHS type contained
+// fields that weren't ZSTs. I don't believe this was possible to abuse, but
+// it's at least nice to give users better errors.
+
+#![feature(arbitrary_self_types)]
+#![feature(unsize)]
+#![feature(dispatch_from_dyn)]
+
+use std::marker::Unsize;
+use std::ops::DispatchFromDyn;
+
+struct Dispatchable<T: ?Sized, Z> {
+    _ptr: Box<T>,
+    z: Z,
+}
+
+impl<T, U> DispatchFromDyn<Dispatchable<U, i32>> for Dispatchable<T, ()>
+//~^ ERROR implementing the `DispatchFromDyn` trait requires multiple coercions
+where
+    T: Unsize<U> + ?Sized,
+    U: ?Sized,
+{
+}
+
+fn main() {}
diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.stderr b/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.stderr
new file mode 100644
index 00000000000..1f13c51f679
--- /dev/null
+++ b/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.stderr
@@ -0,0 +1,16 @@
+error[E0378]: implementing the `DispatchFromDyn` trait requires multiple coercions
+  --> $DIR/dispatch-from-dyn-zst-transmute-zst-nonzst.rs:17:1
+   |
+LL | / impl<T, U> DispatchFromDyn<Dispatchable<U, i32>> for Dispatchable<T, ()>
+LL | |
+LL | | where
+LL | |     T: Unsize<U> + ?Sized,
+LL | |     U: ?Sized,
+   | |______________^
+   |
+   = note: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced
+   = note: currently, 2 fields need coercions: `_ptr` (`Box<T>` to `Box<U>`), `z` (`()` to `i32`)
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0378`.
diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute.rs b/tests/ui/self/dispatch-from-dyn-zst-transmute.rs
new file mode 100644
index 00000000000..57c255b4d7b
--- /dev/null
+++ b/tests/ui/self/dispatch-from-dyn-zst-transmute.rs
@@ -0,0 +1,34 @@
+#![feature(arbitrary_self_types)]
+#![feature(unsize)]
+#![feature(dispatch_from_dyn)]
+
+use std::marker::PhantomData;
+use std::marker::Unsize;
+use std::ops::DispatchFromDyn;
+use std::ops::Deref;
+
+struct IsSendToken<T: ?Sized>(PhantomData<fn(T) -> T>);
+
+struct Foo<'a, U: ?Sized> {
+    token: IsSendToken<U>,
+    ptr: &'a U,
+}
+
+impl<'a, T, U> DispatchFromDyn<Foo<'a, U>> for Foo<'a, T>
+//~^ ERROR implementing the `DispatchFromDyn` trait requires multiple coercions
+where
+    T: Unsize<U> + ?Sized,
+    U: ?Sized {}
+
+trait Bar {
+    fn f(self: Foo<'_, Self>);
+}
+
+impl<U: ?Sized> Deref for Foo<'_, U> {
+    type Target = U;
+    fn deref(&self) -> &U {
+        self.ptr
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute.stderr b/tests/ui/self/dispatch-from-dyn-zst-transmute.stderr
new file mode 100644
index 00000000000..5a8ae88b5f1
--- /dev/null
+++ b/tests/ui/self/dispatch-from-dyn-zst-transmute.stderr
@@ -0,0 +1,16 @@
+error[E0378]: implementing the `DispatchFromDyn` trait requires multiple coercions
+  --> $DIR/dispatch-from-dyn-zst-transmute.rs:17:1
+   |
+LL | / impl<'a, T, U> DispatchFromDyn<Foo<'a, U>> for Foo<'a, T>
+LL | |
+LL | | where
+LL | |     T: Unsize<U> + ?Sized,
+LL | |     U: ?Sized {}
+   | |_____________^
+   |
+   = note: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced
+   = note: currently, 2 fields need coercions: `token` (`IsSendToken<T>` to `IsSendToken<U>`), `ptr` (`&'a T` to `&'a U`)
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0378`.
diff --git a/tests/ui/self/phantomdata-in-coerce-and-dispatch-impls.rs b/tests/ui/self/phantomdata-in-coerce-and-dispatch-impls.rs
new file mode 100644
index 00000000000..9c7e33830f5
--- /dev/null
+++ b/tests/ui/self/phantomdata-in-coerce-and-dispatch-impls.rs
@@ -0,0 +1,25 @@
+//@ check-pass
+
+#![feature(coerce_unsized, dispatch_from_dyn, unsize)]
+
+use std::marker::Unsize;
+use std::ops::{CoerceUnsized, DispatchFromDyn};
+use std::marker::PhantomData;
+
+trait Mirror {
+    type Assoc;
+}
+impl<T> Mirror for T {
+    type Assoc = T;
+}
+
+struct W<T: 'static> {
+    t: &'static T,
+    f: <PhantomData<T> as Mirror>::Assoc,
+}
+
+impl<T, U> CoerceUnsized<W<U>> for W<T> where T: Unsize<U> {}
+
+impl<T, U> DispatchFromDyn<W<U>> for W<T> where T: Unsize<U> {}
+
+fn main() {}