mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-31 13:04:42 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			59 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			59 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| // Copied from rustc ui test suite
 | |
| 
 | |
| // 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<T> {
 | |
|     len: usize,
 | |
|     data: [T; 0],
 | |
|     tail: Opaque,
 | |
| }
 | |
| 
 | |
| #[repr(C)]
 | |
| pub struct ListImpl<T, const N: usize> {
 | |
|     len: usize,
 | |
|     data: [T; N],
 | |
| }
 | |
| 
 | |
| impl<T> List<T> {
 | |
|     const fn as_slice(&self) -> &[T] {
 | |
|         unsafe { std::slice::from_raw_parts(self.data.as_ptr(), self.len) }
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl<T, const N: usize> ListImpl<T, N> {
 | |
|     const fn as_list(&self) -> &List<T> {
 | |
|         unsafe { std::mem::transmute(self) }
 | |
|     }
 | |
| }
 | |
| 
 | |
| pub static A: ListImpl<u128, 3> = ListImpl {
 | |
|     len: 3,
 | |
|     data: [5, 6, 7],
 | |
| };
 | |
| pub static A_REF: &'static List<u128> = A.as_list();
 | |
| pub static A_TAIL_OFFSET: isize = tail_offset(A.as_list());
 | |
| 
 | |
| const fn tail_offset<T>(list: &List<T>) -> isize {
 | |
|     unsafe { (addr_of!(list.tail) as *const u8).offset_from(list as *const List<T> 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));
 | |
| }
 | 
