Skip to content

Add specific diagnostic when attempting to transmute between equal generic types #57044

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 31, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1552,7 +1552,8 @@ fn takes_u8(_: u8) {}

fn main() {
unsafe { takes_u8(::std::mem::transmute(0u16)); }
// error: transmute called with types of different sizes
// error: cannot transmute between types of different sizes,
// or dependently-sized types
}
```

Expand Down
19 changes: 12 additions & 7 deletions src/librustc/middle/intrinsicck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,11 @@ impl<'a, 'tcx> ExprVisitor<'a, 'tcx> {
format!("{} bits", size.bits())
}
Ok(SizeSkeleton::Pointer { tail, .. }) => {
format!("pointer to {}", tail)
format!("pointer to `{}`", tail)
}
Err(LayoutError::Unknown(bad)) => {
if bad == ty {
"this type's size can vary".to_owned()
"this type does not have a fixed size".to_owned()
} else {
format!("size can vary because of {}", bad)
}
Expand All @@ -110,11 +110,16 @@ impl<'a, 'tcx> ExprVisitor<'a, 'tcx> {
}
};

struct_span_err!(self.tcx.sess, span, E0512,
"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();
let mut err = struct_span_err!(self.tcx.sess, span, E0512,
"cannot transmute between types of different sizes, \
or dependently-sized types");
if from == to {
err.note(&format!("`{}` does not have a fixed size", from));
} else {
err.note(&format!("source type: `{}` ({})", from, skeleton_string(from, sk_from)))
.note(&format!("target type: `{}` ({})", to, skeleton_string(to, sk_to)));
}
err.emit()
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/error-codes/E0512.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0512]: transmute called with types of different sizes
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $DIR/E0512.rs:4:23
|
LL | unsafe { takes_u8(::std::mem::transmute(0u16)); } //~ ERROR E0512
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: source type: u16 (16 bits)
= note: target type: u8 (8 bits)
= note: source type: `u16` (16 bits)
= note: target type: `u8` (8 bits)

error: aborting due to previous error

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-21174.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,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 types of different sizes
//~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
}

fn main() { }
6 changes: 3 additions & 3 deletions src/test/ui/issues/issue-21174.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0512]: transmute called with types of different sizes
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $DIR/issue-21174.rs:7:30
|
LL | let new: T::B = unsafe { std::mem::transmute(value) };
| ^^^^^^^^^^^^^^^^^^^
|
= note: source type: <T as Trait<'a>>::A (size can vary because of <T as Trait>::A)
= note: target type: <T as Trait<'a>>::B (size can vary because of <T as Trait>::B)
= note: source type: `<T as Trait<'a>>::A` (size can vary because of <T as Trait>::A)
= note: target type: `<T as Trait<'a>>::B` (size can vary because of <T as Trait>::B)

error: aborting due to previous error

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-28625.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ struct ArrayPeano<T: Bar> {
}

fn foo<T>(a: &ArrayPeano<T>) -> &[T] where T: Bar {
unsafe { std::mem::transmute(a) } //~ ERROR transmute called with types of different sizes
unsafe { std::mem::transmute(a) } //~ ERROR cannot transmute between types of different sizes
}

impl Bar for () {
Expand Down
8 changes: 4 additions & 4 deletions src/test/ui/issues/issue-28625.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0512]: transmute called with types of different sizes
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $DIR/issue-28625.rs:12:14
|
LL | unsafe { std::mem::transmute(a) } //~ ERROR transmute called with types of different sizes
LL | unsafe { std::mem::transmute(a) } //~ ERROR cannot transmute between types of different sizes
| ^^^^^^^^^^^^^^^^^^^
|
= note: source type: &ArrayPeano<T> (N bits)
= note: target type: &[T] (N bits)
= note: source type: `&ArrayPeano<T>` (N bits)
= note: target type: `&[T]` (N bits)

error: aborting due to previous error

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-32377.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct Bar<U: Foo> {

fn foo<U: Foo>(x: [usize; 2]) -> Bar<U> {
unsafe { mem::transmute(x) }
//~^ ERROR transmute called with types of different sizes
//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
}

fn main() {}
6 changes: 3 additions & 3 deletions src/test/ui/issues/issue-32377.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0512]: transmute called with types of different sizes
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $DIR/issue-32377.rs:15:14
|
LL | unsafe { mem::transmute(x) }
| ^^^^^^^^^^^^^^
|
= note: source type: [usize; 2] (N bits)
= note: target type: Bar<U> (N bits)
= note: source type: `[usize; 2]` (N bits)
= note: target type: `Bar<U>` (N bits)

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// the error points to the start of the file, not the line with the
// transmute

// error-pattern: transmute called with types of different sizes
// error-pattern: cannot transmute between types of different sizes, or dependently-sized types

use std::mem;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0512]: transmute called with types of different sizes
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $DIR/packed-struct-generic-transmute.rs:24:38
|
LL | let oof: Oof<[u8; 5], i32> = mem::transmute(foo);
| ^^^^^^^^^^^^^^
|
= note: source type: Foo<[u8; 5], i32> (72 bits)
= note: target type: Oof<[u8; 5], i32> (96 bits)
= note: source type: `Foo<[u8; 5], i32>` (72 bits)
= note: target type: `Oof<[u8; 5], i32>` (96 bits)

error: aborting due to previous error

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/packed-struct/packed-struct-transmute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// transmute

// normalize-stderr-test "\d+ bits" -> "N bits"
// error-pattern: transmute called with types of different sizes
// error-pattern: cannot transmute between types of different sizes, or dependently-sized types

use std::mem;

Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/packed-struct/packed-struct-transmute.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0512]: transmute called with types of different sizes
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $DIR/packed-struct-transmute.rs:26:24
|
LL | let oof: Oof = mem::transmute(foo);
| ^^^^^^^^^^^^^^
|
= note: source type: Foo (N bits)
= note: target type: Oof (N bits)
= note: source type: `Foo` (N bits)
= note: target type: `Oof` (N bits)

error: aborting due to previous error

Expand Down
9 changes: 9 additions & 0 deletions src/test/ui/transmute-equal-assoc-types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
trait Foo {
type Bar;
}

unsafe fn noop<F: Foo>(foo: F::Bar) -> F::Bar {
::std::mem::transmute(foo) //~ ERROR cannot transmute between types of different sizes
}

fn main() {}
11 changes: 11 additions & 0 deletions src/test/ui/transmute-equal-assoc-types.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $DIR/transmute-equal-assoc-types.rs:6:5
|
LL | ::std::mem::transmute(foo) //~ ERROR cannot transmute between types of different sizes
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `<F as Foo>::Bar` does not have a fixed size

error: aborting due to previous error

For more information about this error, try `rustc --explain E0512`.
12 changes: 6 additions & 6 deletions src/test/ui/transmute/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// normalize-stderr-32bit: "&str \(64 bits\)" -> "&str ($$STR bits)"
// normalize-stderr-64bit: "&str \(128 bits\)" -> "&str ($$STR bits)"
// normalize-stderr-32bit: "`&str` \(64 bits\)" -> "`&str` ($$STR bits)"
// normalize-stderr-64bit: "`&str` \(128 bits\)" -> "`&str` ($$STR bits)"



Expand All @@ -13,20 +13,20 @@ pub trait TypeConstructor<'a> {
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
transmute(x) //~ ERROR cannot transmute between types of different sizes
}

unsafe fn sizes() {
let x: u8 = transmute(10u16); //~ ERROR transmute called with types of different sizes
let x: u8 = transmute(10u16); //~ ERROR cannot transmute between types of different sizes
}

unsafe fn ptrs() {
let x: u8 = transmute("test"); //~ ERROR transmute called with types of different sizes
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 transmute called with types of different sizes
let x: Foo = transmute(10); //~ ERROR cannot transmute between types of different sizes
}

fn main() {}
32 changes: 16 additions & 16 deletions src/test/ui/transmute/main.stderr
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
error[E0512]: transmute called with types of different sizes
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $DIR/main.rs:16:5
|
LL | transmute(x) //~ ERROR transmute called with types of different sizes
LL | transmute(x) //~ ERROR cannot transmute between 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)
= 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
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $DIR/main.rs:20:17
|
LL | let x: u8 = transmute(10u16); //~ ERROR transmute called with types of different sizes
LL | let x: u8 = transmute(10u16); //~ ERROR cannot transmute between types of different sizes
| ^^^^^^^^^
|
= note: source type: u16 (16 bits)
= note: target type: u8 (8 bits)
= note: source type: `u16` (16 bits)
= note: target type: `u8` (8 bits)

error[E0512]: transmute called with types of different sizes
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $DIR/main.rs:24:17
|
LL | let x: u8 = transmute("test"); //~ ERROR transmute called with types of different sizes
LL | let x: u8 = transmute("test"); //~ ERROR cannot transmute between types of different sizes
| ^^^^^^^^^
|
= note: source type: &str ($STR bits)
= note: target type: u8 (8 bits)
= note: source type: `&str` ($STR bits)
= note: target type: `u8` (8 bits)

error[E0512]: transmute called with types of different sizes
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $DIR/main.rs:29:18
|
LL | let x: Foo = transmute(10); //~ ERROR transmute called with types of different sizes
LL | let x: Foo = transmute(10); //~ ERROR cannot transmute between types of different sizes
| ^^^^^^^^^
|
= note: source type: i32 (32 bits)
= note: target type: Foo (0 bits)
= note: source type: `i32` (32 bits)
= note: target type: `Foo` (0 bits)

error: aborting due to 4 previous errors

Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/transmute/transmute-different-sizes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ use std::mem::transmute;

unsafe fn f() {
let _: i8 = transmute(16i16);
//~^ ERROR transmute called with types of different sizes
//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
}

unsafe fn g<T>(x: &T) {
let _: i8 = transmute(x);
//~^ ERROR transmute called with types of different sizes
//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
}

trait Specializable { type Output; }
Expand All @@ -25,7 +25,7 @@ impl<T> Specializable for T {

unsafe fn specializable<T>(x: u16) -> <T as Specializable>::Output {
transmute(x)
//~^ ERROR transmute called with types of different sizes
//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
}

fn main() {}
18 changes: 9 additions & 9 deletions src/test/ui/transmute/transmute-different-sizes.stderr
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
error[E0512]: transmute called with types of different sizes
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)
= note: source type: `i16` (N bits)
= note: target type: `i8` (N bits)

error[E0512]: transmute called with types of different sizes
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)
= note: source type: `&T` (N bits)
= note: target type: `i8` (N bits)

error[E0512]: transmute called with types of different sizes
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's size can vary)
= 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

Expand Down
8 changes: 4 additions & 4 deletions src/test/ui/transmute/transmute-fat-pointers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
use std::mem::transmute;

fn a<T, U: ?Sized>(x: &[T]) -> &U {
unsafe { transmute(x) } //~ ERROR transmute called with types of different sizes
unsafe { transmute(x) } //~ ERROR cannot transmute between types of different sizes
}

fn b<T: ?Sized, U: ?Sized>(x: &T) -> &U {
unsafe { transmute(x) } //~ ERROR transmute called with types of different sizes
unsafe { transmute(x) } //~ ERROR cannot transmute between types of different sizes
}

fn c<T, U>(x: &T) -> &U {
Expand All @@ -23,11 +23,11 @@ fn d<T, U>(x: &[T]) -> &[U] {
}

fn e<T: ?Sized, U>(x: &T) -> &U {
unsafe { transmute(x) } //~ ERROR transmute called with types of different sizes
unsafe { transmute(x) } //~ ERROR cannot transmute between types of different sizes
}

fn f<T, U: ?Sized>(x: &T) -> &U {
unsafe { transmute(x) } //~ ERROR transmute called with types of different sizes
unsafe { transmute(x) } //~ ERROR cannot transmute between types of different sizes
}

fn main() { }
Loading