]> git.lizzy.rs Git - rust.git/blob - tests/ui/const-ptr/allowed_slices.rs
Rollup merge of #105172 - alexs-sh:issue-98861-fix-next, r=scottmcm
[rust.git] / tests / ui / const-ptr / allowed_slices.rs
1 // run-pass
2 #![feature(
3     slice_from_ptr_range,
4     const_slice_from_ptr_range,
5     pointer_byte_offsets,
6     const_pointer_byte_offsets
7 )]
8 use std::{
9     mem::MaybeUninit,
10     ptr,
11     slice::{from_ptr_range, from_raw_parts},
12 };
13
14 // Dangling is ok, as long as it's either for ZST reads or for no reads
15 pub static S0: &[u32] = unsafe { from_raw_parts(dangling(), 0) };
16 pub static S1: &[()] = unsafe { from_raw_parts(dangling(), 3) };
17
18 // References are always valid of reads of a single element (basically `slice::from_ref`)
19 pub static S2: &[u32] = unsafe { from_raw_parts(&D0, 1) };
20 pub static S3: &[MaybeUninit<&u32>] = unsafe { from_raw_parts(&D1, 1) };
21
22 // Reinterpreting data is fine, as long as layouts match
23 pub static S4: &[u8] = unsafe { from_raw_parts((&D0) as *const _ as _, 3) };
24 // This is only valid because D1 has uninitialized bytes, if it was an initialized pointer,
25 // that would reinterpret pointers as integers which is UB in CTFE.
26 pub static S5: &[MaybeUninit<u8>] = unsafe { from_raw_parts((&D1) as *const _ as _, 2) };
27 // Even though u32 and [bool; 4] have different layouts, D0 has a value that
28 // is valid as [bool; 4], so this is not UB (it's basically a transmute)
29 pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) };
30
31 // Structs are considered single allocated objects,
32 // as long as you don't reinterpret padding as initialized
33 // data everything is ok.
34 pub static S7: &[u16] = unsafe {
35     let ptr = (&D2 as *const Struct as *const u16).byte_add(4);
36
37     from_raw_parts(ptr, 3)
38 };
39 pub static S8: &[MaybeUninit<u16>] = unsafe {
40     let ptr = &D2 as *const Struct as *const MaybeUninit<u16>;
41
42     from_raw_parts(ptr, 6)
43 };
44
45 pub static R0: &[u32] = unsafe { from_ptr_range(dangling()..dangling()) };
46 // from_ptr_range panics on zst
47 //pub static R1: &[()] = unsafe { from_ptr_range(dangling(), dangling().byte_add(3)) };
48 pub static R2: &[u32] = unsafe {
49     let ptr = &D0 as *const u32;
50     from_ptr_range(ptr..ptr.add(1))
51 };
52 pub static R3: &[MaybeUninit<&u32>] = unsafe {
53     let ptr = &D1 as *const MaybeUninit<&u32>;
54     from_ptr_range(ptr..ptr.add(1))
55 };
56 pub static R4: &[u8] = unsafe {
57     let ptr = &D0 as *const u32 as *const u8;
58     from_ptr_range(ptr..ptr.add(3))
59 };
60 pub static R5: &[MaybeUninit<u8>] = unsafe {
61     let ptr = &D1 as *const MaybeUninit<&u32> as *const MaybeUninit<u8>;
62     from_ptr_range(ptr..ptr.add(2))
63 };
64 pub static R6: &[bool] = unsafe {
65     let ptr = &D0 as *const u32 as *const bool;
66     from_ptr_range(ptr..ptr.add(4))
67 };
68 pub static R7: &[u16] = unsafe {
69     let d2 = &D2;
70     let l = &d2.b as *const u32 as *const u16;
71     let r = &d2.d as *const u8 as *const u16;
72
73     from_ptr_range(l..r)
74 };
75 pub static R8: &[MaybeUninit<u16>] = unsafe {
76     let d2 = &D2;
77     let l = d2 as *const Struct as *const MaybeUninit<u16>;
78     let r = &d2.d as *const u8 as *const MaybeUninit<u16>;
79
80     from_ptr_range(l..r)
81 };
82
83 // Using valid slice is always valid
84 pub static R9: &[u32] = unsafe { from_ptr_range(R0.as_ptr_range()) };
85 pub static R10: &[u32] = unsafe { from_ptr_range(R2.as_ptr_range()) };
86
87 const D0: u32 = (1 << 16) | 1;
88 const D1: MaybeUninit<&u32> = MaybeUninit::uninit();
89 const D2: Struct = Struct { a: 1, b: 2, c: 3, d: 4 };
90
91 const fn dangling<T>() -> *const T {
92     ptr::NonNull::dangling().as_ptr() as _
93 }
94
95 #[repr(C)]
96 struct Struct {
97     a: u8,
98     // _pad: [MaybeUninit<u8>; 3]
99     b: u32,
100     c: u16,
101     d: u8,
102     // _pad: [MaybeUninit<u8>; 1]
103 }
104
105 fn main() {}