]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_codegen_cranelift/example/issue-91827-extern-types.rs
Auto merge of #99101 - RalfJung:interpret-projections, r=oli-obk
[rust.git] / compiler / rustc_codegen_cranelift / example / issue-91827-extern-types.rs
1 // Copied from rustc ui test suite
2
3 // run-pass
4 //
5 // Test that we can handle unsized types with an extern type tail part.
6 // Regression test for issue #91827.
7
8 #![feature(const_ptr_offset_from)]
9 #![feature(extern_types)]
10
11 use std::ptr::addr_of;
12
13 extern "C" {
14     type Opaque;
15 }
16
17 unsafe impl Sync for Opaque {}
18
19 #[repr(C)]
20 pub struct List<T> {
21     len: usize,
22     data: [T; 0],
23     tail: Opaque,
24 }
25
26 #[repr(C)]
27 pub struct ListImpl<T, const N: usize> {
28     len: usize,
29     data: [T; N],
30 }
31
32 impl<T> List<T> {
33     const fn as_slice(&self) -> &[T] {
34         unsafe { std::slice::from_raw_parts(self.data.as_ptr(), self.len) }
35     }
36 }
37
38 impl<T, const N: usize> ListImpl<T, N> {
39     const fn as_list(&self) -> &List<T> {
40         unsafe { std::mem::transmute(self) }
41     }
42 }
43
44 pub static A: ListImpl<u128, 3> = ListImpl {
45     len: 3,
46     data: [5, 6, 7],
47 };
48 pub static A_REF: &'static List<u128> = A.as_list();
49 pub static A_TAIL_OFFSET: isize = tail_offset(A.as_list());
50
51 const fn tail_offset<T>(list: &List<T>) -> isize {
52     unsafe { (addr_of!(list.tail) as *const u8).offset_from(list as *const List<T> as *const u8) }
53 }
54
55 fn main() {
56     assert_eq!(A_REF.as_slice(), &[5, 6, 7]);
57     // Check that interpreter and code generation agree about the position of the tail field.
58     assert_eq!(A_TAIL_OFFSET, tail_offset(A_REF));
59 }