// run-pass // // Test that we can handle unsized types with an extern type tail part. // Regression test for issue #91827. #![feature(extern_types)] use std::ptr::addr_of; extern "C" { type Opaque; } unsafe impl Sync for Opaque {} #[repr(C)] pub struct List { len: usize, data: [T; 0], tail: Opaque, } #[repr(C)] pub struct ListImpl { len: usize, data: [T; N], } impl List { const fn as_slice(&self) -> &[T] { unsafe { std::slice::from_raw_parts(self.data.as_ptr(), self.len) } } } impl ListImpl { const fn as_list(&self) -> &List { unsafe { std::mem::transmute(self) } } } pub static A: ListImpl = ListImpl { len: 3, data: [5, 6, 7], }; pub static A_REF: &'static List = A.as_list(); pub static A_TAIL_OFFSET: isize = tail_offset(A.as_list()); const fn tail_offset(list: &List) -> isize { unsafe { (addr_of!(list.tail) as *const u8).offset_from(list as *const List as *const u8) } } fn main() { assert_eq!(A_REF.as_slice(), &[5, 6, 7]); // Check that interpreter and code generation agree about the position of the tail field. assert_eq!(A_TAIL_OFFSET, tail_offset(A_REF)); }