@@ -69,6 +69,16 @@ fn unlikely(b: bool) -> bool {
6969 b
7070}
7171
72+ // Use strict provenance functions if available.
73+ #[ cfg( feature = "nightly" ) ]
74+ use core:: ptr:: invalid_mut;
75+ // Implement it with a cast otherwise.
76+ #[ cfg( not( feature = "nightly" ) ) ]
77+ #[ inline( always) ]
78+ fn invalid_mut < T > ( addr : usize ) -> * mut T {
79+ addr as * mut T
80+ }
81+
7282#[ inline]
7383unsafe fn offset_from < T > ( to : * const T , from : * const T ) -> usize {
7484 to. offset_from ( from) as usize
@@ -371,7 +381,7 @@ impl<T> Bucket<T> {
371381 // won't overflow because index must be less than length (bucket_mask)
372382 // and bucket_mask is guaranteed to be less than `isize::MAX`
373383 // (see TableLayout::calculate_layout_for method)
374- ( index + 1 ) as * mut T
384+ invalid_mut ( index + 1 )
375385 } else {
376386 base. as_ptr ( ) . sub ( index)
377387 } ;
@@ -507,7 +517,8 @@ impl<T> Bucket<T> {
507517 pub fn as_ptr ( & self ) -> * mut T {
508518 if Self :: IS_ZERO_SIZED_TYPE {
509519 // Just return an arbitrary ZST pointer which is properly aligned
510- mem:: align_of :: < T > ( ) as * mut T
520+ // invalid pointer is good enough for ZST
521+ invalid_mut ( mem:: align_of :: < T > ( ) )
511522 } else {
512523 unsafe { self . ptr . as_ptr ( ) . sub ( 1 ) }
513524 }
@@ -553,7 +564,8 @@ impl<T> Bucket<T> {
553564 #[ inline]
554565 unsafe fn next_n ( & self , offset : usize ) -> Self {
555566 let ptr = if Self :: IS_ZERO_SIZED_TYPE {
556- ( self . ptr . as_ptr ( ) as usize + offset) as * mut T
567+ // invalid pointer is good enough for ZST
568+ invalid_mut ( self . ptr . as_ptr ( ) as usize + offset)
557569 } else {
558570 self . ptr . as_ptr ( ) . sub ( offset)
559571 } ;
0 commit comments