]> git.lizzy.rs Git - rust.git/commitdiff
Update transmute size lints.
authorMark Simulacrum <mark.simulacrum@gmail.com>
Mon, 29 May 2017 23:22:41 +0000 (17:22 -0600)
committerMark Simulacrum <mark.simulacrum@gmail.com>
Sun, 18 Jun 2017 16:36:07 +0000 (10:36 -0600)
Also moves a few transmute tests to UI tests to better test their
output.

19 files changed:
src/librustc/diagnostics.rs
src/librustc/middle/intrinsicck.rs
src/test/compile-fail/E0512.rs
src/test/compile-fail/issue-21174.rs
src/test/compile-fail/issue-28625.rs
src/test/compile-fail/issue-32377.rs
src/test/compile-fail/packed-struct-generic-transmute.rs
src/test/compile-fail/packed-struct-transmute.rs
src/test/compile-fail/transmute-different-sizes.rs
src/test/compile-fail/transmute-fat-pointers.rs
src/test/compile-fail/transmute-from-fn-item-types-error.rs [deleted file]
src/test/compile-fail/transmute-impl.rs
src/test/compile-fail/transmute-type-parameters.rs [deleted file]
src/test/ui/transmute/main.rs [new file with mode: 0644]
src/test/ui/transmute/main.stderr [new file with mode: 0644]
src/test/ui/transmute/transmute-from-fn-item-types-error.rs [new file with mode: 0644]
src/test/ui/transmute/transmute-from-fn-item-types-error.stderr [new file with mode: 0644]
src/test/ui/transmute/transmute-type-parameters.rs [new file with mode: 0644]
src/test/ui/transmute/transmute-type-parameters.stderr [new file with mode: 0644]

index 28fb96aa203242834cff1125c5bee3dd041c2632..4d378b0bf7dd3ae9596b2f678ddf260165b9d811 100644 (file)
@@ -1631,7 +1631,7 @@ fn takes_u8(_: u8) {}
 
 fn main() {
     unsafe { takes_u8(::std::mem::transmute(0u16)); }
-    // error: transmute called with differently sized types
+    // error: transmute called with types of different sizes
 }
 ```
 
index 57815b7f0b690b68cc85a0b3aaffb28cdec53fce..de92395ac6955b316ec88640d16f01af490baf42 100644 (file)
@@ -86,17 +86,16 @@ fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) {
             // Special-case transmutting from `typeof(function)` and
             // `Option<typeof(function)>` to present a clearer error.
             let from = unpack_option_like(self.tcx.global_tcx(), from);
-            match (&from.sty, sk_to) {
-                (&ty::TyFnDef(..), SizeSkeleton::Known(size_to))
-                        if size_to == Pointer.size(self.tcx) => {
+            if let (&ty::TyFnDef(..), SizeSkeleton::Known(size_to)) = (&from.sty, sk_to) {
+                if size_to == Pointer.size(self.tcx) => {
                     struct_span_err!(self.tcx.sess, span, E0591,
-                                     "`{}` is zero-sized and can't be transmuted to `{}`",
-                                     from, to)
-                        .span_note(span, "cast with `as` to a pointer instead")
+                                     "can't transmute zero-sized type")
+                        .note(&format!("source type: {}", from))
+                        .note(&format!("target type: {}", to))
+                        .help("cast with `as` to a pointer instead")
                         .emit();
                     return;
                 }
-                _ => {}
             }
         }
 
@@ -111,7 +110,7 @@ fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) {
                 }
                 Err(LayoutError::Unknown(bad)) => {
                     if bad == ty {
-                        format!("size can vary")
+                        format!("this type's size can vary")
                     } else {
                         format!("size can vary because of {}", bad)
                     }
@@ -121,14 +120,9 @@ fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) {
         };
 
         struct_span_err!(self.tcx.sess, span, E0512,
-                  "transmute called with differently sized types: \
-                   {} ({}) to {} ({})",
-                  from, skeleton_string(from, sk_from),
-                  to, skeleton_string(to, sk_to))
-            .span_label(span,
-                format!("transmuting between {} and {}",
-                    skeleton_string(from, sk_from),
-                    skeleton_string(to, sk_to)))
+            "transmute called with types of different sizes")
+            .note(&format!("source type: {} ({})", from, skeleton_string(from, sk_from)))
+            .note(&format!("target type: {} ({})", to, skeleton_string(to, sk_to)))
             .emit();
     }
 }
index 2b89873ee45ff9838a8c6e42f8dfcbb8b328c248..25f962716413119eed2f6df8851b13a72c2fafb6 100644 (file)
@@ -12,5 +12,4 @@ fn takes_u8(_: u8) {}
 
 fn main() {
     unsafe { takes_u8(::std::mem::transmute(0u16)); } //~ ERROR E0512
-                                                      //~| transmuting between 16 bits and 8 bits
 }
index c92a404b71a6fbf38ad9afc5af0a6402985d585b..9d9b7e48043540bc19ccd37af270b5e573915c14 100644 (file)
@@ -15,7 +15,7 @@ trait Trait<'a> {
 
 fn foo<'a, T: Trait<'a>>(value: T::A) {
     let new: T::B = unsafe { std::mem::transmute(value) };
-//~^ ERROR: transmute called with differently sized types
+//~^ ERROR: transmute called with types of different sizes
 }
 
 fn main() { }
index c332e4ea45973a028e007590fcc1fbec8f9cfa43..dc9155ed66c6e1dd8ea4935532c7ec8b81f7df37 100644 (file)
@@ -17,7 +17,7 @@ struct ArrayPeano<T: Bar> {
 }
 
 fn foo<T>(a: &ArrayPeano<T>) -> &[T] where T: Bar {
-    unsafe { std::mem::transmute(a) } //~ ERROR transmute called with differently sized types
+    unsafe { std::mem::transmute(a) } //~ ERROR transmute called with types of different sizes
 }
 
 impl Bar for () {
index 6e8126348da69c6a0e2fe2040b00ba9afeb448fa..5091ba4ee1aa4254801563bb6732c1750a9709cc 100644 (file)
@@ -21,7 +21,7 @@ struct Bar<U: Foo> {
 
 fn foo<U: Foo>(x: [usize; 2]) -> Bar<U> {
     unsafe { mem::transmute(x) }
-    //~^ ERROR transmute called with differently sized types
+    //~^ ERROR transmute called with types of different sizes
 }
 
 fn main() {}
index 2c345e6c8ab2bcd52aace101c8292d51f171557a..c96184d5988437dfbf450d6c4cb60d4b42ea7884 100644 (file)
@@ -13,7 +13,7 @@
 // the error points to the start of the file, not the line with the
 // transmute
 
-// error-pattern: transmute called with differently sized types
+// error-pattern: transmute called with types of different sizes
 
 use std::mem;
 
index 94f2522f3eb340e4a8fd809def65bcfb44695ada..abb02dd39e67d705bb01bd1795c2362b804deee9 100644 (file)
@@ -13,7 +13,7 @@
 // the error points to the start of the file, not the line with the
 // transmute
 
-// error-pattern: transmute called with differently sized types
+// error-pattern: transmute called with types of different sizes
 
 use std::mem;
 
index 5fab271efce64cb72905e943b8b029531b75dff3..113e2ed4c80f44d85ff4eb500f05e8cef7382ade 100644 (file)
 
 unsafe fn f() {
     let _: i8 = transmute(16i16);
-    //~^ ERROR transmute called with differently sized types
+    //~^ ERROR transmute called with types of different sizes
 }
 
 unsafe fn g<T>(x: &T) {
     let _: i8 = transmute(x);
-    //~^ ERROR transmute called with differently sized types
+    //~^ ERROR transmute called with types of different sizes
 }
 
 trait Specializable { type Output; }
@@ -33,7 +33,7 @@ impl<T> Specializable for T {
 
 unsafe fn specializable<T>(x: u16) -> <T as Specializable>::Output {
     transmute(x)
-    //~^ ERROR transmute called with differently sized types
+    //~^ ERROR transmute called with types of different sizes
 }
 
 fn main() {}
index f7324247f3b4a01eb60a78a2206a0da461ab058e..59027fc7787f846603046b04ce548020e794dee9 100644 (file)
 use std::mem::transmute;
 
 fn a<T, U: ?Sized>(x: &[T]) -> &U {
-    unsafe { transmute(x) } //~ ERROR transmute called with differently sized types
+    unsafe { transmute(x) } //~ ERROR transmute called with types of different sizes
 }
 
 fn b<T: ?Sized, U: ?Sized>(x: &T) -> &U {
-    unsafe { transmute(x) } //~ ERROR transmute called with differently sized types
+    unsafe { transmute(x) } //~ ERROR transmute called with types of different sizes
 }
 
 fn c<T, U>(x: &T) -> &U {
@@ -31,11 +31,11 @@ fn d<T, U>(x: &[T]) -> &[U] {
 }
 
 fn e<T: ?Sized, U>(x: &T) -> &U {
-    unsafe { transmute(x) } //~ ERROR transmute called with differently sized types
+    unsafe { transmute(x) } //~ ERROR transmute called with types of different sizes
 }
 
 fn f<T, U: ?Sized>(x: &T) -> &U {
-    unsafe { transmute(x) } //~ ERROR transmute called with differently sized types
+    unsafe { transmute(x) } //~ ERROR transmute called with types of different sizes
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/transmute-from-fn-item-types-error.rs b/src/test/compile-fail/transmute-from-fn-item-types-error.rs
deleted file mode 100644 (file)
index c3fe1de..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::mem;
-
-unsafe fn foo() -> (isize, *const (), Option<fn()>) {
-    let i = mem::transmute(bar);
-    //~^ ERROR is zero-sized and can't be transmuted
-    //~^^ NOTE cast with `as` to a pointer instead
-
-    let p = mem::transmute(foo);
-    //~^ ERROR is zero-sized and can't be transmuted
-    //~^^ NOTE cast with `as` to a pointer instead
-
-    let of = mem::transmute(main);
-    //~^ ERROR is zero-sized and can't be transmuted
-    //~^^ NOTE cast with `as` to a pointer instead
-
-    (i, p, of)
-}
-
-unsafe fn bar() {
-    // Error as usual if the resulting type is not pointer-sized.
-    mem::transmute::<_, u8>(main);
-    //~^ ERROR transmute called with differently sized types
-    //~^^ NOTE transmuting between 0 bits and 8 bits
-
-    mem::transmute::<_, *mut ()>(foo);
-    //~^ ERROR is zero-sized and can't be transmuted
-    //~^^ NOTE cast with `as` to a pointer instead
-
-    mem::transmute::<_, fn()>(bar);
-    //~^ ERROR is zero-sized and can't be transmuted
-    //~^^ NOTE cast with `as` to a pointer instead
-
-    // No error if a coercion would otherwise occur.
-    mem::transmute::<fn(), usize>(main);
-}
-
-unsafe fn baz() {
-    mem::transmute::<_, *mut ()>(Some(foo));
-    //~^ ERROR is zero-sized and can't be transmuted
-    //~^^ NOTE cast with `as` to a pointer instead
-
-    mem::transmute::<_, fn()>(Some(bar));
-    //~^ ERROR is zero-sized and can't be transmuted
-    //~^^ NOTE cast with `as` to a pointer instead
-
-    mem::transmute::<_, Option<fn()>>(Some(baz));
-    //~^ ERROR is zero-sized and can't be transmuted
-    //~^^ NOTE cast with `as` to a pointer instead
-
-    // No error if a coercion would otherwise occur.
-    mem::transmute::<Option<fn()>, usize>(Some(main));
-}
-
-fn main() {
-    unsafe {
-        foo();
-        bar();
-        baz();
-    }
-}
index 55cebbd6cfcbe71ec8915bbd9e8ec4567c524b9e..2f8f9e46e1aeeb6f21d9fe508e9f4f069fe20ebb 100644 (file)
@@ -26,7 +26,7 @@ fn m(x: &T) -> &isize where T : Sized {
 
     fn n(x: &T) -> &isize {
         // Not OK here, because T : Sized is not in scope.
-        unsafe { transmute(x) } //~ ERROR transmute called with differently sized types
+        unsafe { transmute(x) } //~ ERROR transmute called with types of different sizes
     }
 }
 
diff --git a/src/test/compile-fail/transmute-type-parameters.rs b/src/test/compile-fail/transmute-type-parameters.rs
deleted file mode 100644 (file)
index b6e7e32..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Tests that `transmute` cannot be called on type parameters.
-
-use std::mem::transmute;
-
-unsafe fn f<T>(x: T) {
-    let _: isize = transmute(x);
-//~^ ERROR differently sized types: T (size can vary) to isize
-}
-
-unsafe fn g<T>(x: (T, isize)) {
-    let _: isize = transmute(x);
-//~^ ERROR differently sized types: (T, isize) (size can vary because of T) to isize
-}
-
-unsafe fn h<T>(x: [T; 10]) {
-    let _: isize = transmute(x);
-//~^ ERROR differently sized types: [T; 10] (size can vary because of T) to isize
-}
-
-struct Bad<T> {
-    f: T,
-}
-
-unsafe fn i<T>(x: Bad<T>) {
-    let _: isize = transmute(x);
-//~^ ERROR differently sized types: Bad<T> (size can vary because of T) to isize
-}
-
-enum Worse<T> {
-    A(T),
-    B,
-}
-
-unsafe fn j<T>(x: Worse<T>) {
-    let _: isize = transmute(x);
-//~^ ERROR differently sized types: Worse<T> (size can vary because of T) to isize
-}
-
-unsafe fn k<T>(x: Option<T>) {
-    let _: isize = transmute(x);
-//~^ ERROR differently sized types: std::option::Option<T> (size can vary because of T) to isize
-}
-
-fn main() {}
diff --git a/src/test/ui/transmute/main.rs b/src/test/ui/transmute/main.rs
new file mode 100644 (file)
index 0000000..28cac90
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+#![feature(untagged_unions)]
+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) //~ ERROR transmute called with types of different sizes
+}
+
+unsafe fn sizes() {
+    let x: u8 = transmute(10u16); //~ ERROR transmute called with types of different sizes
+}
+
+unsafe fn ptrs() {
+    let x: u8 = transmute("test"); //~ ERROR transmute called with types of different sizes
+}
+
+union Foo { x: () }
+unsafe fn vary() {
+    let x: Foo = transmute(10); //~ ERROR transmute called with types of different sizes
+}
+
+fn main() {}
diff --git a/src/test/ui/transmute/main.stderr b/src/test/ui/transmute/main.stderr
new file mode 100644 (file)
index 0000000..2ae4252
--- /dev/null
@@ -0,0 +1,38 @@
+error[E0512]: transmute called with types of different sizes
+  --> $DIR/main.rs:20:5
+   |
+20 |     transmute(x) //~ ERROR transmute called with types of different sizes
+   |     ^^^^^^^^^
+   |
+   = note: source type: <C as TypeConstructor<'a>>::T (size can vary because of <C as TypeConstructor>::T)
+   = note: target type: <C as TypeConstructor<'b>>::T (size can vary because of <C as TypeConstructor>::T)
+
+error[E0512]: transmute called with types of different sizes
+  --> $DIR/main.rs:24:17
+   |
+24 |     let x: u8 = transmute(10u16); //~ ERROR transmute called with types of different sizes
+   |                 ^^^^^^^^^
+   |
+   = note: source type: u16 (16 bits)
+   = note: target type: u8 (8 bits)
+
+error[E0512]: transmute called with types of different sizes
+  --> $DIR/main.rs:28:17
+   |
+28 |     let x: u8 = transmute("test"); //~ ERROR transmute called with types of different sizes
+   |                 ^^^^^^^^^
+   |
+   = note: source type: &str (128 bits)
+   = note: target type: u8 (8 bits)
+
+error[E0512]: transmute called with types of different sizes
+  --> $DIR/main.rs:33:18
+   |
+33 |     let x: Foo = transmute(10); //~ ERROR transmute called with types of different sizes
+   |                  ^^^^^^^^^
+   |
+   = note: source type: i32 (32 bits)
+   = note: target type: Foo (0 bits)
+
+error: aborting due to previous error(s)
+
diff --git a/src/test/ui/transmute/transmute-from-fn-item-types-error.rs b/src/test/ui/transmute/transmute-from-fn-item-types-error.rs
new file mode 100644 (file)
index 0000000..808be8b
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::mem;
+
+unsafe fn foo() -> (isize, *const (), Option<fn()>) {
+    let i = mem::transmute(bar);
+    //~^ ERROR is zero-sized and can't be transmuted
+    //~^^ NOTE cast with `as` to a pointer instead
+
+    let p = mem::transmute(foo);
+    //~^ ERROR is zero-sized and can't be transmuted
+    //~^^ NOTE cast with `as` to a pointer instead
+
+    let of = mem::transmute(main);
+    //~^ ERROR is zero-sized and can't be transmuted
+    //~^^ NOTE cast with `as` to a pointer instead
+
+    (i, p, of)
+}
+
+unsafe fn bar() {
+    // Error as usual if the resulting type is not pointer-sized.
+    mem::transmute::<_, u8>(main);
+    //~^ ERROR transmute called with types of different sizes
+    //~^^ NOTE transmuting between fn() {main} and u8
+
+    mem::transmute::<_, *mut ()>(foo);
+    //~^ ERROR is zero-sized and can't be transmuted
+    //~^^ NOTE cast with `as` to a pointer instead
+
+    mem::transmute::<_, fn()>(bar);
+    //~^ ERROR is zero-sized and can't be transmuted
+    //~^^ NOTE cast with `as` to a pointer instead
+
+    // No error if a coercion would otherwise occur.
+    mem::transmute::<fn(), usize>(main);
+}
+
+unsafe fn baz() {
+    mem::transmute::<_, *mut ()>(Some(foo));
+    //~^ ERROR is zero-sized and can't be transmuted
+    //~^^ NOTE cast with `as` to a pointer instead
+
+    mem::transmute::<_, fn()>(Some(bar));
+    //~^ ERROR is zero-sized and can't be transmuted
+    //~^^ NOTE cast with `as` to a pointer instead
+
+    mem::transmute::<_, Option<fn()>>(Some(baz));
+    //~^ ERROR is zero-sized and can't be transmuted
+    //~^^ NOTE cast with `as` to a pointer instead
+
+    // No error if a coercion would otherwise occur.
+    mem::transmute::<Option<fn()>, usize>(Some(main));
+}
+
+fn main() {
+    unsafe {
+        foo();
+        bar();
+        baz();
+    }
+}
diff --git a/src/test/ui/transmute/transmute-from-fn-item-types-error.stderr b/src/test/ui/transmute/transmute-from-fn-item-types-error.stderr
new file mode 100644 (file)
index 0000000..efd6063
--- /dev/null
@@ -0,0 +1,91 @@
+error[E0591]: can't transmute zero-sized type
+  --> $DIR/transmute-from-fn-item-types-error.rs:14:13
+   |
+14 |     let i = mem::transmute(bar);
+   |             ^^^^^^^^^^^^^^
+   |
+   = note: source type: unsafe fn() {bar}
+   = note: target type: isize
+   = help: cast with `as` to a pointer instead
+
+error[E0591]: can't transmute zero-sized type
+  --> $DIR/transmute-from-fn-item-types-error.rs:18:13
+   |
+18 |     let p = mem::transmute(foo);
+   |             ^^^^^^^^^^^^^^
+   |
+   = note: source type: unsafe fn() -> (isize, *const (), std::option::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:22:14
+   |
+22 |     let of = mem::transmute(main);
+   |              ^^^^^^^^^^^^^^
+   |
+   = note: source type: fn() {main}
+   = note: target type: std::option::Option<fn()>
+   = help: cast with `as` to a pointer instead
+
+error[E0512]: transmute called with types of different sizes
+  --> $DIR/transmute-from-fn-item-types-error.rs:31:5
+   |
+31 |     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:35:5
+   |
+35 |     mem::transmute::<_, *mut ()>(foo);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: source type: unsafe fn() -> (isize, *const (), std::option::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:39:5
+   |
+39 |     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:48:5
+   |
+48 |     mem::transmute::<_, *mut ()>(Some(foo));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: source type: unsafe fn() -> (isize, *const (), std::option::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:52:5
+   |
+52 |     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:56:5
+   |
+56 |     mem::transmute::<_, Option<fn()>>(Some(baz));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: source type: unsafe fn() {baz}
+   = note: target type: std::option::Option<fn()>
+   = help: cast with `as` to a pointer instead
+
+error: aborting due to previous error(s)
+
diff --git a/src/test/ui/transmute/transmute-type-parameters.rs b/src/test/ui/transmute/transmute-type-parameters.rs
new file mode 100644 (file)
index 0000000..b6e7e32
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Tests that `transmute` cannot be called on type parameters.
+
+use std::mem::transmute;
+
+unsafe fn f<T>(x: T) {
+    let _: isize = transmute(x);
+//~^ ERROR differently sized types: T (size can vary) to isize
+}
+
+unsafe fn g<T>(x: (T, isize)) {
+    let _: isize = transmute(x);
+//~^ ERROR differently sized types: (T, isize) (size can vary because of T) to isize
+}
+
+unsafe fn h<T>(x: [T; 10]) {
+    let _: isize = transmute(x);
+//~^ ERROR differently sized types: [T; 10] (size can vary because of T) to isize
+}
+
+struct Bad<T> {
+    f: T,
+}
+
+unsafe fn i<T>(x: Bad<T>) {
+    let _: isize = transmute(x);
+//~^ ERROR differently sized types: Bad<T> (size can vary because of T) to isize
+}
+
+enum Worse<T> {
+    A(T),
+    B,
+}
+
+unsafe fn j<T>(x: Worse<T>) {
+    let _: isize = transmute(x);
+//~^ ERROR differently sized types: Worse<T> (size can vary because of T) to isize
+}
+
+unsafe fn k<T>(x: Option<T>) {
+    let _: isize = transmute(x);
+//~^ ERROR differently sized types: std::option::Option<T> (size can vary because of T) to isize
+}
+
+fn main() {}
diff --git a/src/test/ui/transmute/transmute-type-parameters.stderr b/src/test/ui/transmute/transmute-type-parameters.stderr
new file mode 100644 (file)
index 0000000..39f18ef
--- /dev/null
@@ -0,0 +1,56 @@
+error[E0512]: transmute called with types of different sizes
+  --> $DIR/transmute-type-parameters.rs:16:20
+   |
+16 |     let _: isize = transmute(x);
+   |                    ^^^^^^^^^
+   |
+   = note: source type: T (this type's size can vary)
+   = note: target type: isize (64 bits)
+
+error[E0512]: transmute called with types of different sizes
+  --> $DIR/transmute-type-parameters.rs:21:20
+   |
+21 |     let _: isize = transmute(x);
+   |                    ^^^^^^^^^
+   |
+   = note: source type: (T, isize) (size can vary because of T)
+   = note: target type: isize (64 bits)
+
+error[E0512]: transmute called with types of different sizes
+  --> $DIR/transmute-type-parameters.rs:26:20
+   |
+26 |     let _: isize = transmute(x);
+   |                    ^^^^^^^^^
+   |
+   = note: source type: [T; 10] (size can vary because of T)
+   = note: target type: isize (64 bits)
+
+error[E0512]: transmute called with types of different sizes
+  --> $DIR/transmute-type-parameters.rs:35:20
+   |
+35 |     let _: isize = transmute(x);
+   |                    ^^^^^^^^^
+   |
+   = note: source type: Bad<T> (size can vary because of T)
+   = note: target type: isize (64 bits)
+
+error[E0512]: transmute called with types of different sizes
+  --> $DIR/transmute-type-parameters.rs:45:20
+   |
+45 |     let _: isize = transmute(x);
+   |                    ^^^^^^^^^
+   |
+   = note: source type: Worse<T> (size can vary because of T)
+   = note: target type: isize (64 bits)
+
+error[E0512]: transmute called with types of different sizes
+  --> $DIR/transmute-type-parameters.rs:50:20
+   |
+50 |     let _: isize = transmute(x);
+   |                    ^^^^^^^^^
+   |
+   = note: source type: std::option::Option<T> (size can vary because of T)
+   = note: target type: isize (64 bits)
+
+error: aborting due to previous error(s)
+