@@ -1478,7 +1478,7 @@ impl<T: ?Sized> *const T {
14781478 panic ! ( "align_offset: align is not a power-of-two" ) ;
14791479 }
14801480 unsafe {
1481- intrinsics :: align_offset ( self , align)
1481+ align_offset ( self , align)
14821482 }
14831483 }
14841484
@@ -2543,7 +2543,7 @@ impl<T: ?Sized> *mut T {
25432543 panic ! ( "align_offset: align is not a power-of-two" ) ;
25442544 }
25452545 unsafe {
2546- intrinsics :: align_offset ( self , align)
2546+ align_offset ( self , align)
25472547 }
25482548 }
25492549
@@ -2565,8 +2565,6 @@ impl<T: ?Sized> *mut T {
25652565/// Calculate offset (in terms of elements of `stride` stride) that has to be applied
25662566/// to pointer `p` so that pointer `p` would get aligned to `a`.
25672567///
2568- /// This is an implementation of the `align_offset` intrinsic for the case where `stride > 1`.
2569- ///
25702568/// Note: This implementation has been carefully tailored to not panic. It is UB for this to panic.
25712569/// The only real change that can be made here is change of `INV_TABLE_MOD_16` and associated
25722570/// constants.
@@ -2578,7 +2576,7 @@ impl<T: ?Sized> *mut T {
25782576/// Any questions go to @nagisa.
25792577#[ lang="align_offset" ]
25802578#[ cfg( not( stage0) ) ]
2581- unsafe fn align_offset ( p : * const ( ) , a : usize , stride : usize ) -> usize {
2579+ pub ( crate ) unsafe fn align_offset < T : Sized > ( p : * const T , a : usize ) -> usize {
25822580 /// Calculate multiplicative modular inverse of `x` modulo `m`.
25832581 ///
25842582 /// This implementation is tailored for align_offset and has following preconditions:
@@ -2587,12 +2585,13 @@ unsafe fn align_offset(p: *const (), a: usize, stride: usize) -> usize {
25872585 /// * `x < m`; (if `x ≥ m`, pass in `x % m` instead)
25882586 ///
25892587 /// Implementation of this function shall not panic. Ever.
2588+ #[ inline]
25902589 fn mod_inv ( x : usize , m : usize ) -> usize {
25912590 /// Multiplicative modular inverse table modulo 2⁴ = 16.
25922591 ///
25932592 /// Note, that this table does not contain values where inverse does not exist (i.e. for
25942593 /// `0⁻¹ mod 16`, `2⁻¹ mod 16`, etc.)
2595- static INV_TABLE_MOD_16 : [ usize ; 8 ] = [ 1 , 11 , 13 , 7 , 9 , 3 , 5 , 15 ] ;
2594+ const INV_TABLE_MOD_16 : [ usize ; 8 ] = [ 1 , 11 , 13 , 7 , 9 , 3 , 5 , 15 ] ;
25962595 /// Modulo for which the `INV_TABLE_MOD_16` is intended.
25972596 const INV_TABLE_MOD : usize = 16 ;
25982597 /// INV_TABLE_MOD²
@@ -2627,18 +2626,30 @@ unsafe fn align_offset(p: *const (), a: usize, stride: usize) -> usize {
26272626 }
26282627 }
26292628
2629+ let stride = :: mem:: size_of :: < T > ( ) ;
26302630 let a_minus_one = a. wrapping_sub ( 1 ) ;
26312631 let pmoda = p as usize & a_minus_one;
2632- let smoda = stride & a_minus_one;
2633- // a is power-of-two so cannot be 0. stride = 0 is handled by the intrinsic.
2634- let gcdpow = intrinsics:: cttz_nonzero ( stride) . min ( intrinsics:: cttz_nonzero ( a) ) ;
2635- let gcd = 1usize << gcdpow;
26362632
26372633 if pmoda == 0 {
26382634 // Already aligned. Yay!
26392635 return 0 ;
26402636 }
26412637
2638+ if stride <= 1 {
2639+ return if stride == 0 {
2640+ // If the pointer is not aligned, and the element is zero-sized, then no amount of
2641+ // elements will ever align the pointer.
2642+ !0
2643+ } else {
2644+ a. wrapping_sub ( pmoda)
2645+ } ;
2646+ }
2647+
2648+ let smoda = stride & a_minus_one;
2649+ // a is power-of-two so cannot be 0. stride = 0 is handled above.
2650+ let gcdpow = intrinsics:: cttz_nonzero ( stride) . min ( intrinsics:: cttz_nonzero ( a) ) ;
2651+ let gcd = 1usize << gcdpow;
2652+
26422653 if gcd == 1 {
26432654 // This branch solves for the variable $o$ in following linear congruence equation:
26442655 //
0 commit comments