diff options
Diffstat (limited to 'tests')
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() {} |
