diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs new file mode 100644 index 00000000000..2e5a9d0d3b5 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs @@ -0,0 +1,40 @@ +// Combination of `ptr-to-trait-obj-wrap.rs` and `ptr-to-trait-obj-add-auto.rs`. +// +// Checks that you *can't* add auto traits to trait object in pointer casts involving wrapping said +// traits structures. + +trait A {} + +struct W(T); +struct X(T); + +fn unwrap(a: *const W) -> *const (dyn A + Send) { + a as _ + //~^ error + //~| error + //~| error +} + +fn unwrap_nested(a: *const W>) -> *const W { + a as _ + //~^ error + //~| error + //~| error +} + +fn rewrap(a: *const W) -> *const X { + a as _ + //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast +} + +fn rewrap_nested(a: *const W>) -> *const W> { + a as _ + //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast +} + +fn wrap(a: *const dyn A) -> *const W { + a as _ + //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr new file mode 100644 index 00000000000..00a27156f07 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr @@ -0,0 +1,113 @@ +error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:12:5 + | +LL | a as _ + | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` + | +help: this trait has no implementations, consider adding one + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:6:1 + | +LL | trait A {} + | ^^^^^^^ + = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A + Send` + +error[E0277]: `(dyn A + 'static)` cannot be sent between threads safely + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:12:5 + | +LL | a as _ + | ^ `(dyn A + 'static)` cannot be sent between threads safely + | + = help: within `W<(dyn A + 'static)>`, the trait `Send` is not implemented for `(dyn A + 'static)` +note: required because it appears within the type `W<(dyn A + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:8:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A + Send` + +error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:12:5 + | +LL | a as _ + | ^ doesn't have a size known at compile-time + | + = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` +note: required because it appears within the type `W<(dyn A + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:8:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A + Send` + +error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:19:5 + | +LL | a as _ + | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` + | +help: this trait has no implementations, consider adding one + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:6:1 + | +LL | trait A {} + | ^^^^^^^ + = note: required for the cast from `*const W>` to `*const W` + +error[E0277]: `(dyn A + 'static)` cannot be sent between threads safely + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:19:5 + | +LL | a as _ + | ^ `(dyn A + 'static)` cannot be sent between threads safely + | + = help: within `W<(dyn A + 'static)>`, the trait `Send` is not implemented for `(dyn A + 'static)` +note: required because it appears within the type `W<(dyn A + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:8:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W>` to `*const W` + +error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:19:5 + | +LL | a as _ + | ^ doesn't have a size known at compile-time + | + = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` +note: required because it appears within the type `W<(dyn A + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:8:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W>` to `*const W` + +error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:26:5 + | +LL | a as _ + | ^^^^^^ unsupported cast + | + = note: this could allow UB elsewhere + = help: use `transmute` if you're sure this is sound + +error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:31:5 + | +LL | a as _ + | ^^^^^^ unsupported cast + | + = note: this could allow UB elsewhere + = help: use `transmute` if you're sure this is sound + +error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:36:5 + | +LL | a as _ + | ^^^^^^ unsupported cast + | + = note: this could allow UB elsewhere + = help: use `transmute` if you're sure this is sound + +error: aborting due to 9 previous errors + +Some errors have detailed explanations: E0277, E0804. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs new file mode 100644 index 00000000000..55dc0aa184d --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs @@ -0,0 +1,38 @@ +// Combination of `ptr-to-trait-obj-different-args.rs` and `ptr-to-trait-obj-wrap.rs`. +// +// Checks that you *can't* change type arguments of trait objects in pointer casts involving +// wrapping said traits structures. + +trait A {} + +struct W(T); +struct X(T); + +fn unwrap(a: *const W>) -> *const dyn A { + a as _ + //~^ error + //~| error +} + +fn unwrap_nested(a: *const W>>) -> *const W> { + a as _ + //~^ error + //~| error +} + +fn rewrap(a: *const W>) -> *const X> { + a as _ + //~^ error: casting `*const W<(dyn A + 'static)>` as `*const X>` is invalid +} + +fn rewrap_nested(a: *const W>>) -> *const W>> { + a as _ + //~^ error: casting `*const W + 'static)>>` as `*const W>>` is invalid +} + +fn wrap(a: *const dyn A) -> *const W> { + a as _ + //~^ error: casting `*const (dyn A + 'static)` as `*const W>` is invalid +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr new file mode 100644 index 00000000000..59543229de7 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr @@ -0,0 +1,82 @@ +error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:12:5 + | +LL | a as _ + | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` + | +help: this trait has no implementations, consider adding one + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:6:1 + | +LL | trait A {} + | ^^^^^^^^^^ + = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A` + +error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:12:5 + | +LL | a as _ + | ^ doesn't have a size known at compile-time + | + = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` +note: required because it appears within the type `W<(dyn A + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:8:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A` + +error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:18:5 + | +LL | a as _ + | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` + | +help: this trait has no implementations, consider adding one + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:6:1 + | +LL | trait A {} + | ^^^^^^^^^^ + = note: required for the cast from `*const W + 'static)>>` to `*const W>` + +error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:18:5 + | +LL | a as _ + | ^ doesn't have a size known at compile-time + | + = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` +note: required because it appears within the type `W<(dyn A + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:8:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W + 'static)>>` to `*const W>` + +error[E0606]: casting `*const W<(dyn A + 'static)>` as `*const X>` is invalid + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:24:5 + | +LL | a as _ + | ^^^^^^ + | + = note: the trait objects may have different vtables + +error[E0606]: casting `*const W + 'static)>>` as `*const W>>` is invalid + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:29:5 + | +LL | a as _ + | ^^^^^^ + | + = note: the trait objects may have different vtables + +error[E0606]: casting `*const (dyn A + 'static)` as `*const W>` is invalid + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:34:5 + | +LL | a as _ + | ^^^^^^ + | + = note: the trait objects may have different vtables + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0277, E0606. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.rs b/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.rs new file mode 100644 index 00000000000..b0941277d01 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.rs @@ -0,0 +1,41 @@ +// Combination of `ptr-to-trait-obj-different-regions-misc.rs` and `ptr-to-trait-obj-wrap.rs`. +// +// Checks that you *can't* change lifetime arguments of trait objects in pointer casts involving +// wrapping said traits structures. + +trait A<'a> {} + +struct W(T); +struct X(T); + +fn unwrap<'a, 'b>(a: *const W>) -> *const dyn A<'b> { + a as _ + //~^ error + //~| error +} + +fn unwrap_nested<'a, 'b>(a: *const W>>) -> *const W> { + a as _ + //~^ error + //~| error +} + +fn rewrap<'a, 'b>(a: *const W>) -> *const X> { + a as _ + //~^ error: lifetime may not live long enough + //~| error: lifetime may not live long enough +} + +fn rewrap_nested<'a, 'b>(a: *const W>>) -> *const W>> { + a as _ + //~^ error: lifetime may not live long enough + //~| error: lifetime may not live long enough +} + +fn wrap<'a, 'b>(a: *const dyn A<'a>) -> *const W> { + a as _ + //~^ error: lifetime may not live long enough + //~| error: lifetime may not live long enough +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr new file mode 100644 index 00000000000..3d5fafea2ee --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr @@ -0,0 +1,139 @@ +error[E0277]: the trait bound `W<(dyn A<'a> + 'static)>: A<'b>` is not satisfied + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:12:5 + | +LL | a as _ + | ^ the trait `A<'b>` is not implemented for `W<(dyn A<'a> + 'static)>` + | +help: this trait has no implementations, consider adding one + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:6:1 + | +LL | trait A<'a> {} + | ^^^^^^^^^^^ + = note: required for the cast from `*const W<(dyn A<'a> + 'static)>` to `*const dyn A<'b>` + +error[E0277]: the size for values of type `(dyn A<'a> + 'static)` cannot be known at compilation time + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:12:5 + | +LL | a as _ + | ^ doesn't have a size known at compile-time + | + = help: within `W<(dyn A<'a> + 'static)>`, the trait `Sized` is not implemented for `(dyn A<'a> + 'static)` +note: required because it appears within the type `W<(dyn A<'a> + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:8:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W<(dyn A<'a> + 'static)>` to `*const dyn A<'b>` + +error[E0277]: the trait bound `W<(dyn A<'a> + 'static)>: A<'b>` is not satisfied + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:18:5 + | +LL | a as _ + | ^ the trait `A<'b>` is not implemented for `W<(dyn A<'a> + 'static)>` + | +help: this trait has no implementations, consider adding one + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:6:1 + | +LL | trait A<'a> {} + | ^^^^^^^^^^^ + = note: required for the cast from `*const W + 'static)>>` to `*const W>` + +error[E0277]: the size for values of type `(dyn A<'a> + 'static)` cannot be known at compilation time + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:18:5 + | +LL | a as _ + | ^ doesn't have a size known at compile-time + | + = help: within `W<(dyn A<'a> + 'static)>`, the trait `Sized` is not implemented for `(dyn A<'a> + 'static)` +note: required because it appears within the type `W<(dyn A<'a> + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:8:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W + 'static)>>` to `*const W>` + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:24:5 + | +LL | fn rewrap<'a, 'b>(a: *const W>) -> *const X> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | a as _ + | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | + = help: consider adding the following bound: `'b: 'a` + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:24:5 + | +LL | fn rewrap<'a, 'b>(a: *const W>) -> *const X> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | a as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + +help: `'b` and `'a` must be the same: replace one with the other + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:30:5 + | +LL | fn rewrap_nested<'a, 'b>(a: *const W>>) -> *const W>> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | a as _ + | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | + = help: consider adding the following bound: `'b: 'a` + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:30:5 + | +LL | fn rewrap_nested<'a, 'b>(a: *const W>>) -> *const W>> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | a as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + +help: `'b` and `'a` must be the same: replace one with the other + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:36:5 + | +LL | fn wrap<'a, 'b>(a: *const dyn A<'a>) -> *const W> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | a as _ + | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | + = help: consider adding the following bound: `'b: 'a` + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:36:5 + | +LL | fn wrap<'a, 'b>(a: *const dyn A<'a>) -> *const W> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | a as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + +help: `'b` and `'a` must be the same: replace one with the other + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 10 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap.rs b/tests/ui/cast/ptr-to-trait-obj-wrap.rs new file mode 100644 index 00000000000..f45cedcab72 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap.rs @@ -0,0 +1,36 @@ +// Checks that various casts of pointers to trait objects wrapped in structures +// work. Note that the metadata doesn't change when a DST is wrapped in a +// structure, so these casts *are* fine. +// +// `unwrap` and `unwrap_nested` currently don't work due to a compiler limitation. + +trait A {} + +struct W(T); +struct X(T); + +fn unwrap(a: *const W) -> *const dyn A { + a as _ + //~^ error + //~| error +} + +fn unwrap_nested(a: *const W>) -> *const W { + a as _ + //~^ error + //~| error +} + +fn rewrap(a: *const W) -> *const X { + a as _ +} + +fn rewrap_nested(a: *const W>) -> *const W> { + a as _ +} + +fn wrap(a: *const dyn A) -> *const W { + a as _ +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap.stderr new file mode 100644 index 00000000000..3003363c04a --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap.stderr @@ -0,0 +1,57 @@ +error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied + --> $DIR/ptr-to-trait-obj-wrap.rs:13:5 + | +LL | a as _ + | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` + | +help: this trait has no implementations, consider adding one + --> $DIR/ptr-to-trait-obj-wrap.rs:7:1 + | +LL | trait A {} + | ^^^^^^^ + = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A` + +error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time + --> $DIR/ptr-to-trait-obj-wrap.rs:13:5 + | +LL | a as _ + | ^ doesn't have a size known at compile-time + | + = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` +note: required because it appears within the type `W<(dyn A + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap.rs:9:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A` + +error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied + --> $DIR/ptr-to-trait-obj-wrap.rs:19:5 + | +LL | a as _ + | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` + | +help: this trait has no implementations, consider adding one + --> $DIR/ptr-to-trait-obj-wrap.rs:7:1 + | +LL | trait A {} + | ^^^^^^^ + = note: required for the cast from `*const W>` to `*const W` + +error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time + --> $DIR/ptr-to-trait-obj-wrap.rs:19:5 + | +LL | a as _ + | ^ doesn't have a size known at compile-time + | + = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` +note: required because it appears within the type `W<(dyn A + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap.rs:9:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W>` to `*const W` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`.