fn main() {
unsafe { takes_u8(::std::mem::transmute(0u16)); }
- // error: transmute called with differently sized types
+ // error: transmute called with types of different sizes
}
```
// 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;
}
- _ => {}
}
}
}
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)
}
};
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();
}
}
fn main() {
unsafe { takes_u8(::std::mem::transmute(0u16)); } //~ ERROR E0512
- //~| transmuting between 16 bits and 8 bits
}
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() { }
}
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 () {
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() {}
// 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;
// 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;
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; }
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() {}
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 {
}
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() { }
+++ /dev/null
-// 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();
- }
-}
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
}
}
+++ /dev/null
-// 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() {}
--- /dev/null
+// 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() {}
--- /dev/null
+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)
+
--- /dev/null
+// 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();
+ }
+}
--- /dev/null
+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)
+
--- /dev/null
+// 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() {}
--- /dev/null
+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)
+