]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_codegen_cranelift/example/issue-91827-extern-types.rs
Merge commit '7f27e2e74ef957baa382dc05cf08df6368165c74' into clippyup
[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(extern_types)]
9
10 use std::ptr::addr_of;
11
12 extern "C" {
13     type Opaque;
14 }
15
16 unsafe impl Sync for Opaque {}
17
18 #[repr(C)]
19 pub struct List<T> {
20     len: usize,
21     data: [T; 0],
22     tail: Opaque,
23 }
24
25 #[repr(C)]
26 pub struct ListImpl<T, const N: usize> {
27     len: usize,
28     data: [T; N],
29 }
30
31 impl<T> List<T> {
32     const fn as_slice(&self) -> &[T] {
33         unsafe { std::slice::from_raw_parts(self.data.as_ptr(), self.len) }
34     }
35 }
36
37 impl<T, const N: usize> ListImpl<T, N> {
38     const fn as_list(&self) -> &List<T> {
39         unsafe { std::mem::transmute(self) }
40     }
41 }
42
43 pub static A: ListImpl<u128, 3> = ListImpl {
44     len: 3,
45     data: [5, 6, 7],
46 };
47 pub static A_REF: &'static List<u128> = A.as_list();
48 pub static A_TAIL_OFFSET: isize = tail_offset(A.as_list());
49
50 const fn tail_offset<T>(list: &List<T>) -> isize {
51     unsafe { (addr_of!(list.tail) as *const u8).offset_from(list as *const List<T> as *const u8) }
52 }
53
54 fn main() {
55     assert_eq!(A_REF.as_slice(), &[5, 6, 7]);
56     // Check that interpreter and code generation agree about the position of the tail field.
57     assert_eq!(A_TAIL_OFFSET, tail_offset(A_REF));
58 }