#![feature(static_align)] #![deny(non_upper_case_globals)] use std::cell::Cell; // When a static uses `align(N)`, its address should be a multiple of `N`. #[rustc_align_static(256)] static FOO: u64 = 0; #[rustc_align_static(512)] static BAR: u64 = 0; struct HasDrop(*const HasDrop); impl Drop for HasDrop { fn drop(&mut self) { assert_eq!(core::ptr::from_mut(self).cast_const(), self.0); } } thread_local! { #[rustc_align_static(4096)] static LOCAL: u64 = 0; #[allow(unused_mut, reason = "test attribute handling")] #[cfg_attr(true, rustc_align_static(4096))] static CONST_LOCAL: u64 = const { 0 }; #[cfg_attr(any(true), cfg_attr(true, rustc_align_static(4096)))] #[allow(unused_mut, reason = "test attribute handling")] static HASDROP_LOCAL: Cell = Cell::new(HasDrop(core::ptr::null())); /// I love doc comments. #[allow(unused_mut, reason = "test attribute handling")] #[cfg_attr(all(), cfg_attr(any(true), cfg_attr(true, rustc_align_static(4096))))] #[allow(unused_mut, reason = "test attribute handling")] /// I love doc comments. static HASDROP_CONST_LOCAL: Cell = const { Cell::new(HasDrop(core::ptr::null())) }; #[cfg_attr(true,)] #[cfg_attr(false,)] #[cfg_attr( true, rustc_align_static(32), cfg_attr(true, allow(non_upper_case_globals, reason = "test attribute handling")), cfg_attr(false,) )] #[cfg_attr(false, rustc_align_static(0))] static more_attr_testing: u64 = 0; } fn thread_local_ptr(key: &'static std::thread::LocalKey) -> *const T { key.with(|local| core::ptr::from_ref::(local)) } fn main() { assert!(core::ptr::from_ref(&FOO).addr().is_multiple_of(256)); assert!(core::ptr::from_ref(&BAR).addr().is_multiple_of(512)); assert!(thread_local_ptr(&LOCAL).addr().is_multiple_of(4096)); assert!(thread_local_ptr(&CONST_LOCAL).addr().is_multiple_of(4096)); assert!(thread_local_ptr(&HASDROP_LOCAL).addr().is_multiple_of(4096)); assert!(thread_local_ptr(&HASDROP_CONST_LOCAL).addr().is_multiple_of(4096)); assert!(thread_local_ptr(&more_attr_testing).addr().is_multiple_of(32)); // Test that address (and therefore alignment) is maintained during drop let hasdrop_ptr = thread_local_ptr(&HASDROP_LOCAL); core::mem::forget(HASDROP_LOCAL.replace(HasDrop(hasdrop_ptr.cast()))); let hasdrop_const_ptr = thread_local_ptr(&HASDROP_CONST_LOCAL); core::mem::forget(HASDROP_CONST_LOCAL.replace(HasDrop(hasdrop_const_ptr.cast()))); }