@@ -1343,4 +1343,81 @@ extern "rust-intrinsic" {
13431343 /// on MSVC it's `*mut [usize; 2]`. For more information see the compiler's
13441344 /// source as well as std's catch implementation.
13451345 pub fn try ( f : fn ( * mut u8 ) , data : * mut u8 , local_ptr : * mut u8 ) -> i32 ;
1346+
1347+ /// Computes the byte offset that needs to be applied to `ptr` in order to
1348+ /// make it aligned to `align`.
1349+ /// If it is not possible to align `ptr`, the implementation returns
1350+ /// `usize::max_value()`.
1351+ ///
1352+ /// There are no guarantees whatsover that offsetting the pointer will not
1353+ /// overflow or go beyond the allocation that `ptr` points into.
1354+ /// It is up to the caller to ensure that the returned offset is correct
1355+ /// in all terms other than alignment.
1356+ ///
1357+ /// # Examples
1358+ ///
1359+ /// Accessing adjacent `u8` as `u16`
1360+ ///
1361+ /// ```
1362+ /// # #![feature(core_intrinsics)]
1363+ /// # fn foo(n: usize) {
1364+ /// # use std::intrinsics::align_offset;
1365+ /// # use std::mem::align_of;
1366+ /// # unsafe {
1367+ /// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
1368+ /// let ptr = &x[n] as *const u8;
1369+ /// let offset = align_offset(ptr as *const (), align_of::<u16>());
1370+ /// if offset < x.len() - n - 1 {
1371+ /// let u16_ptr = ptr.offset(offset as isize) as *const u16;
1372+ /// assert_ne!(*u16_ptr, 500);
1373+ /// } else {
1374+ /// // while the pointer can be aligned via `offset`, it would point
1375+ /// // outside the allocation
1376+ /// }
1377+ /// # } }
1378+ /// ```
1379+ #[ cfg( not( stage0) ) ]
1380+ pub fn align_offset ( ptr : * const ( ) , align : usize ) -> usize ;
1381+ }
1382+
1383+ #[ cfg( stage0) ]
1384+ /// Computes the byte offset that needs to be applied to `ptr` in order to
1385+ /// make it aligned to `align`.
1386+ /// If it is not possible to align `ptr`, the implementation returns
1387+ /// `usize::max_value()`.
1388+ ///
1389+ /// There are no guarantees whatsover that offsetting the pointer will not
1390+ /// overflow or go beyond the allocation that `ptr` points into.
1391+ /// It is up to the caller to ensure that the returned offset is correct
1392+ /// in all terms other than alignment.
1393+ ///
1394+ /// # Examples
1395+ ///
1396+ /// Accessing adjacent `u8` as `u16`
1397+ ///
1398+ /// ```
1399+ /// # #![feature(core_intrinsics)]
1400+ /// # fn foo(n: usize) {
1401+ /// # use std::intrinsics::align_offset;
1402+ /// # use std::mem::align_of;
1403+ /// # unsafe {
1404+ /// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
1405+ /// let ptr = &x[n] as *const u8;
1406+ /// let offset = align_offset(ptr as *const (), align_of::<u16>());
1407+ /// if offset < x.len() - n - 1 {
1408+ /// let u16_ptr = ptr.offset(offset as isize) as *const u16;
1409+ /// assert_ne!(*u16_ptr, 500);
1410+ /// } else {
1411+ /// // while the pointer can be aligned via `offset`, it would point
1412+ /// // outside the allocation
1413+ /// }
1414+ /// # } }
1415+ /// ```
1416+ pub unsafe fn align_offset ( ptr : * const ( ) , align : usize ) -> usize {
1417+ let offset = ptr as usize % align;
1418+ if offset == 0 {
1419+ 0
1420+ } else {
1421+ align - offset
1422+ }
13461423}
0 commit comments