summaryrefslogtreecommitdiffstats
path: root/tests/ui/transmute
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
commit218caa410aa38c29984be31a5229b9fa717560ee (patch)
treec54bd55eeb6e4c508940a30e94c0032fbd45d677 /tests/ui/transmute
parentReleasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz
rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/transmute')
-rw-r--r--tests/ui/transmute/lifetimes.rs23
-rw-r--r--tests/ui/transmute/main.rs29
-rw-r--r--tests/ui/transmute/main.stderr30
-rw-r--r--tests/ui/transmute/transmute-different-sizes.rs31
-rw-r--r--tests/ui/transmute/transmute-different-sizes.stderr30
-rw-r--r--tests/ui/transmute/transmute-fat-pointers.rs33
-rw-r--r--tests/ui/transmute/transmute-fat-pointers.stderr39
-rw-r--r--tests/ui/transmute/transmute-from-fn-item-types-error.rs60
-rw-r--r--tests/ui/transmute/transmute-from-fn-item-types-error.stderr92
-rw-r--r--tests/ui/transmute/transmute-impl.rs25
-rw-r--r--tests/ui/transmute/transmute-impl.stderr12
-rw-r--r--tests/ui/transmute/transmute-imut-to-mut.rs8
-rw-r--r--tests/ui/transmute/transmute-imut-to-mut.stderr10
-rw-r--r--tests/ui/transmute/transmute-padding-ice.rs29
-rw-r--r--tests/ui/transmute/transmute-padding-ice.stderr24
-rw-r--r--tests/ui/transmute/transmute-type-parameters.rs44
-rw-r--r--tests/ui/transmute/transmute-type-parameters.stderr57
17 files changed, 576 insertions, 0 deletions
diff --git a/tests/ui/transmute/lifetimes.rs b/tests/ui/transmute/lifetimes.rs
new file mode 100644
index 000000000..943191551
--- /dev/null
+++ b/tests/ui/transmute/lifetimes.rs
@@ -0,0 +1,23 @@
+// check-pass
+
+use std::ptr::NonNull;
+
+struct Foo<'a, T: ?Sized>(&'a (), NonNull<T>);
+
+fn foo<'a, 'b, T: ?Sized>(x: Foo<'a, T>) -> Foo<'b, T> {
+ unsafe { std::mem::transmute(x) }
+}
+
+struct Bar<'a, T: ?Sized>(&'a T);
+
+fn bar<'a, 'b, T: ?Sized>(x: Bar<'a, T>) -> Bar<'b, T> {
+ unsafe { std::mem::transmute(x) }
+}
+
+struct Boo<'a, T: ?Sized>(&'a T, u32);
+
+fn boo<'a, 'b, T: ?Sized>(x: Boo<'a, T>) -> Boo<'b, T> {
+ unsafe { std::mem::transmute(x) }
+}
+
+fn main() {}
diff --git a/tests/ui/transmute/main.rs b/tests/ui/transmute/main.rs
new file mode 100644
index 000000000..da4a0a660
--- /dev/null
+++ b/tests/ui/transmute/main.rs
@@ -0,0 +1,29 @@
+// normalize-stderr-32bit: "`&str` \(64 bits\)" -> "`&str` ($$STR bits)"
+// normalize-stderr-64bit: "`&str` \(128 bits\)" -> "`&str` ($$STR bits)"
+
+use std::mem::transmute;
+
+pub trait TypeConstructor<'a> {
+ type T;
+}
+
+unsafe fn transmute_lifetime<'a, 'b, C>(x: <C as TypeConstructor<'a>>::T)
+ -> <C as TypeConstructor<'b>>::T
+where for<'z> C: TypeConstructor<'z> {
+ transmute(x)
+}
+
+unsafe fn sizes() {
+ let x: u8 = transmute(10u16); //~ ERROR cannot transmute between types of different sizes
+}
+
+unsafe fn ptrs() {
+ let x: u8 = transmute("test"); //~ ERROR cannot transmute between types of different sizes
+}
+
+union Foo { x: () }
+unsafe fn vary() {
+ let x: Foo = transmute(10); //~ ERROR cannot transmute between types of different sizes
+}
+
+fn main() {}
diff --git a/tests/ui/transmute/main.stderr b/tests/ui/transmute/main.stderr
new file mode 100644
index 000000000..6cb0d7f67
--- /dev/null
+++ b/tests/ui/transmute/main.stderr
@@ -0,0 +1,30 @@
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/main.rs:17:17
+ |
+LL | let x: u8 = transmute(10u16);
+ | ^^^^^^^^^
+ |
+ = note: source type: `u16` (16 bits)
+ = note: target type: `u8` (8 bits)
+
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/main.rs:21:17
+ |
+LL | let x: u8 = transmute("test");
+ | ^^^^^^^^^
+ |
+ = note: source type: `&str` ($STR bits)
+ = note: target type: `u8` (8 bits)
+
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/main.rs:26:18
+ |
+LL | let x: Foo = transmute(10);
+ | ^^^^^^^^^
+ |
+ = note: source type: `i32` (32 bits)
+ = note: target type: `Foo` (0 bits)
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0512`.
diff --git a/tests/ui/transmute/transmute-different-sizes.rs b/tests/ui/transmute/transmute-different-sizes.rs
new file mode 100644
index 000000000..690decf63
--- /dev/null
+++ b/tests/ui/transmute/transmute-different-sizes.rs
@@ -0,0 +1,31 @@
+// normalize-stderr-test "\d+ bits" -> "N bits"
+
+// Tests that `transmute` cannot be called on types of different size.
+
+#![allow(warnings)]
+#![feature(specialization)]
+
+use std::mem::transmute;
+
+unsafe fn f() {
+ let _: i8 = transmute(16i16);
+ //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
+}
+
+unsafe fn g<T>(x: &T) {
+ let _: i8 = transmute(x);
+ //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
+}
+
+trait Specializable { type Output; }
+
+impl<T> Specializable for T {
+ default type Output = u16;
+}
+
+unsafe fn specializable<T>(x: u16) -> <T as Specializable>::Output {
+ transmute(x)
+ //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
+}
+
+fn main() {}
diff --git a/tests/ui/transmute/transmute-different-sizes.stderr b/tests/ui/transmute/transmute-different-sizes.stderr
new file mode 100644
index 000000000..07a38df69
--- /dev/null
+++ b/tests/ui/transmute/transmute-different-sizes.stderr
@@ -0,0 +1,30 @@
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/transmute-different-sizes.rs:11:17
+ |
+LL | let _: i8 = transmute(16i16);
+ | ^^^^^^^^^
+ |
+ = note: source type: `i16` (N bits)
+ = note: target type: `i8` (N bits)
+
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/transmute-different-sizes.rs:16:17
+ |
+LL | let _: i8 = transmute(x);
+ | ^^^^^^^^^
+ |
+ = note: source type: `&T` (N bits)
+ = note: target type: `i8` (N bits)
+
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/transmute-different-sizes.rs:27:5
+ |
+LL | transmute(x)
+ | ^^^^^^^^^
+ |
+ = note: source type: `u16` (N bits)
+ = note: target type: `<T as Specializable>::Output` (this type does not have a fixed size)
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0512`.
diff --git a/tests/ui/transmute/transmute-fat-pointers.rs b/tests/ui/transmute/transmute-fat-pointers.rs
new file mode 100644
index 000000000..7c1beffd1
--- /dev/null
+++ b/tests/ui/transmute/transmute-fat-pointers.rs
@@ -0,0 +1,33 @@
+// normalize-stderr-test "\d+ bits" -> "N bits"
+
+// Tests that are conservative around thin/fat pointer mismatches.
+
+#![allow(dead_code)]
+
+use std::mem::transmute;
+
+fn a<T, U: ?Sized>(x: &[T]) -> &U {
+ unsafe { transmute(x) } //~ ERROR cannot transmute between types of different sizes
+}
+
+fn b<T: ?Sized, U: ?Sized>(x: &T) -> &U {
+ unsafe { transmute(x) } //~ ERROR cannot transmute between types of different sizes
+}
+
+fn c<T, U>(x: &T) -> &U {
+ unsafe { transmute(x) }
+}
+
+fn d<T, U>(x: &[T]) -> &[U] {
+ unsafe { transmute(x) }
+}
+
+fn e<T: ?Sized, U>(x: &T) -> &U {
+ unsafe { transmute(x) } //~ ERROR cannot transmute between types of different sizes
+}
+
+fn f<T, U: ?Sized>(x: &T) -> &U {
+ unsafe { transmute(x) } //~ ERROR cannot transmute between types of different sizes
+}
+
+fn main() { }
diff --git a/tests/ui/transmute/transmute-fat-pointers.stderr b/tests/ui/transmute/transmute-fat-pointers.stderr
new file mode 100644
index 000000000..e8335fcbe
--- /dev/null
+++ b/tests/ui/transmute/transmute-fat-pointers.stderr
@@ -0,0 +1,39 @@
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/transmute-fat-pointers.rs:10:14
+ |
+LL | unsafe { transmute(x) }
+ | ^^^^^^^^^
+ |
+ = note: source type: `&[T]` (N bits)
+ = note: target type: `&U` (pointer to `U`)
+
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/transmute-fat-pointers.rs:14:14
+ |
+LL | unsafe { transmute(x) }
+ | ^^^^^^^^^
+ |
+ = note: source type: `&T` (pointer to `T`)
+ = note: target type: `&U` (pointer to `U`)
+
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/transmute-fat-pointers.rs:26:14
+ |
+LL | unsafe { transmute(x) }
+ | ^^^^^^^^^
+ |
+ = note: source type: `&T` (pointer to `T`)
+ = note: target type: `&U` (N bits)
+
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/transmute-fat-pointers.rs:30:14
+ |
+LL | unsafe { transmute(x) }
+ | ^^^^^^^^^
+ |
+ = note: source type: `&T` (N bits)
+ = note: target type: `&U` (pointer to `U`)
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0512`.
diff --git a/tests/ui/transmute/transmute-from-fn-item-types-error.rs b/tests/ui/transmute/transmute-from-fn-item-types-error.rs
new file mode 100644
index 000000000..f858a199e
--- /dev/null
+++ b/tests/ui/transmute/transmute-from-fn-item-types-error.rs
@@ -0,0 +1,60 @@
+use std::mem;
+
+unsafe fn foo() -> (i8, *const (), Option<fn()>) {
+ let i = mem::transmute(bar);
+ //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
+
+
+ let p = mem::transmute(foo);
+ //~^ ERROR can't transmute zero-sized type
+
+
+ let of = mem::transmute(main);
+ //~^ ERROR can't transmute zero-sized type
+
+
+ (i, p, of)
+}
+
+unsafe fn bar() {
+ // Error as usual if the resulting type is not pointer-sized.
+ mem::transmute::<_, u8>(main);
+ //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
+
+
+ mem::transmute::<_, *mut ()>(foo);
+ //~^ ERROR can't transmute zero-sized type
+
+
+ mem::transmute::<_, fn()>(bar);
+ //~^ ERROR can't transmute zero-sized type
+
+
+ // No error if a coercion would otherwise occur.
+ mem::transmute::<fn(), usize>(main);
+}
+
+unsafe fn baz() {
+ mem::transmute::<_, *mut ()>(Some(foo));
+ //~^ ERROR can't transmute zero-sized type
+
+
+ mem::transmute::<_, fn()>(Some(bar));
+ //~^ ERROR can't transmute zero-sized type
+
+
+ mem::transmute::<_, Option<fn()>>(Some(baz));
+ //~^ ERROR can't transmute zero-sized type
+
+
+ // No error if a coercion would otherwise occur.
+ mem::transmute::<Option<fn()>, usize>(Some(main));
+}
+
+fn main() {
+ unsafe {
+ foo();
+ bar();
+ baz();
+ }
+}
diff --git a/tests/ui/transmute/transmute-from-fn-item-types-error.stderr b/tests/ui/transmute/transmute-from-fn-item-types-error.stderr
new file mode 100644
index 000000000..aefe3fb8e
--- /dev/null
+++ b/tests/ui/transmute/transmute-from-fn-item-types-error.stderr
@@ -0,0 +1,92 @@
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/transmute-from-fn-item-types-error.rs:4:13
+ |
+LL | let i = mem::transmute(bar);
+ | ^^^^^^^^^^^^^^
+ |
+ = note: source type: `unsafe fn() {bar}` (0 bits)
+ = note: target type: `i8` (8 bits)
+
+error[E0591]: can't transmute zero-sized type
+ --> $DIR/transmute-from-fn-item-types-error.rs:8:13
+ |
+LL | let p = mem::transmute(foo);
+ | ^^^^^^^^^^^^^^
+ |
+ = note: source type: unsafe fn() -> (i8, *const (), Option<fn()>) {foo}
+ = note: target type: *const ()
+ = help: cast with `as` to a pointer instead
+
+error[E0591]: can't transmute zero-sized type
+ --> $DIR/transmute-from-fn-item-types-error.rs:12:14
+ |
+LL | let of = mem::transmute(main);
+ | ^^^^^^^^^^^^^^
+ |
+ = note: source type: fn() {main}
+ = note: target type: Option<fn()>
+ = help: cast with `as` to a pointer instead
+
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/transmute-from-fn-item-types-error.rs:21:5
+ |
+LL | mem::transmute::<_, u8>(main);
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: source type: `fn() {main}` (0 bits)
+ = note: target type: `u8` (8 bits)
+
+error[E0591]: can't transmute zero-sized type
+ --> $DIR/transmute-from-fn-item-types-error.rs:25:5
+ |
+LL | mem::transmute::<_, *mut ()>(foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: source type: unsafe fn() -> (i8, *const (), Option<fn()>) {foo}
+ = note: target type: *mut ()
+ = help: cast with `as` to a pointer instead
+
+error[E0591]: can't transmute zero-sized type
+ --> $DIR/transmute-from-fn-item-types-error.rs:29:5
+ |
+LL | mem::transmute::<_, fn()>(bar);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: source type: unsafe fn() {bar}
+ = note: target type: fn()
+ = help: cast with `as` to a pointer instead
+
+error[E0591]: can't transmute zero-sized type
+ --> $DIR/transmute-from-fn-item-types-error.rs:38:5
+ |
+LL | mem::transmute::<_, *mut ()>(Some(foo));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: source type: unsafe fn() -> (i8, *const (), Option<fn()>) {foo}
+ = note: target type: *mut ()
+ = help: cast with `as` to a pointer instead
+
+error[E0591]: can't transmute zero-sized type
+ --> $DIR/transmute-from-fn-item-types-error.rs:42:5
+ |
+LL | mem::transmute::<_, fn()>(Some(bar));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: source type: unsafe fn() {bar}
+ = note: target type: fn()
+ = help: cast with `as` to a pointer instead
+
+error[E0591]: can't transmute zero-sized type
+ --> $DIR/transmute-from-fn-item-types-error.rs:46:5
+ |
+LL | mem::transmute::<_, Option<fn()>>(Some(baz));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: source type: unsafe fn() {baz}
+ = note: target type: Option<fn()>
+ = help: cast with `as` to a pointer instead
+
+error: aborting due to 9 previous errors
+
+Some errors have detailed explanations: E0512, E0591.
+For more information about an error, try `rustc --explain E0512`.
diff --git a/tests/ui/transmute/transmute-impl.rs b/tests/ui/transmute/transmute-impl.rs
new file mode 100644
index 000000000..df422bda1
--- /dev/null
+++ b/tests/ui/transmute/transmute-impl.rs
@@ -0,0 +1,25 @@
+// normalize-stderr-test "\d+ bits" -> "N bits"
+
+// Tests that are conservative around thin/fat pointer mismatches.
+
+#![allow(dead_code)]
+
+use std::mem::transmute;
+
+struct Foo<T: ?Sized> {
+ t: Box<T>
+}
+
+impl<T: ?Sized> Foo<T> {
+ fn m(x: &T) -> &isize where T : Sized {
+ // OK here, because T : Sized is in scope.
+ unsafe { transmute(x) }
+ }
+
+ fn n(x: &T) -> &isize {
+ // Not OK here, because T : Sized is not in scope.
+ unsafe { transmute(x) } //~ ERROR cannot transmute between types of different sizes
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/transmute/transmute-impl.stderr b/tests/ui/transmute/transmute-impl.stderr
new file mode 100644
index 000000000..dd19bcd54
--- /dev/null
+++ b/tests/ui/transmute/transmute-impl.stderr
@@ -0,0 +1,12 @@
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/transmute-impl.rs:21:18
+ |
+LL | unsafe { transmute(x) }
+ | ^^^^^^^^^
+ |
+ = note: source type: `&T` (pointer to `T`)
+ = note: target type: `&isize` (N bits)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0512`.
diff --git a/tests/ui/transmute/transmute-imut-to-mut.rs b/tests/ui/transmute/transmute-imut-to-mut.rs
new file mode 100644
index 000000000..9f3f76c1e
--- /dev/null
+++ b/tests/ui/transmute/transmute-imut-to-mut.rs
@@ -0,0 +1,8 @@
+// Tests that transmuting from &T to &mut T is Undefined Behavior.
+
+use std::mem::transmute;
+
+fn main() {
+ let _a: &mut u8 = unsafe { transmute(&1u8) };
+ //~^ ERROR transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell
+}
diff --git a/tests/ui/transmute/transmute-imut-to-mut.stderr b/tests/ui/transmute/transmute-imut-to-mut.stderr
new file mode 100644
index 000000000..1e9dff3ce
--- /dev/null
+++ b/tests/ui/transmute/transmute-imut-to-mut.stderr
@@ -0,0 +1,10 @@
+error: transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell
+ --> $DIR/transmute-imut-to-mut.rs:6:32
+ |
+LL | let _a: &mut u8 = unsafe { transmute(&1u8) };
+ | ^^^^^^^^^
+ |
+ = note: `#[deny(mutable_transmutes)]` on by default
+
+error: aborting due to previous error
+
diff --git a/tests/ui/transmute/transmute-padding-ice.rs b/tests/ui/transmute/transmute-padding-ice.rs
new file mode 100644
index 000000000..a1be7075a
--- /dev/null
+++ b/tests/ui/transmute/transmute-padding-ice.rs
@@ -0,0 +1,29 @@
+#![crate_type = "lib"]
+#![feature(transmutability)]
+#![allow(dead_code)]
+
+mod assert {
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
+ pub struct Context;
+
+ pub fn is_maybe_transmutable<Src, Dst>()
+ where
+ Dst: BikeshedIntrinsicFrom<
+ Src,
+ Context,
+ { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
+ >,
+ {
+ }
+}
+
+fn test() {
+ #[repr(C, align(2))]
+ struct A(u8, u8);
+
+ #[repr(C)]
+ struct B(u8, u8);
+
+ assert::is_maybe_transmutable::<B, A>();
+ //~^ ERROR cannot be safely transmuted
+}
diff --git a/tests/ui/transmute/transmute-padding-ice.stderr b/tests/ui/transmute/transmute-padding-ice.stderr
new file mode 100644
index 000000000..c9233890f
--- /dev/null
+++ b/tests/ui/transmute/transmute-padding-ice.stderr
@@ -0,0 +1,24 @@
+error[E0277]: `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`.
+ --> $DIR/transmute-padding-ice.rs:27:40
+ |
+LL | assert::is_maybe_transmutable::<B, A>();
+ | ^ `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`.
+ |
+ = help: the trait `BikeshedIntrinsicFrom<B, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `A`
+note: required by a bound in `is_maybe_transmutable`
+ --> $DIR/transmute-padding-ice.rs:11:14
+ |
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<
+ | ______________^
+LL | | Src,
+LL | | Context,
+LL | | { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
+LL | | >,
+ | |_________^ required by this bound in `is_maybe_transmutable`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/transmute/transmute-type-parameters.rs b/tests/ui/transmute/transmute-type-parameters.rs
new file mode 100644
index 000000000..5f44b2d0f
--- /dev/null
+++ b/tests/ui/transmute/transmute-type-parameters.rs
@@ -0,0 +1,44 @@
+// Tests that `transmute` cannot be called on type parameters.
+
+use std::mem::transmute;
+
+unsafe fn f<T>(x: T) {
+ let _: i32 = transmute(x);
+//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
+}
+
+unsafe fn g<T>(x: (T, i32)) {
+ let _: i32 = transmute(x);
+//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
+}
+
+unsafe fn h<T>(x: [T; 10]) {
+ let _: i32 = transmute(x);
+//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
+}
+
+struct Bad<T> {
+ f: T,
+}
+
+unsafe fn i<T>(x: Bad<T>) {
+ let _: i32 = transmute(x);
+//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
+}
+
+enum Worse<T> {
+ A(T),
+ B,
+}
+
+unsafe fn j<T>(x: Worse<T>) {
+ let _: i32 = transmute(x);
+//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
+}
+
+unsafe fn k<T>(x: Option<T>) {
+ let _: i32 = transmute(x);
+//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
+}
+
+fn main() {}
diff --git a/tests/ui/transmute/transmute-type-parameters.stderr b/tests/ui/transmute/transmute-type-parameters.stderr
new file mode 100644
index 000000000..220b929d4
--- /dev/null
+++ b/tests/ui/transmute/transmute-type-parameters.stderr
@@ -0,0 +1,57 @@
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/transmute-type-parameters.rs:6:18
+ |
+LL | let _: i32 = transmute(x);
+ | ^^^^^^^^^
+ |
+ = note: source type: `T` (this type does not have a fixed size)
+ = note: target type: `i32` (32 bits)
+
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/transmute-type-parameters.rs:11:18
+ |
+LL | let _: i32 = transmute(x);
+ | ^^^^^^^^^
+ |
+ = note: source type: `(T, i32)` (size can vary because of T)
+ = note: target type: `i32` (32 bits)
+
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/transmute-type-parameters.rs:16:18
+ |
+LL | let _: i32 = transmute(x);
+ | ^^^^^^^^^
+ |
+ = note: source type: `[T; 10]` (size can vary because of T)
+ = note: target type: `i32` (32 bits)
+
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/transmute-type-parameters.rs:25:18
+ |
+LL | let _: i32 = transmute(x);
+ | ^^^^^^^^^
+ |
+ = note: source type: `Bad<T>` (size can vary because of T)
+ = note: target type: `i32` (32 bits)
+
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/transmute-type-parameters.rs:35:18
+ |
+LL | let _: i32 = transmute(x);
+ | ^^^^^^^^^
+ |
+ = note: source type: `Worse<T>` (size can vary because of T)
+ = note: target type: `i32` (32 bits)
+
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/transmute-type-parameters.rs:40:18
+ |
+LL | let _: i32 = transmute(x);
+ | ^^^^^^^^^
+ |
+ = note: source type: `Option<T>` (size can vary because of T)
+ = note: target type: `i32` (32 bits)
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0512`.