@@ -69,6 +69,16 @@ fn unlikely(b: bool) -> bool {
69
69
b
70
70
}
71
71
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
+
72
82
#[ inline]
73
83
unsafe fn offset_from < T > ( to : * const T , from : * const T ) -> usize {
74
84
to. offset_from ( from) as usize
@@ -371,7 +381,7 @@ impl<T> Bucket<T> {
371
381
// won't overflow because index must be less than length (bucket_mask)
372
382
// and bucket_mask is guaranteed to be less than `isize::MAX`
373
383
// (see TableLayout::calculate_layout_for method)
374
- ( index + 1 ) as * mut T
384
+ invalid_mut ( index + 1 )
375
385
} else {
376
386
base. as_ptr ( ) . sub ( index)
377
387
} ;
@@ -507,7 +517,8 @@ impl<T> Bucket<T> {
507
517
pub fn as_ptr ( & self ) -> * mut T {
508
518
if Self :: IS_ZERO_SIZED_TYPE {
509
519
// 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 > ( ) )
511
522
} else {
512
523
unsafe { self . ptr . as_ptr ( ) . sub ( 1 ) }
513
524
}
@@ -553,7 +564,8 @@ impl<T> Bucket<T> {
553
564
#[ inline]
554
565
unsafe fn next_n ( & self , offset : usize ) -> Self {
555
566
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)
557
569
} else {
558
570
self . ptr . as_ptr ( ) . sub ( offset)
559
571
} ;
0 commit comments