about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs40
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr113
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs38
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr82
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.rs41
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr139
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap.rs36
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap.stderr57
8 files changed, 546 insertions, 0 deletions
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: ?Sized>(T);
+struct X<T: ?Sized>(T);
+
+fn unwrap(a: *const W<dyn A>) -> *const (dyn A + Send) {
+    a as _
+    //~^ error
+    //~| error
+    //~| error
+}
+
+fn unwrap_nested(a: *const W<W<dyn A>>) -> *const W<dyn A + Send> {
+    a as _
+    //~^ error
+    //~| error
+    //~| error
+}
+
+fn rewrap(a: *const W<dyn A>) -> *const X<dyn A + Send> {
+    a as _
+    //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast
+}
+
+fn rewrap_nested(a: *const W<W<dyn A>>) -> *const W<X<dyn A + Send>> {
+    a as _
+    //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast
+}
+
+fn wrap(a: *const dyn A) -> *const W<dyn A + Send> {
+    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: ?Sized>(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: ?Sized>(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<W<(dyn A + 'static)>>` to `*const W<dyn A + Send>`
+
+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: ?Sized>(T);
+   |        ^
+   = note: required for the cast from `*const W<W<(dyn A + 'static)>>` to `*const W<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: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: ?Sized>(T);
+   |        ^
+   = note: required for the cast from `*const W<W<(dyn A + 'static)>>` to `*const W<dyn A + Send>`
+
+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<T> {}
+
+struct W<T: ?Sized>(T);
+struct X<T: ?Sized>(T);
+
+fn unwrap<F, G>(a: *const W<dyn A<F>>) -> *const dyn A<G> {
+    a as _
+    //~^ error
+    //~| error
+}
+
+fn unwrap_nested<F, G>(a: *const W<W<dyn A<F>>>) -> *const W<dyn A<G>> {
+    a as _
+    //~^ error
+    //~| error
+}
+
+fn rewrap<F, G>(a: *const W<dyn A<F>>) -> *const X<dyn A<G>> {
+    a as _
+    //~^ error: casting `*const W<(dyn A<F> + 'static)>` as `*const X<dyn A<G>>` is invalid
+}
+
+fn rewrap_nested<F, G>(a: *const W<W<dyn A<F>>>) -> *const W<X<dyn A<G>>> {
+    a as _
+    //~^ error: casting `*const W<W<(dyn A<F> + 'static)>>` as `*const W<X<dyn A<G>>>` is invalid
+}
+
+fn wrap<F, G>(a: *const dyn A<F>) -> *const W<dyn A<G>> {
+    a as _
+    //~^ error: casting `*const (dyn A<F> + 'static)` as `*const W<dyn A<G>>` 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<F> + 'static)>: A<G>` is not satisfied
+  --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:12:5
+   |
+LL |     a as _
+   |     ^ the trait `A<G>` is not implemented for `W<(dyn A<F> + 'static)>`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:6:1
+   |
+LL | trait A<T> {}
+   | ^^^^^^^^^^
+   = note: required for the cast from `*const W<(dyn A<F> + 'static)>` to `*const dyn A<G>`
+
+error[E0277]: the size for values of type `(dyn A<F> + '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<F> + 'static)>`, the trait `Sized` is not implemented for `(dyn A<F> + 'static)`
+note: required because it appears within the type `W<(dyn A<F> + 'static)>`
+  --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:8:8
+   |
+LL | struct W<T: ?Sized>(T);
+   |        ^
+   = note: required for the cast from `*const W<(dyn A<F> + 'static)>` to `*const dyn A<G>`
+
+error[E0277]: the trait bound `W<(dyn A<F> + 'static)>: A<G>` is not satisfied
+  --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:18:5
+   |
+LL |     a as _
+   |     ^ the trait `A<G>` is not implemented for `W<(dyn A<F> + 'static)>`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:6:1
+   |
+LL | trait A<T> {}
+   | ^^^^^^^^^^
+   = note: required for the cast from `*const W<W<(dyn A<F> + 'static)>>` to `*const W<dyn A<G>>`
+
+error[E0277]: the size for values of type `(dyn A<F> + '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<F> + 'static)>`, the trait `Sized` is not implemented for `(dyn A<F> + 'static)`
+note: required because it appears within the type `W<(dyn A<F> + 'static)>`
+  --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:8:8
+   |
+LL | struct W<T: ?Sized>(T);
+   |        ^
+   = note: required for the cast from `*const W<W<(dyn A<F> + 'static)>>` to `*const W<dyn A<G>>`
+
+error[E0606]: casting `*const W<(dyn A<F> + 'static)>` as `*const X<dyn A<G>>` 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<W<(dyn A<F> + 'static)>>` as `*const W<X<dyn A<G>>>` 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<F> + 'static)` as `*const W<dyn A<G>>` 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: ?Sized>(T);
+struct X<T: ?Sized>(T);
+
+fn unwrap<'a, 'b>(a: *const W<dyn A<'a>>) -> *const dyn A<'b> {
+    a as _
+    //~^ error
+    //~| error
+}
+
+fn unwrap_nested<'a, 'b>(a: *const W<W<dyn A<'a>>>) -> *const W<dyn A<'b>> {
+    a as _
+    //~^ error
+    //~| error
+}
+
+fn rewrap<'a, 'b>(a: *const W<dyn A<'a>>) -> *const X<dyn A<'b>> {
+    a as _
+    //~^ error: lifetime may not live long enough
+    //~| error: lifetime may not live long enough
+}
+
+fn rewrap_nested<'a, 'b>(a: *const W<W<dyn A<'a>>>) -> *const W<X<dyn A<'b>>> {
+    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<dyn A<'b>> {
+    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: ?Sized>(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<W<(dyn A<'a> + 'static)>>` to `*const W<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: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: ?Sized>(T);
+   |        ^
+   = note: required for the cast from `*const W<W<(dyn A<'a> + 'static)>>` to `*const W<dyn A<'b>>`
+
+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<dyn A<'a>>) -> *const X<dyn A<'b>> {
+   |           --  -- 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<dyn A<'a>>) -> *const X<dyn A<'b>> {
+   |           --  -- 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<W<dyn A<'a>>>) -> *const W<X<dyn A<'b>>> {
+   |                  --  -- 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<W<dyn A<'a>>>) -> *const W<X<dyn A<'b>>> {
+   |                  --  -- 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<dyn A<'b>> {
+   |         --  -- 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<dyn A<'b>> {
+   |         --  -- 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: ?Sized>(T);
+struct X<T: ?Sized>(T);
+
+fn unwrap(a: *const W<dyn A>) -> *const dyn A {
+    a as _
+    //~^ error
+    //~| error
+}
+
+fn unwrap_nested(a: *const W<W<dyn A>>) -> *const W<dyn A> {
+    a as _
+    //~^ error
+    //~| error
+}
+
+fn rewrap(a: *const W<dyn A>) -> *const X<dyn A> {
+    a as _
+}
+
+fn rewrap_nested(a: *const W<W<dyn A>>) -> *const W<X<dyn A>> {
+    a as _
+}
+
+fn wrap(a: *const dyn A) -> *const W<dyn A> {
+    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: ?Sized>(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<W<(dyn A + 'static)>>` to `*const W<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: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: ?Sized>(T);
+   |        ^
+   = note: required for the cast from `*const W<W<(dyn A + 'static)>>` to `*const W<dyn A>`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.