From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- src/test/ui/cast/cast-as-bool.rs | 9 + src/test/ui/cast/cast-as-bool.stderr | 22 +++ src/test/ui/cast/cast-char.rs | 10 + src/test/ui/cast/cast-char.stderr | 20 ++ src/test/ui/cast/cast-does-fallback.rs | 12 ++ src/test/ui/cast/cast-errors-issue-43825.rs | 7 + src/test/ui/cast/cast-errors-issue-43825.stderr | 9 + src/test/ui/cast/cast-from-nil.rs | 2 + src/test/ui/cast/cast-from-nil.stderr | 9 + src/test/ui/cast/cast-int-to-char.rs | 9 + src/test/ui/cast/cast-int-to-char.stderr | 89 +++++++++ src/test/ui/cast/cast-macro-lhs.rs | 12 ++ src/test/ui/cast/cast-macro-lhs.stderr | 11 ++ src/test/ui/cast/cast-region-to-uint.rs | 6 + src/test/ui/cast/cast-rfc0401-2.rs | 8 + src/test/ui/cast/cast-rfc0401-2.stderr | 9 + src/test/ui/cast/cast-rfc0401-vtable-kinds.rs | 62 +++++++ src/test/ui/cast/cast-rfc0401.rs | 173 +++++++++++++++++ src/test/ui/cast/cast-to-bare-fn.rs | 10 + src/test/ui/cast/cast-to-bare-fn.stderr | 15 ++ src/test/ui/cast/cast-to-infer-ty.rs | 8 + src/test/ui/cast/cast-to-nil.rs | 2 + src/test/ui/cast/cast-to-nil.stderr | 9 + .../cast-to-unsized-trait-object-suggestion.rs | 4 + .../cast-to-unsized-trait-object-suggestion.stderr | 19 ++ src/test/ui/cast/cast.rs | 21 +++ src/test/ui/cast/casts-differing-anon.rs | 22 +++ src/test/ui/cast/casts-differing-anon.stderr | 11 ++ src/test/ui/cast/casts-issue-46365.rs | 8 + src/test/ui/cast/casts-issue-46365.stderr | 9 + src/test/ui/cast/codegen-object-shim.rs | 6 + src/test/ui/cast/fat-ptr-cast-rpass.rs | 34 ++++ src/test/ui/cast/fat-ptr-cast.rs | 33 ++++ src/test/ui/cast/fat-ptr-cast.stderr | 88 +++++++++ src/test/ui/cast/issue-10991.rs | 4 + src/test/ui/cast/issue-10991.stderr | 9 + src/test/ui/cast/issue-17444.rs | 8 + src/test/ui/cast/issue-17444.stderr | 9 + src/test/ui/cast/issue-84213.fixed | 16 ++ src/test/ui/cast/issue-84213.rs | 16 ++ src/test/ui/cast/issue-84213.stderr | 25 +++ src/test/ui/cast/issue-85586.rs | 10 + src/test/ui/cast/issue-85586.stderr | 9 + src/test/ui/cast/issue-88621.rs | 13 ++ src/test/ui/cast/issue-88621.stderr | 9 + src/test/ui/cast/issue-89497.fixed | 10 + src/test/ui/cast/issue-89497.rs | 10 + src/test/ui/cast/issue-89497.stderr | 15 ++ src/test/ui/cast/supported-cast.rs | 206 +++++++++++++++++++++ src/test/ui/cast/unsupported-cast.rs | 5 + src/test/ui/cast/unsupported-cast.stderr | 9 + 51 files changed, 1161 insertions(+) create mode 100644 src/test/ui/cast/cast-as-bool.rs create mode 100644 src/test/ui/cast/cast-as-bool.stderr create mode 100644 src/test/ui/cast/cast-char.rs create mode 100644 src/test/ui/cast/cast-char.stderr create mode 100644 src/test/ui/cast/cast-does-fallback.rs create mode 100644 src/test/ui/cast/cast-errors-issue-43825.rs create mode 100644 src/test/ui/cast/cast-errors-issue-43825.stderr create mode 100644 src/test/ui/cast/cast-from-nil.rs create mode 100644 src/test/ui/cast/cast-from-nil.stderr create mode 100644 src/test/ui/cast/cast-int-to-char.rs create mode 100644 src/test/ui/cast/cast-int-to-char.stderr create mode 100644 src/test/ui/cast/cast-macro-lhs.rs create mode 100644 src/test/ui/cast/cast-macro-lhs.stderr create mode 100644 src/test/ui/cast/cast-region-to-uint.rs create mode 100644 src/test/ui/cast/cast-rfc0401-2.rs create mode 100644 src/test/ui/cast/cast-rfc0401-2.stderr create mode 100644 src/test/ui/cast/cast-rfc0401-vtable-kinds.rs create mode 100644 src/test/ui/cast/cast-rfc0401.rs create mode 100644 src/test/ui/cast/cast-to-bare-fn.rs create mode 100644 src/test/ui/cast/cast-to-bare-fn.stderr create mode 100644 src/test/ui/cast/cast-to-infer-ty.rs create mode 100644 src/test/ui/cast/cast-to-nil.rs create mode 100644 src/test/ui/cast/cast-to-nil.stderr create mode 100644 src/test/ui/cast/cast-to-unsized-trait-object-suggestion.rs create mode 100644 src/test/ui/cast/cast-to-unsized-trait-object-suggestion.stderr create mode 100644 src/test/ui/cast/cast.rs create mode 100644 src/test/ui/cast/casts-differing-anon.rs create mode 100644 src/test/ui/cast/casts-differing-anon.stderr create mode 100644 src/test/ui/cast/casts-issue-46365.rs create mode 100644 src/test/ui/cast/casts-issue-46365.stderr create mode 100644 src/test/ui/cast/codegen-object-shim.rs create mode 100644 src/test/ui/cast/fat-ptr-cast-rpass.rs create mode 100644 src/test/ui/cast/fat-ptr-cast.rs create mode 100644 src/test/ui/cast/fat-ptr-cast.stderr create mode 100644 src/test/ui/cast/issue-10991.rs create mode 100644 src/test/ui/cast/issue-10991.stderr create mode 100644 src/test/ui/cast/issue-17444.rs create mode 100644 src/test/ui/cast/issue-17444.stderr create mode 100644 src/test/ui/cast/issue-84213.fixed create mode 100644 src/test/ui/cast/issue-84213.rs create mode 100644 src/test/ui/cast/issue-84213.stderr create mode 100644 src/test/ui/cast/issue-85586.rs create mode 100644 src/test/ui/cast/issue-85586.stderr create mode 100644 src/test/ui/cast/issue-88621.rs create mode 100644 src/test/ui/cast/issue-88621.stderr create mode 100644 src/test/ui/cast/issue-89497.fixed create mode 100644 src/test/ui/cast/issue-89497.rs create mode 100644 src/test/ui/cast/issue-89497.stderr create mode 100644 src/test/ui/cast/supported-cast.rs create mode 100644 src/test/ui/cast/unsupported-cast.rs create mode 100644 src/test/ui/cast/unsupported-cast.stderr (limited to 'src/test/ui/cast') diff --git a/src/test/ui/cast/cast-as-bool.rs b/src/test/ui/cast/cast-as-bool.rs new file mode 100644 index 000000000..1aed218ae --- /dev/null +++ b/src/test/ui/cast/cast-as-bool.rs @@ -0,0 +1,9 @@ +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 +} diff --git a/src/test/ui/cast/cast-as-bool.stderr b/src/test/ui/cast/cast-as-bool.stderr new file mode 100644 index 000000000..15d94ab69 --- /dev/null +++ b/src/test/ui/cast/cast-as-bool.stderr @@ -0,0 +1,22 @@ +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:5: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:8:13 + | +LL | let v = "hello" as bool; + | ^^^^^^^^^^^^^^^ + +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/src/test/ui/cast/cast-char.rs b/src/test/ui/cast/cast-char.rs new file mode 100644 index 000000000..9634ed56f --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-char.stderr b/src/test/ui/cast/cast-char.stderr new file mode 100644 index 000000000..211937c9d --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-does-fallback.rs b/src/test/ui/cast/cast-does-fallback.rs new file mode 100644 index 000000000..770f7a31c --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-errors-issue-43825.rs b/src/test/ui/cast/cast-errors-issue-43825.rs new file mode 100644 index 000000000..00e0da44b --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-errors-issue-43825.stderr b/src/test/ui/cast/cast-errors-issue-43825.stderr new file mode 100644 index 000000000..1e77f5dbd --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-from-nil.rs b/src/test/ui/cast/cast-from-nil.rs new file mode 100644 index 000000000..b5ceef76a --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-from-nil.stderr b/src/test/ui/cast/cast-from-nil.stderr new file mode 100644 index 000000000..dab133cfb --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-int-to-char.rs b/src/test/ui/cast/cast-int-to-char.rs new file mode 100644 index 000000000..379956968 --- /dev/null +++ b/src/test/ui/cast/cast-int-to-char.rs @@ -0,0 +1,9 @@ +fn foo(_t: T) {} + +fn main() { + foo::('0'); //~ ERROR + foo::('0'); //~ ERROR + foo::('0'); //~ ERROR + foo::('0'); //~ ERROR + foo::(0u32); //~ ERROR +} diff --git a/src/test/ui/cast/cast-int-to-char.stderr b/src/test/ui/cast/cast-int-to-char.stderr new file mode 100644 index 000000000..ef606b6ae --- /dev/null +++ b/src/test/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::('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) {} + | ^^^ ----- +help: you can cast a `char` to a `u32`, since a `char` always occupies 4 bytes + | +LL | foo::('0' as u32); + | ++++++ + +error[E0308]: mismatched types + --> $DIR/cast-int-to-char.rs:5:16 + | +LL | foo::('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) {} + | ^^^ ----- +help: you can cast a `char` to an `i32`, since a `char` always occupies 4 bytes + | +LL | foo::('0' as i32); + | ++++++ + +error[E0308]: mismatched types + --> $DIR/cast-int-to-char.rs:6:16 + | +LL | foo::('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) {} + | ^^^ ----- +help: you can cast a `char` to a `u64`, since a `char` always occupies 4 bytes + | +LL | foo::('0' as u64); + | ++++++ + +error[E0308]: mismatched types + --> $DIR/cast-int-to-char.rs:7:16 + | +LL | foo::('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) {} + | ^^^ ----- +help: you can cast a `char` to an `i64`, since a `char` always occupies 4 bytes + | +LL | foo::('0' as i64); + | ++++++ + +error[E0308]: mismatched types + --> $DIR/cast-int-to-char.rs:8:17 + | +LL | foo::(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) {} + | ^^^ ----- + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/cast/cast-macro-lhs.rs b/src/test/ui/cast/cast-macro-lhs.rs new file mode 100644 index 000000000..b509b3239 --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-macro-lhs.stderr b/src/test/ui/cast/cast-macro-lhs.stderr new file mode 100644 index 000000000..db7ce57e1 --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-region-to-uint.rs b/src/test/ui/cast/cast-region-to-uint.rs new file mode 100644 index 000000000..33ec2d276 --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-rfc0401-2.rs b/src/test/ui/cast/cast-rfc0401-2.rs new file mode 100644 index 000000000..7709aa341 --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-rfc0401-2.stderr b/src/test/ui/cast/cast-rfc0401-2.stderr new file mode 100644 index 000000000..52f6af78a --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-rfc0401-vtable-kinds.rs b/src/test/ui/cast/cast-rfc0401-vtable-kinds.rs new file mode 100644 index 000000000..249481467 --- /dev/null +++ b/src/test/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 { + fn foo(&self, _: T) -> u32 { 42 } +} + +trait Bar { + fn bar(&self) { println!("Bar!"); } +} + +impl Foo for () {} +impl Foo for u32 { fn foo(&self, _: u32) -> u32 { self+43 } } +impl Bar for () {} + +unsafe fn round_trip_and_call<'a>(t: *const (dyn Foo+'a)) -> u32 { + let foo_e : *const dyn Foo = t as *const _; + let r_1 = foo_e as *mut dyn Foo; + + (&*r_1).foo(0) +} + +#[repr(C)] +struct FooS(T); +#[repr(C)] +struct BarS(T); + +fn foo_to_bar(u: *const FooS) -> *const BarS { + u as *const BarS +} + +fn tuple_i32_to_u32(u: *const (i32, T)) -> *const (u32, T) { + u as *const (u32, T) +} + + +fn main() { + let x = 4u32; + let y : &dyn Foo = &x; + let fl = unsafe { round_trip_and_call(y as *const dyn Foo) }; + 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/src/test/ui/cast/cast-rfc0401.rs b/src/test/ui/cast/cast-rfc0401.rs new file mode 100644 index 000000000..996fa013f --- /dev/null +++ b/src/test/ui/cast/cast-rfc0401.rs @@ -0,0 +1,173 @@ +// 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 = &mut it; + assert_eq!((itr as &mut dyn Iterator).next(), Some(137)); + assert_eq!((itr as &mut dyn Iterator).next(), None); + + assert_eq!(Some(4u32) as Option, 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 + // Disabling the lint to ensure that the assertion can still be run + #[allow(const_err)] + { + 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/src/test/ui/cast/cast-to-bare-fn.rs b/src/test/ui/cast/cast-to-bare-fn.rs new file mode 100644 index 000000000..1992f2637 --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-to-bare-fn.stderr b/src/test/ui/cast/cast-to-bare-fn.stderr new file mode 100644 index 000000000..d97b0c5f8 --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-to-infer-ty.rs b/src/test/ui/cast/cast-to-infer-ty.rs new file mode 100644 index 000000000..053ebb621 --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-to-nil.rs b/src/test/ui/cast/cast-to-nil.rs new file mode 100644 index 000000000..085bb09e6 --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-to-nil.stderr b/src/test/ui/cast/cast-to-nil.stderr new file mode 100644 index 000000000..29a9baffd --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-to-unsized-trait-object-suggestion.rs b/src/test/ui/cast/cast-to-unsized-trait-object-suggestion.rs new file mode 100644 index 000000000..5342b595c --- /dev/null +++ b/src/test/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/src/test/ui/cast/cast-to-unsized-trait-object-suggestion.stderr b/src/test/ui/cast/cast-to-unsized-trait-object-suggestion.stderr new file mode 100644 index 000000000..3b5b8ea69 --- /dev/null +++ b/src/test/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` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0620`. diff --git a/src/test/ui/cast/cast.rs b/src/test/ui/cast/cast.rs new file mode 100644 index 000000000..218275c4d --- /dev/null +++ b/src/test/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/src/test/ui/cast/casts-differing-anon.rs b/src/test/ui/cast/casts-differing-anon.rs new file mode 100644 index 000000000..d4a0f9613 --- /dev/null +++ b/src/test/ui/cast/casts-differing-anon.rs @@ -0,0 +1,22 @@ +use std::fmt; + +fn foo() -> Box { + let x : Box<[u8]> = Box::new([0]); + x +} +fn bar() -> Box { + let y: Box = 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/src/test/ui/cast/casts-differing-anon.stderr b/src/test/ui/cast/casts-differing-anon.stderr new file mode 100644 index 000000000..f9abfb522 --- /dev/null +++ b/src/test/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/src/test/ui/cast/casts-issue-46365.rs b/src/test/ui/cast/casts-issue-46365.rs new file mode 100644 index 000000000..50aa1a856 --- /dev/null +++ b/src/test/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/src/test/ui/cast/casts-issue-46365.stderr b/src/test/ui/cast/casts-issue-46365.stderr new file mode 100644 index 000000000..841754736 --- /dev/null +++ b/src/test/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/src/test/ui/cast/codegen-object-shim.rs b/src/test/ui/cast/codegen-object-shim.rs new file mode 100644 index 000000000..9a85a50eb --- /dev/null +++ b/src/test/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/src/test/ui/cast/fat-ptr-cast-rpass.rs b/src/test/ui/cast/fat-ptr-cast-rpass.rs new file mode 100644 index 000000000..f5747eb8b --- /dev/null +++ b/src/test/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/src/test/ui/cast/fat-ptr-cast.rs b/src/test/ui/cast/fat-ptr-cast.rs new file mode 100644 index 000000000..b5276dc61 --- /dev/null +++ b/src/test/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() { + let s = 0 as *const T; + //~^ ERROR cannot cast `usize` to a pointer that may be wide +} diff --git a/src/test/ui/cast/fat-ptr-cast.stderr b/src/test/ui/cast/fat-ptr-cast.stderr new file mode 100644 index 000000000..18e7b68ff --- /dev/null +++ b/src/test/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/src/test/ui/cast/issue-10991.rs b/src/test/ui/cast/issue-10991.rs new file mode 100644 index 000000000..c36829fdf --- /dev/null +++ b/src/test/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/src/test/ui/cast/issue-10991.stderr b/src/test/ui/cast/issue-10991.stderr new file mode 100644 index 000000000..5b8a18233 --- /dev/null +++ b/src/test/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/src/test/ui/cast/issue-17444.rs b/src/test/ui/cast/issue-17444.rs new file mode 100644 index 000000000..906b443c9 --- /dev/null +++ b/src/test/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/src/test/ui/cast/issue-17444.stderr b/src/test/ui/cast/issue-17444.stderr new file mode 100644 index 000000000..1097079df --- /dev/null +++ b/src/test/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/src/test/ui/cast/issue-84213.fixed b/src/test/ui/cast/issue-84213.fixed new file mode 100644 index 000000000..b5c4a7752 --- /dev/null +++ b/src/test/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/src/test/ui/cast/issue-84213.rs b/src/test/ui/cast/issue-84213.rs new file mode 100644 index 000000000..6eb81291a --- /dev/null +++ b/src/test/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/src/test/ui/cast/issue-84213.stderr b/src/test/ui/cast/issue-84213.stderr new file mode 100644 index 000000000..025970e54 --- /dev/null +++ b/src/test/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/src/test/ui/cast/issue-85586.rs b/src/test/ui/cast/issue-85586.rs new file mode 100644 index 000000000..78816582b --- /dev/null +++ b/src/test/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/src/test/ui/cast/issue-85586.stderr b/src/test/ui/cast/issue-85586.stderr new file mode 100644 index 000000000..ed8a6fc62 --- /dev/null +++ b/src/test/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/src/test/ui/cast/issue-88621.rs b/src/test/ui/cast/issue-88621.rs new file mode 100644 index 000000000..9242b80e2 --- /dev/null +++ b/src/test/ui/cast/issue-88621.rs @@ -0,0 +1,13 @@ +#![feature(arbitrary_enum_discriminant)] + +#[repr(u8)] +enum Kind2 { + Foo() = 1, + Bar{} = 2, + Baz = 3, +} + +fn main() { + let _ = Kind2::Foo() as u8; + //~^ ERROR non-primitive cast +} diff --git a/src/test/ui/cast/issue-88621.stderr b/src/test/ui/cast/issue-88621.stderr new file mode 100644 index 000000000..e96d86651 --- /dev/null +++ b/src/test/ui/cast/issue-88621.stderr @@ -0,0 +1,9 @@ +error[E0605]: non-primitive cast: `Kind2` as `u8` + --> $DIR/issue-88621.rs:11: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/src/test/ui/cast/issue-89497.fixed b/src/test/ui/cast/issue-89497.fixed new file mode 100644 index 000000000..04c10a5f7 --- /dev/null +++ b/src/test/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/src/test/ui/cast/issue-89497.rs b/src/test/ui/cast/issue-89497.rs new file mode 100644 index 000000000..76301b704 --- /dev/null +++ b/src/test/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/src/test/ui/cast/issue-89497.stderr b/src/test/ui/cast/issue-89497.stderr new file mode 100644 index 000000000..bf3c3537f --- /dev/null +++ b/src/test/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/src/test/ui/cast/supported-cast.rs b/src/test/ui/cast/supported-cast.rs new file mode 100644 index 000000000..ff41ce6c7 --- /dev/null +++ b/src/test/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/src/test/ui/cast/unsupported-cast.rs b/src/test/ui/cast/unsupported-cast.rs new file mode 100644 index 000000000..1384ecc6e --- /dev/null +++ b/src/test/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/src/test/ui/cast/unsupported-cast.stderr b/src/test/ui/cast/unsupported-cast.stderr new file mode 100644 index 000000000..56a375a1d --- /dev/null +++ b/src/test/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`. -- cgit v1.2.3