summaryrefslogtreecommitdiffstats
path: root/src/test/ui/transmute
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/transmute')
-rw-r--r--src/test/ui/transmute/main.rs29
-rw-r--r--src/test/ui/transmute/main.stderr38
-rw-r--r--src/test/ui/transmute/transmute-different-sizes.rs31
-rw-r--r--src/test/ui/transmute/transmute-different-sizes.stderr30
-rw-r--r--src/test/ui/transmute/transmute-fat-pointers.rs33
-rw-r--r--src/test/ui/transmute/transmute-fat-pointers.stderr39
-rw-r--r--src/test/ui/transmute/transmute-from-fn-item-types-error.rs60
-rw-r--r--src/test/ui/transmute/transmute-from-fn-item-types-error.stderr92
-rw-r--r--src/test/ui/transmute/transmute-impl.rs25
-rw-r--r--src/test/ui/transmute/transmute-impl.stderr12
-rw-r--r--src/test/ui/transmute/transmute-imut-to-mut.rs8
-rw-r--r--src/test/ui/transmute/transmute-imut-to-mut.stderr10
-rw-r--r--src/test/ui/transmute/transmute-type-parameters.rs44
-rw-r--r--src/test/ui/transmute/transmute-type-parameters.stderr57
14 files changed, 508 insertions, 0 deletions
diff --git a/src/test/ui/transmute/main.rs b/src/test/ui/transmute/main.rs
new file mode 100644
index 000000000..cb46fc5ec
--- /dev/null
+++ b/src/test/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) //~ ERROR cannot transmute between types of different sizes
+}
+
+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/src/test/ui/transmute/main.stderr b/src/test/ui/transmute/main.stderr
new file mode 100644
index 000000000..f48562094
--- /dev/null
+++ b/src/test/ui/transmute/main.stderr
@@ -0,0 +1,38 @@
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/main.rs:13:5
+ |
+LL | transmute(x)
+ | ^^^^^^^^^
+ |
+ = note: `<C as TypeConstructor>::T` does not have a fixed size
+
+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 4 previous errors
+
+For more information about this error, try `rustc --explain E0512`.
diff --git a/src/test/ui/transmute/transmute-different-sizes.rs b/src/test/ui/transmute/transmute-different-sizes.rs
new file mode 100644
index 000000000..690decf63
--- /dev/null
+++ b/src/test/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/src/test/ui/transmute/transmute-different-sizes.stderr b/src/test/ui/transmute/transmute-different-sizes.stderr
new file mode 100644
index 000000000..07a38df69
--- /dev/null
+++ b/src/test/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/src/test/ui/transmute/transmute-fat-pointers.rs b/src/test/ui/transmute/transmute-fat-pointers.rs
new file mode 100644
index 000000000..7c1beffd1
--- /dev/null
+++ b/src/test/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/src/test/ui/transmute/transmute-fat-pointers.stderr b/src/test/ui/transmute/transmute-fat-pointers.stderr
new file mode 100644
index 000000000..e8335fcbe
--- /dev/null
+++ b/src/test/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/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
index 000000000..f858a199e
--- /dev/null
+++ b/src/test/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/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
index 000000000..aefe3fb8e
--- /dev/null
+++ b/src/test/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/src/test/ui/transmute/transmute-impl.rs b/src/test/ui/transmute/transmute-impl.rs
new file mode 100644
index 000000000..df422bda1
--- /dev/null
+++ b/src/test/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/src/test/ui/transmute/transmute-impl.stderr b/src/test/ui/transmute/transmute-impl.stderr
new file mode 100644
index 000000000..dd19bcd54
--- /dev/null
+++ b/src/test/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/src/test/ui/transmute/transmute-imut-to-mut.rs b/src/test/ui/transmute/transmute-imut-to-mut.rs
new file mode 100644
index 000000000..9f3f76c1e
--- /dev/null
+++ b/src/test/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/src/test/ui/transmute/transmute-imut-to-mut.stderr b/src/test/ui/transmute/transmute-imut-to-mut.stderr
new file mode 100644
index 000000000..1e9dff3ce
--- /dev/null
+++ b/src/test/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/src/test/ui/transmute/transmute-type-parameters.rs b/src/test/ui/transmute/transmute-type-parameters.rs
new file mode 100644
index 000000000..5f44b2d0f
--- /dev/null
+++ b/src/test/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/src/test/ui/transmute/transmute-type-parameters.stderr b/src/test/ui/transmute/transmute-type-parameters.stderr
new file mode 100644
index 000000000..220b929d4
--- /dev/null
+++ b/src/test/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`.