summaryrefslogtreecommitdiffstats
path: root/tests/ui/cast
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/cast
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/cast')
-rw-r--r--tests/ui/cast/cast-as-bool.rs13
-rw-r--r--tests/ui/cast/cast-as-bool.stderr27
-rw-r--r--tests/ui/cast/cast-char.rs10
-rw-r--r--tests/ui/cast/cast-char.stderr20
-rw-r--r--tests/ui/cast/cast-does-fallback.rs12
-rw-r--r--tests/ui/cast/cast-errors-issue-43825.rs7
-rw-r--r--tests/ui/cast/cast-errors-issue-43825.stderr9
-rw-r--r--tests/ui/cast/cast-from-nil.rs2
-rw-r--r--tests/ui/cast/cast-from-nil.stderr9
-rw-r--r--tests/ui/cast/cast-int-to-char.rs9
-rw-r--r--tests/ui/cast/cast-int-to-char.stderr89
-rw-r--r--tests/ui/cast/cast-macro-lhs.rs12
-rw-r--r--tests/ui/cast/cast-macro-lhs.stderr11
-rw-r--r--tests/ui/cast/cast-pointee-projection.rs17
-rw-r--r--tests/ui/cast/cast-region-to-uint.rs6
-rw-r--r--tests/ui/cast/cast-rfc0401-2.rs8
-rw-r--r--tests/ui/cast/cast-rfc0401-2.stderr9
-rw-r--r--tests/ui/cast/cast-rfc0401-vtable-kinds.rs62
-rw-r--r--tests/ui/cast/cast-rfc0401.rs169
-rw-r--r--tests/ui/cast/cast-to-bare-fn.rs10
-rw-r--r--tests/ui/cast/cast-to-bare-fn.stderr15
-rw-r--r--tests/ui/cast/cast-to-infer-ty.rs8
-rw-r--r--tests/ui/cast/cast-to-nil.rs2
-rw-r--r--tests/ui/cast/cast-to-nil.stderr9
-rw-r--r--tests/ui/cast/cast-to-unsized-trait-object-suggestion.rs4
-rw-r--r--tests/ui/cast/cast-to-unsized-trait-object-suggestion.stderr19
-rw-r--r--tests/ui/cast/cast.rs21
-rw-r--r--tests/ui/cast/casts-differing-anon.rs22
-rw-r--r--tests/ui/cast/casts-differing-anon.stderr11
-rw-r--r--tests/ui/cast/casts-issue-46365.rs8
-rw-r--r--tests/ui/cast/casts-issue-46365.stderr9
-rw-r--r--tests/ui/cast/codegen-object-shim.rs6
-rw-r--r--tests/ui/cast/fat-ptr-cast-rpass.rs34
-rw-r--r--tests/ui/cast/fat-ptr-cast.rs33
-rw-r--r--tests/ui/cast/fat-ptr-cast.stderr88
-rw-r--r--tests/ui/cast/issue-106883-is-empty.rs27
-rw-r--r--tests/ui/cast/issue-106883-is-empty.stderr58
-rw-r--r--tests/ui/cast/issue-10991.rs4
-rw-r--r--tests/ui/cast/issue-10991.stderr9
-rw-r--r--tests/ui/cast/issue-17444.rs8
-rw-r--r--tests/ui/cast/issue-17444.stderr9
-rw-r--r--tests/ui/cast/issue-84213.fixed16
-rw-r--r--tests/ui/cast/issue-84213.rs16
-rw-r--r--tests/ui/cast/issue-84213.stderr25
-rw-r--r--tests/ui/cast/issue-85586.rs10
-rw-r--r--tests/ui/cast/issue-85586.stderr9
-rw-r--r--tests/ui/cast/issue-88621.rs11
-rw-r--r--tests/ui/cast/issue-88621.stderr9
-rw-r--r--tests/ui/cast/issue-89497.fixed10
-rw-r--r--tests/ui/cast/issue-89497.rs10
-rw-r--r--tests/ui/cast/issue-89497.stderr15
-rw-r--r--tests/ui/cast/supported-cast.rs206
-rw-r--r--tests/ui/cast/unsupported-cast.rs5
-rw-r--r--tests/ui/cast/unsupported-cast.stderr9
54 files changed, 1266 insertions, 0 deletions
diff --git a/tests/ui/cast/cast-as-bool.rs b/tests/ui/cast/cast-as-bool.rs
new file mode 100644
index 000000000..fbebc80d9
--- /dev/null
+++ b/tests/ui/cast/cast-as-bool.rs
@@ -0,0 +1,13 @@
+fn main() {
+ let u = 5 as bool; //~ ERROR cannot cast as `bool`
+ //~| HELP compare with zero instead
+ //~| SUGGESTION 5 != 0
+
+ let t = (1 + 2) as bool; //~ ERROR cannot cast as `bool`
+ //~| HELP compare with zero instead
+ //~| SUGGESTION (1 + 2) != 0
+
+ let v = "hello" as bool;
+ //~^ ERROR casting `&'static str` as `bool` is invalid
+ //~| HELP consider using the `is_empty` method on `&'static str` to determine if it contains anything
+}
diff --git a/tests/ui/cast/cast-as-bool.stderr b/tests/ui/cast/cast-as-bool.stderr
new file mode 100644
index 000000000..19ac8f10f
--- /dev/null
+++ b/tests/ui/cast/cast-as-bool.stderr
@@ -0,0 +1,27 @@
+error[E0054]: cannot cast as `bool`
+ --> $DIR/cast-as-bool.rs:2:13
+ |
+LL | let u = 5 as bool;
+ | ^^^^^^^^^ help: compare with zero instead: `5 != 0`
+
+error[E0054]: cannot cast as `bool`
+ --> $DIR/cast-as-bool.rs:6:13
+ |
+LL | let t = (1 + 2) as bool;
+ | ^^^^^^^^^^^^^^^ help: compare with zero instead: `(1 + 2) != 0`
+
+error[E0606]: casting `&'static str` as `bool` is invalid
+ --> $DIR/cast-as-bool.rs:10:13
+ |
+LL | let v = "hello" as bool;
+ | ^^^^^^^^^^^^^^^
+ |
+help: consider using the `is_empty` method on `&'static str` to determine if it contains anything
+ |
+LL | let v = !"hello".is_empty();
+ | + ~~~~~~~~~~~
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0054, E0606.
+For more information about an error, try `rustc --explain E0054`.
diff --git a/tests/ui/cast/cast-char.rs b/tests/ui/cast/cast-char.rs
new file mode 100644
index 000000000..9634ed56f
--- /dev/null
+++ b/tests/ui/cast/cast-char.rs
@@ -0,0 +1,10 @@
+#![deny(overflowing_literals)]
+
+fn main() {
+ const XYZ: char = 0x1F888 as char;
+ //~^ ERROR only `u8` can be cast into `char`
+ const XY: char = 129160 as char;
+ //~^ ERROR only `u8` can be cast into `char`
+ const ZYX: char = '\u{01F888}';
+ println!("{}", XYZ);
+}
diff --git a/tests/ui/cast/cast-char.stderr b/tests/ui/cast/cast-char.stderr
new file mode 100644
index 000000000..211937c9d
--- /dev/null
+++ b/tests/ui/cast/cast-char.stderr
@@ -0,0 +1,20 @@
+error: only `u8` can be cast into `char`
+ --> $DIR/cast-char.rs:4:23
+ |
+LL | const XYZ: char = 0x1F888 as char;
+ | ^^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{1F888}'`
+ |
+note: the lint level is defined here
+ --> $DIR/cast-char.rs:1:9
+ |
+LL | #![deny(overflowing_literals)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: only `u8` can be cast into `char`
+ --> $DIR/cast-char.rs:6:22
+ |
+LL | const XY: char = 129160 as char;
+ | ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{1F888}'`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/cast/cast-does-fallback.rs b/tests/ui/cast/cast-does-fallback.rs
new file mode 100644
index 000000000..770f7a31c
--- /dev/null
+++ b/tests/ui/cast/cast-does-fallback.rs
@@ -0,0 +1,12 @@
+// run-pass
+
+pub fn main() {
+ // Test that these type check correctly.
+ (&42u8 >> 4) as usize;
+ (&42u8 << 4) as usize;
+
+ let cap = 512 * 512;
+ cap as u8;
+ // Assert `cap` did not get inferred to `u8` and overflowed.
+ assert_ne!(cap, 0);
+}
diff --git a/tests/ui/cast/cast-errors-issue-43825.rs b/tests/ui/cast/cast-errors-issue-43825.rs
new file mode 100644
index 000000000..00e0da44b
--- /dev/null
+++ b/tests/ui/cast/cast-errors-issue-43825.rs
@@ -0,0 +1,7 @@
+fn main() {
+ let error = error; //~ ERROR cannot find value `error`
+
+ // These used to cause errors.
+ 0 as f32;
+ 0.0 as u32;
+}
diff --git a/tests/ui/cast/cast-errors-issue-43825.stderr b/tests/ui/cast/cast-errors-issue-43825.stderr
new file mode 100644
index 000000000..1e77f5dbd
--- /dev/null
+++ b/tests/ui/cast/cast-errors-issue-43825.stderr
@@ -0,0 +1,9 @@
+error[E0425]: cannot find value `error` in this scope
+ --> $DIR/cast-errors-issue-43825.rs:2:17
+ |
+LL | let error = error;
+ | ^^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/cast/cast-from-nil.rs b/tests/ui/cast/cast-from-nil.rs
new file mode 100644
index 000000000..b5ceef76a
--- /dev/null
+++ b/tests/ui/cast/cast-from-nil.rs
@@ -0,0 +1,2 @@
+// error-pattern: non-primitive cast: `()` as `u32`
+fn main() { let u = (assert!(true) as u32); }
diff --git a/tests/ui/cast/cast-from-nil.stderr b/tests/ui/cast/cast-from-nil.stderr
new file mode 100644
index 000000000..dab133cfb
--- /dev/null
+++ b/tests/ui/cast/cast-from-nil.stderr
@@ -0,0 +1,9 @@
+error[E0605]: non-primitive cast: `()` as `u32`
+ --> $DIR/cast-from-nil.rs:2:21
+ |
+LL | fn main() { let u = (assert!(true) as u32); }
+ | ^^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0605`.
diff --git a/tests/ui/cast/cast-int-to-char.rs b/tests/ui/cast/cast-int-to-char.rs
new file mode 100644
index 000000000..379956968
--- /dev/null
+++ b/tests/ui/cast/cast-int-to-char.rs
@@ -0,0 +1,9 @@
+fn foo<T>(_t: T) {}
+
+fn main() {
+ foo::<u32>('0'); //~ ERROR
+ foo::<i32>('0'); //~ ERROR
+ foo::<u64>('0'); //~ ERROR
+ foo::<i64>('0'); //~ ERROR
+ foo::<char>(0u32); //~ ERROR
+}
diff --git a/tests/ui/cast/cast-int-to-char.stderr b/tests/ui/cast/cast-int-to-char.stderr
new file mode 100644
index 000000000..ef606b6ae
--- /dev/null
+++ b/tests/ui/cast/cast-int-to-char.stderr
@@ -0,0 +1,89 @@
+error[E0308]: mismatched types
+ --> $DIR/cast-int-to-char.rs:4:16
+ |
+LL | foo::<u32>('0');
+ | ---------- ^^^ expected `u32`, found `char`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/cast-int-to-char.rs:1:4
+ |
+LL | fn foo<T>(_t: T) {}
+ | ^^^ -----
+help: you can cast a `char` to a `u32`, since a `char` always occupies 4 bytes
+ |
+LL | foo::<u32>('0' as u32);
+ | ++++++
+
+error[E0308]: mismatched types
+ --> $DIR/cast-int-to-char.rs:5:16
+ |
+LL | foo::<i32>('0');
+ | ---------- ^^^ expected `i32`, found `char`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/cast-int-to-char.rs:1:4
+ |
+LL | fn foo<T>(_t: T) {}
+ | ^^^ -----
+help: you can cast a `char` to an `i32`, since a `char` always occupies 4 bytes
+ |
+LL | foo::<i32>('0' as i32);
+ | ++++++
+
+error[E0308]: mismatched types
+ --> $DIR/cast-int-to-char.rs:6:16
+ |
+LL | foo::<u64>('0');
+ | ---------- ^^^ expected `u64`, found `char`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/cast-int-to-char.rs:1:4
+ |
+LL | fn foo<T>(_t: T) {}
+ | ^^^ -----
+help: you can cast a `char` to a `u64`, since a `char` always occupies 4 bytes
+ |
+LL | foo::<u64>('0' as u64);
+ | ++++++
+
+error[E0308]: mismatched types
+ --> $DIR/cast-int-to-char.rs:7:16
+ |
+LL | foo::<i64>('0');
+ | ---------- ^^^ expected `i64`, found `char`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/cast-int-to-char.rs:1:4
+ |
+LL | fn foo<T>(_t: T) {}
+ | ^^^ -----
+help: you can cast a `char` to an `i64`, since a `char` always occupies 4 bytes
+ |
+LL | foo::<i64>('0' as i64);
+ | ++++++
+
+error[E0308]: mismatched types
+ --> $DIR/cast-int-to-char.rs:8:17
+ |
+LL | foo::<char>(0u32);
+ | ----------- ^^^^ expected `char`, found `u32`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/cast-int-to-char.rs:1:4
+ |
+LL | fn foo<T>(_t: T) {}
+ | ^^^ -----
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/cast/cast-macro-lhs.rs b/tests/ui/cast/cast-macro-lhs.rs
new file mode 100644
index 000000000..b509b3239
--- /dev/null
+++ b/tests/ui/cast/cast-macro-lhs.rs
@@ -0,0 +1,12 @@
+// Test to make sure we suggest "consider casting" on the right span
+
+macro_rules! foo {
+ () => { 0 }
+}
+
+fn main() {
+ let x = foo!() as *const [u8];
+ //~^ ERROR cannot cast `usize` to a pointer that is wide
+ //~| NOTE creating a `*const [u8]` requires both an address and a length
+ //~| NOTE consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts`
+}
diff --git a/tests/ui/cast/cast-macro-lhs.stderr b/tests/ui/cast/cast-macro-lhs.stderr
new file mode 100644
index 000000000..db7ce57e1
--- /dev/null
+++ b/tests/ui/cast/cast-macro-lhs.stderr
@@ -0,0 +1,11 @@
+error[E0606]: cannot cast `usize` to a pointer that is wide
+ --> $DIR/cast-macro-lhs.rs:8:23
+ |
+LL | let x = foo!() as *const [u8];
+ | ------ ^^^^^^^^^^^ creating a `*const [u8]` requires both an address and a length
+ | |
+ | consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0606`.
diff --git a/tests/ui/cast/cast-pointee-projection.rs b/tests/ui/cast/cast-pointee-projection.rs
new file mode 100644
index 000000000..f51c5f20f
--- /dev/null
+++ b/tests/ui/cast/cast-pointee-projection.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+trait Tag<'a> {
+ type Type: ?Sized;
+}
+
+trait IntoRaw: for<'a> Tag<'a> {
+ fn into_raw(this: *const <Self as Tag<'_>>::Type) -> *mut <Self as Tag<'_>>::Type;
+}
+
+impl<T: for<'a> Tag<'a>> IntoRaw for T {
+ fn into_raw(this: *const <Self as Tag<'_>>::Type) -> *mut <Self as Tag<'_>>::Type {
+ this as *mut T::Type
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/cast/cast-region-to-uint.rs b/tests/ui/cast/cast-region-to-uint.rs
new file mode 100644
index 000000000..33ec2d276
--- /dev/null
+++ b/tests/ui/cast/cast-region-to-uint.rs
@@ -0,0 +1,6 @@
+// run-pass
+
+pub fn main() {
+ let x: isize = 3;
+ println!("&x={:x}", (&x as *const isize as usize));
+}
diff --git a/tests/ui/cast/cast-rfc0401-2.rs b/tests/ui/cast/cast-rfc0401-2.rs
new file mode 100644
index 000000000..7709aa341
--- /dev/null
+++ b/tests/ui/cast/cast-rfc0401-2.rs
@@ -0,0 +1,8 @@
+// RFC 401 test extracted into distinct file. This is because some the
+// change to suppress "derived" errors wound up suppressing this error
+// message, since the fallback for `3` doesn't occur.
+
+fn main() {
+ let _ = 3 as bool;
+ //~^ ERROR cannot cast as `bool`
+}
diff --git a/tests/ui/cast/cast-rfc0401-2.stderr b/tests/ui/cast/cast-rfc0401-2.stderr
new file mode 100644
index 000000000..52f6af78a
--- /dev/null
+++ b/tests/ui/cast/cast-rfc0401-2.stderr
@@ -0,0 +1,9 @@
+error[E0054]: cannot cast as `bool`
+ --> $DIR/cast-rfc0401-2.rs:6:13
+ |
+LL | let _ = 3 as bool;
+ | ^^^^^^^^^ help: compare with zero instead: `3 != 0`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0054`.
diff --git a/tests/ui/cast/cast-rfc0401-vtable-kinds.rs b/tests/ui/cast/cast-rfc0401-vtable-kinds.rs
new file mode 100644
index 000000000..249481467
--- /dev/null
+++ b/tests/ui/cast/cast-rfc0401-vtable-kinds.rs
@@ -0,0 +1,62 @@
+// run-pass
+// Check that you can cast between different pointers to trait objects
+// whose vtable have the same kind (both lengths, or both trait pointers).
+
+#![feature(unsized_tuple_coercion)]
+
+trait Foo<T> {
+ fn foo(&self, _: T) -> u32 { 42 }
+}
+
+trait Bar {
+ fn bar(&self) { println!("Bar!"); }
+}
+
+impl<T> Foo<T> for () {}
+impl Foo<u32> for u32 { fn foo(&self, _: u32) -> u32 { self+43 } }
+impl Bar for () {}
+
+unsafe fn round_trip_and_call<'a>(t: *const (dyn Foo<u32>+'a)) -> u32 {
+ let foo_e : *const dyn Foo<u16> = t as *const _;
+ let r_1 = foo_e as *mut dyn Foo<u32>;
+
+ (&*r_1).foo(0)
+}
+
+#[repr(C)]
+struct FooS<T:?Sized>(T);
+#[repr(C)]
+struct BarS<T:?Sized>(T);
+
+fn foo_to_bar<T:?Sized>(u: *const FooS<T>) -> *const BarS<T> {
+ u as *const BarS<T>
+}
+
+fn tuple_i32_to_u32<T:?Sized>(u: *const (i32, T)) -> *const (u32, T) {
+ u as *const (u32, T)
+}
+
+
+fn main() {
+ let x = 4u32;
+ let y : &dyn Foo<u32> = &x;
+ let fl = unsafe { round_trip_and_call(y as *const dyn Foo<u32>) };
+ assert_eq!(fl, (43+4));
+
+ let s = FooS([0,1,2]);
+ let u: &FooS<[u32]> = &s;
+ let u: *const FooS<[u32]> = u;
+ let bar_ref : *const BarS<[u32]> = foo_to_bar(u);
+ let z : &BarS<[u32]> = unsafe{&*bar_ref};
+ assert_eq!(&z.0, &[0,1,2]);
+
+ // this assumes that tuple reprs for (i32, _) and (u32, _) are
+ // the same.
+ let s = (0i32, [0, 1, 2]);
+ let u: &(i32, [u8]) = &s;
+ let u: *const (i32, [u8]) = u;
+ let u_u32 : *const (u32, [u8]) = tuple_i32_to_u32(u);
+ unsafe {
+ assert_eq!(&(*u_u32).1, &[0, 1, 2]);
+ }
+}
diff --git a/tests/ui/cast/cast-rfc0401.rs b/tests/ui/cast/cast-rfc0401.rs
new file mode 100644
index 000000000..9a9875416
--- /dev/null
+++ b/tests/ui/cast/cast-rfc0401.rs
@@ -0,0 +1,169 @@
+// run-pass
+
+#![allow(dead_code)]
+
+use std::vec;
+
+enum Simple {
+ A,
+ B,
+ C
+}
+
+enum Valued {
+ H8=163,
+ Z=0,
+ X=256,
+ H7=67,
+}
+
+enum ValuedSigned {
+ M1=-1,
+ P1=1
+}
+
+fn main()
+{
+ // coercion-cast
+ let mut it = vec![137].into_iter();
+ let itr: &mut vec::IntoIter<u32> = &mut it;
+ assert_eq!((itr as &mut dyn Iterator<Item=u32>).next(), Some(137));
+ assert_eq!((itr as &mut dyn Iterator<Item=u32>).next(), None);
+
+ assert_eq!(Some(4u32) as Option<u32>, Some(4u32));
+ assert_eq!((1u32,2u32) as (u32,u32), (1,2));
+
+ // this isn't prim-int-cast. Check that it works.
+ assert_eq!(false as bool, false);
+ assert_eq!(true as bool, true);
+
+ // numeric-cast
+ let l: u64 = 0x8090a0b0c0d0e0f0;
+ let lsz: usize = l as usize;
+ assert_eq!(l as u32, 0xc0d0e0f0);
+
+ // numeric-cast
+ assert_eq!(l as u8, 0xf0);
+ assert_eq!(l as i8,-0x10);
+ assert_eq!(l as u32, 0xc0d0e0f0);
+ assert_eq!(l as u32 as usize as u32, l as u32);
+ assert_eq!(l as i32,-0x3f2f1f10);
+ assert_eq!(l as i32 as isize as i32, l as i32);
+ assert_eq!(l as i64,-0x7f6f5f4f3f2f1f10);
+
+ assert_eq!(0 as f64, 0f64);
+ assert_eq!(1 as f64, 1f64);
+
+ assert_eq!(l as f64, 9264081114510712022f64);
+
+ assert_eq!(l as i64 as f64, -9182662959198838444f64);
+// float overflow : needs fixing
+// assert_eq!(l as f32 as i64 as u64, 9264082620822882088u64);
+// assert_eq!(l as i64 as f32 as i64, 9182664080220408446i64);
+
+ assert_eq!(4294967040f32 as u32, 0xffffff00u32);
+ assert_eq!(1.844674407370955e19f64 as u64, 0xfffffffffffff800u64);
+
+ assert_eq!(9.223372036854775e18f64 as i64, 0x7ffffffffffffc00i64);
+ assert_eq!(-9.223372036854776e18f64 as i64, 0x8000000000000000u64 as i64);
+
+ // addr-ptr-cast/ptr-addr-cast (thin ptr)
+ let p: *const [u8; 1] = lsz as *const [u8; 1];
+ assert_eq!(p as usize, lsz);
+
+ // ptr-ptr-cast (thin ptr)
+ let w: *const () = p as *const ();
+ assert_eq!(w as usize, lsz);
+
+ // ptr-ptr-cast (fat->thin)
+ let u: *const [u8] = unsafe{&*p};
+ assert_eq!(u as *const u8, p as *const u8);
+ assert_eq!(u as *const u16, p as *const u16);
+
+ // ptr-ptr-cast (Length vtables)
+ let mut l : [u8; 2] = [0,1];
+ let w: *mut [u16; 2] = &mut l as *mut [u8; 2] as *mut _;
+ let w: *mut [u16] = unsafe {&mut *w};
+ let w_u8 : *const [u8] = w as *const [u8];
+ assert_eq!(unsafe{&*w_u8}, &l);
+
+ let s: *mut str = w as *mut str;
+ let l_via_str = unsafe{&*(s as *const [u8])};
+ assert_eq!(&l, l_via_str);
+
+ // ptr-ptr-cast (Length vtables, check length is preserved)
+ let l: [[u8; 3]; 2] = [[3, 2, 6], [4, 5, 1]];
+ let p: *const [[u8; 3]] = &l;
+ let p: &[[u8; 2]] = unsafe {&*(p as *const [[u8; 2]])};
+ assert_eq!(p, [[3, 2], [6, 4]]);
+
+ // enum-cast
+ assert_eq!(Simple::A as u8, 0);
+ assert_eq!(Simple::B as u8, 1);
+
+ assert_eq!(Valued::H8 as i8, -93);
+ assert_eq!(Valued::H7 as i8, 67);
+ assert_eq!(Valued::Z as i8, 0);
+
+ assert_eq!(Valued::H8 as u8, 163);
+ assert_eq!(Valued::H7 as u8, 67);
+ assert_eq!(Valued::Z as u8, 0);
+
+ assert_eq!(Valued::H8 as u16, 163);
+ assert_eq!(Valued::Z as u16, 0);
+ assert_eq!(Valued::H8 as u16, 163);
+ assert_eq!(Valued::Z as u16, 0);
+
+ assert_eq!(ValuedSigned::M1 as u16, 65535);
+ assert_eq!(ValuedSigned::M1 as i16, -1);
+ assert_eq!(ValuedSigned::P1 as u16, 1);
+ assert_eq!(ValuedSigned::P1 as i16, 1);
+
+ // prim-int-cast
+ assert_eq!(false as u16, 0);
+ assert_eq!(true as u16, 1);
+ assert_eq!(false as i64, 0);
+ assert_eq!(true as i64, 1);
+ assert_eq!('a' as u32, 0x61);
+ assert_eq!('a' as u16, 0x61);
+ assert_eq!('a' as u8, 0x61);
+ assert_eq!('א' as u8, 0xd0);
+ assert_eq!('א' as u16, 0x5d0);
+ assert_eq!('א' as u32, 0x5d0);
+ assert_eq!('🐵' as u8, 0x35);
+ assert_eq!('🐵' as u16, 0xf435);
+ assert_eq!('🐵' as u32, 0x1f435);
+ assert_eq!('英' as i16, -0x7d0f);
+ assert_eq!('英' as u16, 0x82f1);
+
+ // u8-char-cast
+ assert_eq!(0x61 as char, 'a');
+ assert_eq!(0u8 as char, '\0');
+ assert_eq!(0xd7 as char, '×');
+
+ // array-ptr-cast
+ let x = [1,2,3];
+ let first : *const u32 = &x[0];
+
+ assert_eq!(first, &x as *const _);
+ assert_eq!(first, &x as *const u32);
+
+ // fptr-addr-cast
+ fn foo() {
+ println!("foo!");
+ }
+ fn bar() {
+ println!("bar!");
+ }
+
+ assert!(foo as usize != bar as usize);
+
+ // Taking a few bits of a function's address is totally pointless and we detect that
+ assert_eq!(foo as i16, foo as usize as i16);
+
+ // fptr-ptr-cast
+
+ assert_eq!(foo as *const u8 as usize, foo as usize);
+ assert!(foo as *const u32 != first);
+}
+fn foo() { }
diff --git a/tests/ui/cast/cast-to-bare-fn.rs b/tests/ui/cast/cast-to-bare-fn.rs
new file mode 100644
index 000000000..1992f2637
--- /dev/null
+++ b/tests/ui/cast/cast-to-bare-fn.rs
@@ -0,0 +1,10 @@
+fn foo(_x: isize) { }
+
+fn main() {
+ let v: u64 = 5;
+ let x = foo as extern "C" fn() -> isize;
+ //~^ ERROR non-primitive cast
+ let y = v as extern "Rust" fn(isize) -> (isize, isize);
+ //~^ ERROR non-primitive cast
+ y(x());
+}
diff --git a/tests/ui/cast/cast-to-bare-fn.stderr b/tests/ui/cast/cast-to-bare-fn.stderr
new file mode 100644
index 000000000..d97b0c5f8
--- /dev/null
+++ b/tests/ui/cast/cast-to-bare-fn.stderr
@@ -0,0 +1,15 @@
+error[E0605]: non-primitive cast: `fn(isize) {foo}` as `extern "C" fn() -> isize`
+ --> $DIR/cast-to-bare-fn.rs:5:13
+ |
+LL | let x = foo as extern "C" fn() -> isize;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
+
+error[E0605]: non-primitive cast: `u64` as `fn(isize) -> (isize, isize)`
+ --> $DIR/cast-to-bare-fn.rs:7:13
+ |
+LL | let y = v as extern "Rust" fn(isize) -> (isize, isize);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0605`.
diff --git a/tests/ui/cast/cast-to-infer-ty.rs b/tests/ui/cast/cast-to-infer-ty.rs
new file mode 100644
index 000000000..053ebb621
--- /dev/null
+++ b/tests/ui/cast/cast-to-infer-ty.rs
@@ -0,0 +1,8 @@
+// run-pass
+// Check that we allow a cast to `_` so long as the target type can be
+// inferred elsewhere.
+
+pub fn main() {
+ let i: *const i32 = 0 as _;
+ assert!(i.is_null());
+}
diff --git a/tests/ui/cast/cast-to-nil.rs b/tests/ui/cast/cast-to-nil.rs
new file mode 100644
index 000000000..085bb09e6
--- /dev/null
+++ b/tests/ui/cast/cast-to-nil.rs
@@ -0,0 +1,2 @@
+// error-pattern: non-primitive cast: `u32` as `()`
+fn main() { let u = 0u32 as (); }
diff --git a/tests/ui/cast/cast-to-nil.stderr b/tests/ui/cast/cast-to-nil.stderr
new file mode 100644
index 000000000..29a9baffd
--- /dev/null
+++ b/tests/ui/cast/cast-to-nil.stderr
@@ -0,0 +1,9 @@
+error[E0605]: non-primitive cast: `u32` as `()`
+ --> $DIR/cast-to-nil.rs:2:21
+ |
+LL | fn main() { let u = 0u32 as (); }
+ | ^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0605`.
diff --git a/tests/ui/cast/cast-to-unsized-trait-object-suggestion.rs b/tests/ui/cast/cast-to-unsized-trait-object-suggestion.rs
new file mode 100644
index 000000000..5342b595c
--- /dev/null
+++ b/tests/ui/cast/cast-to-unsized-trait-object-suggestion.rs
@@ -0,0 +1,4 @@
+fn main() {
+ &1 as dyn Send; //~ ERROR cast to unsized
+ Box::new(1) as dyn Send; //~ ERROR cast to unsized
+}
diff --git a/tests/ui/cast/cast-to-unsized-trait-object-suggestion.stderr b/tests/ui/cast/cast-to-unsized-trait-object-suggestion.stderr
new file mode 100644
index 000000000..3b5b8ea69
--- /dev/null
+++ b/tests/ui/cast/cast-to-unsized-trait-object-suggestion.stderr
@@ -0,0 +1,19 @@
+error[E0620]: cast to unsized type: `&{integer}` as `dyn Send`
+ --> $DIR/cast-to-unsized-trait-object-suggestion.rs:2:5
+ |
+LL | &1 as dyn Send;
+ | ^^^^^^--------
+ | |
+ | help: try casting to a reference instead: `&dyn Send`
+
+error[E0620]: cast to unsized type: `Box<{integer}>` as `dyn Send`
+ --> $DIR/cast-to-unsized-trait-object-suggestion.rs:3:5
+ |
+LL | Box::new(1) as dyn Send;
+ | ^^^^^^^^^^^^^^^--------
+ | |
+ | help: you can cast to a `Box` instead: `Box<dyn Send>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0620`.
diff --git a/tests/ui/cast/cast.rs b/tests/ui/cast/cast.rs
new file mode 100644
index 000000000..218275c4d
--- /dev/null
+++ b/tests/ui/cast/cast.rs
@@ -0,0 +1,21 @@
+// run-pass
+
+#![allow(unused_assignments)]
+#![allow(unused_variables)]
+
+pub fn main() {
+ let i: isize = 'Q' as isize;
+ assert_eq!(i, 0x51);
+ let u: u32 = i as u32;
+ assert_eq!(u, 0x51 as u32);
+ assert_eq!(u, 'Q' as u32);
+ assert_eq!(i as u8, 'Q' as u8);
+ assert_eq!(i as u8 as i8, 'Q' as u8 as i8);
+ assert_eq!(0x51 as char, 'Q');
+ assert_eq!(0 as u32, false as u32);
+
+ // Test that `_` is correctly inferred.
+ let x = &"hello";
+ let mut y = x as *const _;
+ y = core::ptr::null_mut();
+}
diff --git a/tests/ui/cast/casts-differing-anon.rs b/tests/ui/cast/casts-differing-anon.rs
new file mode 100644
index 000000000..d4a0f9613
--- /dev/null
+++ b/tests/ui/cast/casts-differing-anon.rs
@@ -0,0 +1,22 @@
+use std::fmt;
+
+fn foo() -> Box<impl fmt::Debug+?Sized> {
+ let x : Box<[u8]> = Box::new([0]);
+ x
+}
+fn bar() -> Box<impl fmt::Debug+?Sized> {
+ let y: Box<dyn fmt::Debug> = Box::new([0]);
+ y
+}
+
+fn main() {
+ let f = foo();
+ let b = bar();
+
+ // this is an `*mut [u8]` in practice
+ let f_raw : *mut _ = Box::into_raw(f);
+ // this is an `*mut fmt::Debug` in practice
+ let mut b_raw = Box::into_raw(b);
+ // ... and they should not be mixable
+ b_raw = f_raw as *mut _; //~ ERROR is invalid
+}
diff --git a/tests/ui/cast/casts-differing-anon.stderr b/tests/ui/cast/casts-differing-anon.stderr
new file mode 100644
index 000000000..f9abfb522
--- /dev/null
+++ b/tests/ui/cast/casts-differing-anon.stderr
@@ -0,0 +1,11 @@
+error[E0606]: casting `*mut impl Debug + ?Sized` as `*mut impl Debug + ?Sized` is invalid
+ --> $DIR/casts-differing-anon.rs:21:13
+ |
+LL | b_raw = f_raw as *mut _;
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: vtable kinds may not match
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0606`.
diff --git a/tests/ui/cast/casts-issue-46365.rs b/tests/ui/cast/casts-issue-46365.rs
new file mode 100644
index 000000000..50aa1a856
--- /dev/null
+++ b/tests/ui/cast/casts-issue-46365.rs
@@ -0,0 +1,8 @@
+struct Lorem {
+ ipsum: Ipsum //~ ERROR cannot find type `Ipsum`
+}
+
+fn main() {
+ // Testing `as` casts, so deliberately not using `ptr::null`.
+ let _foo: *mut Lorem = 0 as *mut _; // no error here
+}
diff --git a/tests/ui/cast/casts-issue-46365.stderr b/tests/ui/cast/casts-issue-46365.stderr
new file mode 100644
index 000000000..841754736
--- /dev/null
+++ b/tests/ui/cast/casts-issue-46365.stderr
@@ -0,0 +1,9 @@
+error[E0412]: cannot find type `Ipsum` in this scope
+ --> $DIR/casts-issue-46365.rs:2:12
+ |
+LL | ipsum: Ipsum
+ | ^^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/cast/codegen-object-shim.rs b/tests/ui/cast/codegen-object-shim.rs
new file mode 100644
index 000000000..9a85a50eb
--- /dev/null
+++ b/tests/ui/cast/codegen-object-shim.rs
@@ -0,0 +1,6 @@
+// run-pass
+
+fn main() {
+ assert_eq!((ToString::to_string as fn(&(dyn ToString+'static)) -> String)(&"foo"),
+ String::from("foo"));
+}
diff --git a/tests/ui/cast/fat-ptr-cast-rpass.rs b/tests/ui/cast/fat-ptr-cast-rpass.rs
new file mode 100644
index 000000000..f5747eb8b
--- /dev/null
+++ b/tests/ui/cast/fat-ptr-cast-rpass.rs
@@ -0,0 +1,34 @@
+// run-pass
+
+#![feature(ptr_metadata)]
+
+trait Foo {
+ fn foo(&self) {}
+}
+
+struct Bar;
+
+impl Foo for Bar {}
+
+fn main() {
+ // Test we can turn a fat pointer to array back into a thin pointer.
+ let a: *const [i32] = &[1, 2, 3];
+ let b = a as *const [i32; 2];
+ unsafe {
+ assert_eq!(*b, [1, 2]);
+ }
+
+ // Test conversion to an address (usize).
+ let a: *const [i32; 3] = &[1, 2, 3];
+ let b: *const [i32] = a;
+ assert_eq!(a as usize, b as *const () as usize);
+
+ // And conversion to a void pointer/address for trait objects too.
+ let a: *mut dyn Foo = &mut Bar;
+ let b = a as *mut () as usize;
+ let c = a as *const () as usize;
+ let d = a.to_raw_parts().0 as usize;
+
+ assert_eq!(b, d);
+ assert_eq!(c, d);
+}
diff --git a/tests/ui/cast/fat-ptr-cast.rs b/tests/ui/cast/fat-ptr-cast.rs
new file mode 100644
index 000000000..b5276dc61
--- /dev/null
+++ b/tests/ui/cast/fat-ptr-cast.rs
@@ -0,0 +1,33 @@
+trait Trait {}
+
+// Make sure casts between thin-pointer <-> fat pointer obey RFC401
+fn main() {
+ let a: &[i32] = &[1, 2, 3];
+ let b: Box<[i32]> = Box::new([1, 2, 3]);
+ let p = a as *const [i32];
+ let q = a.as_ptr();
+
+ a as usize; //~ ERROR casting
+ a as isize; //~ ERROR casting
+ a as i16; //~ ERROR casting `&[i32]` as `i16` is invalid
+ a as u32; //~ ERROR casting `&[i32]` as `u32` is invalid
+ b as usize; //~ ERROR non-primitive cast
+ p as usize;
+ //~^ ERROR casting
+
+ // #22955
+ q as *const [i32]; //~ ERROR cannot cast
+
+ // #21397
+ let t: *mut (dyn Trait + 'static) = 0 as *mut _;
+ //~^ ERROR cannot cast `usize` to a pointer that is wide
+ let mut fail: *const str = 0 as *const str;
+ //~^ ERROR cannot cast `usize` to a pointer that is wide
+ let mut fail2: *const str = 0isize as *const str;
+ //~^ ERROR cannot cast `isize` to a pointer that is wide
+}
+
+fn foo<T: ?Sized>() {
+ let s = 0 as *const T;
+ //~^ ERROR cannot cast `usize` to a pointer that may be wide
+}
diff --git a/tests/ui/cast/fat-ptr-cast.stderr b/tests/ui/cast/fat-ptr-cast.stderr
new file mode 100644
index 000000000..18e7b68ff
--- /dev/null
+++ b/tests/ui/cast/fat-ptr-cast.stderr
@@ -0,0 +1,88 @@
+error[E0606]: casting `&[i32]` as `usize` is invalid
+ --> $DIR/fat-ptr-cast.rs:10:5
+ |
+LL | a as usize;
+ | ^^^^^^^^^^
+ |
+ = help: cast through a raw pointer first
+
+error[E0606]: casting `&[i32]` as `isize` is invalid
+ --> $DIR/fat-ptr-cast.rs:11:5
+ |
+LL | a as isize;
+ | ^^^^^^^^^^
+ |
+ = help: cast through a raw pointer first
+
+error[E0606]: casting `&[i32]` as `i16` is invalid
+ --> $DIR/fat-ptr-cast.rs:12:5
+ |
+LL | a as i16;
+ | ^^^^^^^^
+ |
+ = help: cast through a raw pointer first
+
+error[E0606]: casting `&[i32]` as `u32` is invalid
+ --> $DIR/fat-ptr-cast.rs:13:5
+ |
+LL | a as u32;
+ | ^^^^^^^^
+ |
+ = help: cast through a raw pointer first
+
+error[E0605]: non-primitive cast: `Box<[i32]>` as `usize`
+ --> $DIR/fat-ptr-cast.rs:14:5
+ |
+LL | b as usize;
+ | ^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error[E0606]: casting `*const [i32]` as `usize` is invalid
+ --> $DIR/fat-ptr-cast.rs:15:5
+ |
+LL | p as usize;
+ | ^^^^^^^^^^
+ |
+ = help: cast through a thin pointer first
+
+error[E0607]: cannot cast thin pointer `*const i32` to fat pointer `*const [i32]`
+ --> $DIR/fat-ptr-cast.rs:19:5
+ |
+LL | q as *const [i32];
+ | ^^^^^^^^^^^^^^^^^
+
+error[E0606]: cannot cast `usize` to a pointer that is wide
+ --> $DIR/fat-ptr-cast.rs:22:46
+ |
+LL | let t: *mut (dyn Trait + 'static) = 0 as *mut _;
+ | - ^^^^^^ creating a `*mut (dyn Trait + 'static)` requires both an address and a vtable
+ | |
+ | consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts`
+
+error[E0606]: cannot cast `usize` to a pointer that is wide
+ --> $DIR/fat-ptr-cast.rs:24:37
+ |
+LL | let mut fail: *const str = 0 as *const str;
+ | - ^^^^^^^^^^ creating a `*const str` requires both an address and a length
+ | |
+ | consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts`
+
+error[E0606]: cannot cast `isize` to a pointer that is wide
+ --> $DIR/fat-ptr-cast.rs:26:43
+ |
+LL | let mut fail2: *const str = 0isize as *const str;
+ | ------ ^^^^^^^^^^ creating a `*const str` requires both an address and a length
+ | |
+ | consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts`
+
+error[E0606]: cannot cast `usize` to a pointer that may be wide
+ --> $DIR/fat-ptr-cast.rs:31:18
+ |
+LL | let s = 0 as *const T;
+ | - ^^^^^^^^ creating a `*const T` requires both an address and type-specific metadata
+ | |
+ | consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts`
+
+error: aborting due to 11 previous errors
+
+Some errors have detailed explanations: E0605, E0606, E0607.
+For more information about an error, try `rustc --explain E0605`.
diff --git a/tests/ui/cast/issue-106883-is-empty.rs b/tests/ui/cast/issue-106883-is-empty.rs
new file mode 100644
index 000000000..27e0816dd
--- /dev/null
+++ b/tests/ui/cast/issue-106883-is-empty.rs
@@ -0,0 +1,27 @@
+use std::ops::Deref;
+
+struct Foo;
+
+impl Deref for Foo {
+ type Target = [u8];
+
+ fn deref(&self) -> &Self::Target {
+ &[]
+ }
+}
+
+fn main() {
+ let _ = "foo" as bool;
+ //~^ ERROR casting `&'static str` as `bool` is invalid [E0606]
+
+ let _ = String::from("foo") as bool;
+ //~^ ERROR non-primitive cast: `String` as `bool` [E0605]
+
+ let _ = Foo as bool;
+ //~^ ERROR non-primitive cast: `Foo` as `bool` [E0605]
+}
+
+fn _slice(bar: &[i32]) -> bool {
+ bar as bool
+ //~^ ERROR casting `&[i32]` as `bool` is invalid [E0606]
+}
diff --git a/tests/ui/cast/issue-106883-is-empty.stderr b/tests/ui/cast/issue-106883-is-empty.stderr
new file mode 100644
index 000000000..7115c7704
--- /dev/null
+++ b/tests/ui/cast/issue-106883-is-empty.stderr
@@ -0,0 +1,58 @@
+error[E0606]: casting `&'static str` as `bool` is invalid
+ --> $DIR/issue-106883-is-empty.rs:14:13
+ |
+LL | let _ = "foo" as bool;
+ | ^^^^^^^^^^^^^
+ |
+help: consider using the `is_empty` method on `&'static str` to determine if it contains anything
+ |
+LL | let _ = !"foo".is_empty();
+ | + ~~~~~~~~~~~
+
+error[E0605]: non-primitive cast: `String` as `bool`
+ --> $DIR/issue-106883-is-empty.rs:17:13
+ |
+LL | let _ = String::from("foo") as bool;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+ |
+note: this expression `Deref`s to `str` which implements `is_empty`
+ --> $DIR/issue-106883-is-empty.rs:17:13
+ |
+LL | let _ = String::from("foo") as bool;
+ | ^^^^^^^^^^^^^^^^^^^
+help: consider using the `is_empty` method on `String` to determine if it contains anything
+ |
+LL | let _ = !String::from("foo").is_empty();
+ | + ~~~~~~~~~~~
+
+error[E0605]: non-primitive cast: `Foo` as `bool`
+ --> $DIR/issue-106883-is-empty.rs:20:13
+ |
+LL | let _ = Foo as bool;
+ | ^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+ |
+note: this expression `Deref`s to `[u8]` which implements `is_empty`
+ --> $DIR/issue-106883-is-empty.rs:20:13
+ |
+LL | let _ = Foo as bool;
+ | ^^^
+help: consider using the `is_empty` method on `Foo` to determine if it contains anything
+ |
+LL | let _ = !Foo.is_empty();
+ | + ~~~~~~~~~~~
+
+error[E0606]: casting `&[i32]` as `bool` is invalid
+ --> $DIR/issue-106883-is-empty.rs:25:5
+ |
+LL | bar as bool
+ | ^^^^^^^^^^^
+ |
+help: consider using the `is_empty` method on `&[i32]` to determine if it contains anything
+ |
+LL | !bar.is_empty()
+ | + ~~~~~~~~~~~
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0605, E0606.
+For more information about an error, try `rustc --explain E0605`.
diff --git a/tests/ui/cast/issue-10991.rs b/tests/ui/cast/issue-10991.rs
new file mode 100644
index 000000000..c36829fdf
--- /dev/null
+++ b/tests/ui/cast/issue-10991.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let nil = ();
+ let _t = nil as usize; //~ ERROR: non-primitive cast: `()` as `usize`
+}
diff --git a/tests/ui/cast/issue-10991.stderr b/tests/ui/cast/issue-10991.stderr
new file mode 100644
index 000000000..5b8a18233
--- /dev/null
+++ b/tests/ui/cast/issue-10991.stderr
@@ -0,0 +1,9 @@
+error[E0605]: non-primitive cast: `()` as `usize`
+ --> $DIR/issue-10991.rs:3:14
+ |
+LL | let _t = nil as usize;
+ | ^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0605`.
diff --git a/tests/ui/cast/issue-17444.rs b/tests/ui/cast/issue-17444.rs
new file mode 100644
index 000000000..906b443c9
--- /dev/null
+++ b/tests/ui/cast/issue-17444.rs
@@ -0,0 +1,8 @@
+enum Test {
+ Foo = 0
+}
+
+fn main() {
+ let _x = Test::Foo as *const isize;
+ //~^ ERROR casting `Test` as `*const isize` is invalid
+}
diff --git a/tests/ui/cast/issue-17444.stderr b/tests/ui/cast/issue-17444.stderr
new file mode 100644
index 000000000..1097079df
--- /dev/null
+++ b/tests/ui/cast/issue-17444.stderr
@@ -0,0 +1,9 @@
+error[E0606]: casting `Test` as `*const isize` is invalid
+ --> $DIR/issue-17444.rs:6:14
+ |
+LL | let _x = Test::Foo as *const isize;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0606`.
diff --git a/tests/ui/cast/issue-84213.fixed b/tests/ui/cast/issue-84213.fixed
new file mode 100644
index 000000000..b5c4a7752
--- /dev/null
+++ b/tests/ui/cast/issue-84213.fixed
@@ -0,0 +1,16 @@
+// run-rustfix
+
+struct Something {
+ pub field: u32,
+}
+
+fn main() {
+ let mut something = Something { field: 1337 };
+ let _ = something.field;
+
+ let _pointer_to_something = &something as *const Something;
+ //~^ ERROR: non-primitive cast
+
+ let _mut_pointer_to_something = &mut something as *mut Something;
+ //~^ ERROR: non-primitive cast
+}
diff --git a/tests/ui/cast/issue-84213.rs b/tests/ui/cast/issue-84213.rs
new file mode 100644
index 000000000..6eb81291a
--- /dev/null
+++ b/tests/ui/cast/issue-84213.rs
@@ -0,0 +1,16 @@
+// run-rustfix
+
+struct Something {
+ pub field: u32,
+}
+
+fn main() {
+ let mut something = Something { field: 1337 };
+ let _ = something.field;
+
+ let _pointer_to_something = something as *const Something;
+ //~^ ERROR: non-primitive cast
+
+ let _mut_pointer_to_something = something as *mut Something;
+ //~^ ERROR: non-primitive cast
+}
diff --git a/tests/ui/cast/issue-84213.stderr b/tests/ui/cast/issue-84213.stderr
new file mode 100644
index 000000000..025970e54
--- /dev/null
+++ b/tests/ui/cast/issue-84213.stderr
@@ -0,0 +1,25 @@
+error[E0605]: non-primitive cast: `Something` as `*const Something`
+ --> $DIR/issue-84213.rs:11:33
+ |
+LL | let _pointer_to_something = something as *const Something;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
+ |
+help: consider borrowing the value
+ |
+LL | let _pointer_to_something = &something as *const Something;
+ | +
+
+error[E0605]: non-primitive cast: `Something` as `*mut Something`
+ --> $DIR/issue-84213.rs:14:37
+ |
+LL | let _mut_pointer_to_something = something as *mut Something;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
+ |
+help: consider borrowing the value
+ |
+LL | let _mut_pointer_to_something = &mut something as *mut Something;
+ | ++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0605`.
diff --git a/tests/ui/cast/issue-85586.rs b/tests/ui/cast/issue-85586.rs
new file mode 100644
index 000000000..78816582b
--- /dev/null
+++ b/tests/ui/cast/issue-85586.rs
@@ -0,0 +1,10 @@
+// Check that errors for unresolved types in cast expressions are reported
+// for the offending subexpression, not the whole cast expression.
+
+#![allow(unused_variables)]
+
+fn main() {
+ let a = [1, 2, 3].iter().sum();
+ let b = (a + 1) as usize;
+ //~^ ERROR: type annotations needed [E0282]
+}
diff --git a/tests/ui/cast/issue-85586.stderr b/tests/ui/cast/issue-85586.stderr
new file mode 100644
index 000000000..ed8a6fc62
--- /dev/null
+++ b/tests/ui/cast/issue-85586.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+ --> $DIR/issue-85586.rs:8:13
+ |
+LL | let b = (a + 1) as usize;
+ | ^^^^^^^ cannot infer type
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/cast/issue-88621.rs b/tests/ui/cast/issue-88621.rs
new file mode 100644
index 000000000..1679793ee
--- /dev/null
+++ b/tests/ui/cast/issue-88621.rs
@@ -0,0 +1,11 @@
+#[repr(u8)]
+enum Kind2 {
+ Foo() = 1,
+ Bar{} = 2,
+ Baz = 3,
+}
+
+fn main() {
+ let _ = Kind2::Foo() as u8;
+ //~^ ERROR non-primitive cast
+}
diff --git a/tests/ui/cast/issue-88621.stderr b/tests/ui/cast/issue-88621.stderr
new file mode 100644
index 000000000..886145c1b
--- /dev/null
+++ b/tests/ui/cast/issue-88621.stderr
@@ -0,0 +1,9 @@
+error[E0605]: non-primitive cast: `Kind2` as `u8`
+ --> $DIR/issue-88621.rs:9:13
+ |
+LL | let _ = Kind2::Foo() as u8;
+ | ^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0605`.
diff --git a/tests/ui/cast/issue-89497.fixed b/tests/ui/cast/issue-89497.fixed
new file mode 100644
index 000000000..04c10a5f7
--- /dev/null
+++ b/tests/ui/cast/issue-89497.fixed
@@ -0,0 +1,10 @@
+// Regression test for issue #89497.
+
+// run-rustfix
+
+fn main() {
+ let pointer: usize = &1_i32 as *const i32 as usize;
+ let _reference: &'static i32 = unsafe { &*(pointer as *const i32) };
+ //~^ ERROR: non-primitive cast
+ //~| HELP: consider borrowing the value
+}
diff --git a/tests/ui/cast/issue-89497.rs b/tests/ui/cast/issue-89497.rs
new file mode 100644
index 000000000..76301b704
--- /dev/null
+++ b/tests/ui/cast/issue-89497.rs
@@ -0,0 +1,10 @@
+// Regression test for issue #89497.
+
+// run-rustfix
+
+fn main() {
+ let pointer: usize = &1_i32 as *const i32 as usize;
+ let _reference: &'static i32 = unsafe { pointer as *const i32 as &'static i32 };
+ //~^ ERROR: non-primitive cast
+ //~| HELP: consider borrowing the value
+}
diff --git a/tests/ui/cast/issue-89497.stderr b/tests/ui/cast/issue-89497.stderr
new file mode 100644
index 000000000..bf3c3537f
--- /dev/null
+++ b/tests/ui/cast/issue-89497.stderr
@@ -0,0 +1,15 @@
+error[E0605]: non-primitive cast: `*const i32` as `&'static i32`
+ --> $DIR/issue-89497.rs:7:45
+ |
+LL | let _reference: &'static i32 = unsafe { pointer as *const i32 as &'static i32 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
+ |
+help: consider borrowing the value
+ |
+LL - let _reference: &'static i32 = unsafe { pointer as *const i32 as &'static i32 };
+LL + let _reference: &'static i32 = unsafe { &*(pointer as *const i32) };
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0605`.
diff --git a/tests/ui/cast/supported-cast.rs b/tests/ui/cast/supported-cast.rs
new file mode 100644
index 000000000..ff41ce6c7
--- /dev/null
+++ b/tests/ui/cast/supported-cast.rs
@@ -0,0 +1,206 @@
+// run-pass
+
+pub fn main() {
+ let f = 1_usize as *const String;
+ println!("{:?}", f as isize);
+ println!("{:?}", f as usize);
+ println!("{:?}", f as i8);
+ println!("{:?}", f as i16);
+ println!("{:?}", f as i32);
+ println!("{:?}", f as i64);
+ println!("{:?}", f as u8);
+ println!("{:?}", f as u16);
+ println!("{:?}", f as u32);
+ println!("{:?}", f as u64);
+
+ println!("{:?}", 1 as isize);
+ println!("{:?}", 1 as usize);
+ println!("{:?}", 1 as *const String);
+ println!("{:?}", 1 as i8);
+ println!("{:?}", 1 as i16);
+ println!("{:?}", 1 as i32);
+ println!("{:?}", 1 as i64);
+ println!("{:?}", 1 as u8);
+ println!("{:?}", 1 as u16);
+ println!("{:?}", 1 as u32);
+ println!("{:?}", 1 as u64);
+ println!("{:?}", 1 as f32);
+ println!("{:?}", 1 as f64);
+
+ println!("{:?}", 1_usize as isize);
+ println!("{:?}", 1_usize as usize);
+ println!("{:?}", 1_usize as *const String);
+ println!("{:?}", 1_usize as i8);
+ println!("{:?}", 1_usize as i16);
+ println!("{:?}", 1_usize as i32);
+ println!("{:?}", 1_usize as i64);
+ println!("{:?}", 1_usize as u8);
+ println!("{:?}", 1_usize as u16);
+ println!("{:?}", 1_usize as u32);
+ println!("{:?}", 1_usize as u64);
+ println!("{:?}", 1_usize as f32);
+ println!("{:?}", 1_usize as f64);
+
+ println!("{:?}", 1i8 as isize);
+ println!("{:?}", 1i8 as usize);
+ println!("{:?}", 1i8 as *const String);
+ println!("{:?}", 1i8 as i8);
+ println!("{:?}", 1i8 as i16);
+ println!("{:?}", 1i8 as i32);
+ println!("{:?}", 1i8 as i64);
+ println!("{:?}", 1i8 as u8);
+ println!("{:?}", 1i8 as u16);
+ println!("{:?}", 1i8 as u32);
+ println!("{:?}", 1i8 as u64);
+ println!("{:?}", 1i8 as f32);
+ println!("{:?}", 1i8 as f64);
+
+ println!("{:?}", 1u8 as isize);
+ println!("{:?}", 1u8 as usize);
+ println!("{:?}", 1u8 as *const String);
+ println!("{:?}", 1u8 as i8);
+ println!("{:?}", 1u8 as i16);
+ println!("{:?}", 1u8 as i32);
+ println!("{:?}", 1u8 as i64);
+ println!("{:?}", 1u8 as u8);
+ println!("{:?}", 1u8 as u16);
+ println!("{:?}", 1u8 as u32);
+ println!("{:?}", 1u8 as u64);
+ println!("{:?}", 1u8 as f32);
+ println!("{:?}", 1u8 as f64);
+
+ println!("{:?}", 1i16 as isize);
+ println!("{:?}", 1i16 as usize);
+ println!("{:?}", 1i16 as *const String);
+ println!("{:?}", 1i16 as i8);
+ println!("{:?}", 1i16 as i16);
+ println!("{:?}", 1i16 as i32);
+ println!("{:?}", 1i16 as i64);
+ println!("{:?}", 1i16 as u8);
+ println!("{:?}", 1i16 as u16);
+ println!("{:?}", 1i16 as u32);
+ println!("{:?}", 1i16 as u64);
+ println!("{:?}", 1i16 as f32);
+ println!("{:?}", 1i16 as f64);
+
+ println!("{:?}", 1u16 as isize);
+ println!("{:?}", 1u16 as usize);
+ println!("{:?}", 1u16 as *const String);
+ println!("{:?}", 1u16 as i8);
+ println!("{:?}", 1u16 as i16);
+ println!("{:?}", 1u16 as i32);
+ println!("{:?}", 1u16 as i64);
+ println!("{:?}", 1u16 as u8);
+ println!("{:?}", 1u16 as u16);
+ println!("{:?}", 1u16 as u32);
+ println!("{:?}", 1u16 as u64);
+ println!("{:?}", 1u16 as f32);
+ println!("{:?}", 1u16 as f64);
+
+ println!("{:?}", 1i32 as isize);
+ println!("{:?}", 1i32 as usize);
+ println!("{:?}", 1i32 as *const String);
+ println!("{:?}", 1i32 as i8);
+ println!("{:?}", 1i32 as i16);
+ println!("{:?}", 1i32 as i32);
+ println!("{:?}", 1i32 as i64);
+ println!("{:?}", 1i32 as u8);
+ println!("{:?}", 1i32 as u16);
+ println!("{:?}", 1i32 as u32);
+ println!("{:?}", 1i32 as u64);
+ println!("{:?}", 1i32 as f32);
+ println!("{:?}", 1i32 as f64);
+
+ println!("{:?}", 1u32 as isize);
+ println!("{:?}", 1u32 as usize);
+ println!("{:?}", 1u32 as *const String);
+ println!("{:?}", 1u32 as i8);
+ println!("{:?}", 1u32 as i16);
+ println!("{:?}", 1u32 as i32);
+ println!("{:?}", 1u32 as i64);
+ println!("{:?}", 1u32 as u8);
+ println!("{:?}", 1u32 as u16);
+ println!("{:?}", 1u32 as u32);
+ println!("{:?}", 1u32 as u64);
+ println!("{:?}", 1u32 as f32);
+ println!("{:?}", 1u32 as f64);
+
+ println!("{:?}", 1i64 as isize);
+ println!("{:?}", 1i64 as usize);
+ println!("{:?}", 1i64 as *const String);
+ println!("{:?}", 1i64 as i8);
+ println!("{:?}", 1i64 as i16);
+ println!("{:?}", 1i64 as i32);
+ println!("{:?}", 1i64 as i64);
+ println!("{:?}", 1i64 as u8);
+ println!("{:?}", 1i64 as u16);
+ println!("{:?}", 1i64 as u32);
+ println!("{:?}", 1i64 as u64);
+ println!("{:?}", 1i64 as f32);
+ println!("{:?}", 1i64 as f64);
+
+ println!("{:?}", 1u64 as isize);
+ println!("{:?}", 1u64 as usize);
+ println!("{:?}", 1u64 as *const String);
+ println!("{:?}", 1u64 as i8);
+ println!("{:?}", 1u64 as i16);
+ println!("{:?}", 1u64 as i32);
+ println!("{:?}", 1u64 as i64);
+ println!("{:?}", 1u64 as u8);
+ println!("{:?}", 1u64 as u16);
+ println!("{:?}", 1u64 as u32);
+ println!("{:?}", 1u64 as u64);
+ println!("{:?}", 1u64 as f32);
+ println!("{:?}", 1u64 as f64);
+
+ println!("{:?}", 1u64 as isize);
+ println!("{:?}", 1u64 as usize);
+ println!("{:?}", 1u64 as *const String);
+ println!("{:?}", 1u64 as i8);
+ println!("{:?}", 1u64 as i16);
+ println!("{:?}", 1u64 as i32);
+ println!("{:?}", 1u64 as i64);
+ println!("{:?}", 1u64 as u8);
+ println!("{:?}", 1u64 as u16);
+ println!("{:?}", 1u64 as u32);
+ println!("{:?}", 1u64 as u64);
+ println!("{:?}", 1u64 as f32);
+ println!("{:?}", 1u64 as f64);
+
+ println!("{:?}", true as isize);
+ println!("{:?}", true as usize);
+ println!("{:?}", true as i8);
+ println!("{:?}", true as i16);
+ println!("{:?}", true as i32);
+ println!("{:?}", true as i64);
+ println!("{:?}", true as u8);
+ println!("{:?}", true as u16);
+ println!("{:?}", true as u32);
+ println!("{:?}", true as u64);
+
+ println!("{:?}", 1f32 as isize);
+ println!("{:?}", 1f32 as usize);
+ println!("{:?}", 1f32 as i8);
+ println!("{:?}", 1f32 as i16);
+ println!("{:?}", 1f32 as i32);
+ println!("{:?}", 1f32 as i64);
+ println!("{:?}", 1f32 as u8);
+ println!("{:?}", 1f32 as u16);
+ println!("{:?}", 1f32 as u32);
+ println!("{:?}", 1f32 as u64);
+ println!("{:?}", 1f32 as f32);
+ println!("{:?}", 1f32 as f64);
+
+ println!("{:?}", 1f64 as isize);
+ println!("{:?}", 1f64 as usize);
+ println!("{:?}", 1f64 as i8);
+ println!("{:?}", 1f64 as i16);
+ println!("{:?}", 1f64 as i32);
+ println!("{:?}", 1f64 as i64);
+ println!("{:?}", 1f64 as u8);
+ println!("{:?}", 1f64 as u16);
+ println!("{:?}", 1f64 as u32);
+ println!("{:?}", 1f64 as u64);
+ println!("{:?}", 1f64 as f32);
+ println!("{:?}", 1f64 as f64);
+}
diff --git a/tests/ui/cast/unsupported-cast.rs b/tests/ui/cast/unsupported-cast.rs
new file mode 100644
index 000000000..1384ecc6e
--- /dev/null
+++ b/tests/ui/cast/unsupported-cast.rs
@@ -0,0 +1,5 @@
+struct A;
+
+fn main() {
+ println!("{:?}", 1.0 as *const A); //~ERROR casting `f64` as `*const A` is invalid
+}
diff --git a/tests/ui/cast/unsupported-cast.stderr b/tests/ui/cast/unsupported-cast.stderr
new file mode 100644
index 000000000..56a375a1d
--- /dev/null
+++ b/tests/ui/cast/unsupported-cast.stderr
@@ -0,0 +1,9 @@
+error[E0606]: casting `f64` as `*const A` is invalid
+ --> $DIR/unsupported-cast.rs:4:20
+ |
+LL | println!("{:?}", 1.0 as *const A);
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0606`.