Skip to content

Commit 570b165

Browse files
author
Lukas Markeffsky
committed
consolidate and improve fat pointer cast tests
1 parent 25f8d01 commit 570b165

File tree

5 files changed

+378
-347
lines changed

5 files changed

+378
-347
lines changed

tests/ui/cast/fat-ptr-cast-rpass.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,28 @@ fn main() {
2323
let b: *const [i32] = a;
2424
assert_eq!(a as usize, b as *const () as usize);
2525

26+
// Casting to a different type keeps the metadata.
27+
let c = b as *const [u8];
28+
unsafe {
29+
assert_eq!((*a).len(), (*c).len());
30+
}
31+
32+
// `str` <-> `[T]` conversions are allowed.
33+
let a: *const [u32] = &[1953723730, 544434464, 2053205345, 560426601];
34+
let b = a as *const str;
35+
unsafe {
36+
if cfg!(target_endian = "little") {
37+
assert_eq!((*b), *"Rust");
38+
} else if cfg!(target_endian = "big") {
39+
assert_eq!((*b), *"tsuR");
40+
}
41+
}
42+
let a: *const str = "hello";
43+
let b = a as *const [u8];
44+
unsafe {
45+
assert_eq!((*b), [104, 101, 108, 108, 111]);
46+
}
47+
2648
// And conversion to a void pointer/address for trait objects too.
2749
let a: *mut dyn Foo = &mut Bar;
2850
let b = a as *mut () as usize;
@@ -31,4 +53,11 @@ fn main() {
3153

3254
assert_eq!(b, d);
3355
assert_eq!(c, d);
56+
57+
// Adding auto traits is OK.
58+
let _ = a as *mut (dyn Foo + Send);
59+
60+
// Casting between auto-trait-only trait objects is OK.
61+
let unprincipled: *mut dyn Send = &mut Bar;
62+
let _ = unprincipled as *mut dyn Sync;
3463
}

tests/ui/cast/fat-ptr-cast.rs

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
trait Trait {}
1+
trait Foo { fn foo(&self) {} }
2+
impl<T> Foo for T {}
3+
4+
trait Bar { fn foo(&self) {} }
5+
impl<T> Bar for T {}
6+
7+
enum E {
8+
A, B
9+
}
210

311
// Make sure casts between thin-pointer <-> fat pointer obey RFC401
412
fn main() {
@@ -12,22 +20,84 @@ fn main() {
1220
a as i16; //~ ERROR casting `&[i32]` as `i16` is invalid
1321
a as u32; //~ ERROR casting `&[i32]` as `u32` is invalid
1422
b as usize; //~ ERROR non-primitive cast
15-
p as usize;
16-
//~^ ERROR casting
23+
p as usize; //~ ERROR casting
1724

1825
// #22955
1926
q as *const [i32]; //~ ERROR cannot cast
2027

2128
// #21397
22-
let t: *mut (dyn Trait + 'static) = 0 as *mut _;
29+
let t: *mut (dyn Foo + 'static) = 0 as *mut _;
2330
//~^ ERROR cannot cast `usize` to a pointer that is wide
2431
let mut fail: *const str = 0 as *const str;
2532
//~^ ERROR cannot cast `usize` to a pointer that is wide
2633
let mut fail2: *const str = 0isize as *const str;
2734
//~^ ERROR cannot cast `isize` to a pointer that is wide
35+
36+
let f: f32 = 1.2;
37+
let v = core::ptr::null::<u8>();
38+
let fat_v : *const [u8] = &[];
39+
let fat_sv : *const [i8] = &[];
40+
let foo: &dyn Foo = &f;
41+
42+
let _ = v as &u8; //~ ERROR non-primitive cast
43+
let _ = v as E; //~ ERROR non-primitive cast
44+
let _ = v as fn(); //~ ERROR non-primitive cast
45+
let _ = v as (u32,); //~ ERROR non-primitive cast
46+
let _ = Some(&v) as *const u8; //~ ERROR non-primitive cast
47+
48+
let _ = v as f32; //~ ERROR is invalid
49+
let _ = main as f64; //~ ERROR is invalid
50+
let _ = &v as usize; //~ ERROR is invalid
51+
let _ = f as *const u8; //~ ERROR is invalid
52+
let _ = 3_i32 as bool; //~ ERROR cannot cast
53+
let _ = E::A as bool; //~ ERROR cannot cast
54+
let _ = 0x61u32 as char; //~ ERROR can be cast as
55+
56+
let _ = false as f32; //~ ERROR is invalid
57+
let _ = E::A as f32; //~ ERROR is invalid
58+
let _ = 'a' as f32; //~ ERROR is invalid
59+
60+
let _ = false as *const u8; //~ ERROR is invalid
61+
let _ = E::A as *const u8; //~ ERROR is invalid
62+
let _ = 'a' as *const u8; //~ ERROR is invalid
63+
64+
let _ = 42usize as *const [u8]; //~ ERROR cannot cast `usize` to a pointer that is wide
65+
let _ = v as *const [u8]; //~ ERROR cannot cast
66+
let _ = fat_v as *const dyn Foo; //~ ERROR the size for values of type
67+
let _ = foo as *const str; //~ ERROR is invalid
68+
let _ = foo as *mut str; //~ ERROR is invalid
69+
let _ = main as *mut str; //~ ERROR is invalid
70+
let _ = &f as *mut f32; //~ ERROR is invalid
71+
let _ = &f as *const f64; //~ ERROR is invalid
72+
let _ = fat_sv as usize; //~ ERROR is invalid
73+
74+
let a : *const str = "hello";
75+
let _ = a as *const dyn Foo; //~ ERROR the size for values of type
76+
77+
// check no error cascade
78+
let _ = main.f as *const u32; //~ ERROR no field
79+
80+
let cf: *const dyn Foo = &0;
81+
let _ = cf as *const [u16]; //~ ERROR is invalid
82+
let _ = cf as *const dyn Bar; //~ ERROR is invalid
83+
84+
// casting principal away is not allowed for now
85+
let _ = cf as *const dyn Send; //~ ERROR is invalid
86+
87+
vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>(); //~ ERROR is invalid
2888
}
2989

3090
fn foo<T: ?Sized>() {
3191
let s = 0 as *const T;
3292
//~^ ERROR cannot cast `usize` to a pointer that may be wide
3393
}
94+
95+
fn illegal_cast<U:?Sized,V:?Sized>(u: *const U) -> *const V
96+
{
97+
u as *const V //~ ERROR is invalid
98+
}
99+
100+
fn illegal_cast_2<U:?Sized>(u: *const U) -> *const str
101+
{
102+
u as *const str //~ ERROR is invalid
103+
}

0 commit comments

Comments
 (0)