@@ -45,7 +45,7 @@ use option::Option;
45
45
use option:: Option :: { None , Some } ;
46
46
use result:: Result ;
47
47
use result:: Result :: { Ok , Err } ;
48
- use ptr;
48
+ use ptr:: { self , NonNull } ;
49
49
use mem;
50
50
use marker:: { Copy , Send , Sync , Sized , self } ;
51
51
use iter_private:: TrustedRandomAccess ;
@@ -80,7 +80,7 @@ macro_rules! slice_offset {
80
80
( $ptr: expr, $by: expr) => { {
81
81
let ptr = $ptr;
82
82
if size_from_ptr( ptr) == 0 {
83
- ( ptr as * mut i8 ) . wrapping_offset( $by) as _
83
+ ( ptr as * mut i8 ) . wrapping_offset( $by. wrapping_mul ( align_from_ptr ( ptr ) as isize ) ) as _
84
84
} else {
85
85
ptr. offset( $by)
86
86
}
@@ -93,7 +93,7 @@ macro_rules! make_ref {
93
93
let ptr = $ptr;
94
94
if size_from_ptr( ptr) == 0 {
95
95
// Use a non-null pointer value
96
- & * ( 1 as * mut _)
96
+ & * ( NonNull :: dangling ( ) . as_ptr ( ) as * const _)
97
97
} else {
98
98
& * ptr
99
99
}
@@ -106,13 +106,39 @@ macro_rules! make_ref_mut {
106
106
let ptr = $ptr;
107
107
if size_from_ptr( ptr) == 0 {
108
108
// Use a non-null pointer value
109
- & mut * ( 1 as * mut _ )
109
+ & mut * ( NonNull :: dangling ( ) . as_ptr ( ) )
110
110
} else {
111
111
& mut * ptr
112
112
}
113
113
} } ;
114
114
}
115
115
116
+ macro_rules! make_slice {
117
+ ( $start: expr, $end: expr) => { {
118
+ let start = $start;
119
+ let len = unsafe { ptrdistance( $start, $end) } ;
120
+ if size_from_ptr( start) == 0 {
121
+ // use a non-null pointer value
122
+ unsafe { from_raw_parts( NonNull :: dangling( ) . as_ptr( ) as * const _, len) }
123
+ } else {
124
+ unsafe { from_raw_parts( start, len) }
125
+ }
126
+ } }
127
+ }
128
+
129
+ macro_rules! make_mut_slice {
130
+ ( $start: expr, $end: expr) => { {
131
+ let start = $start;
132
+ let len = unsafe { ptrdistance( $start, $end) } ;
133
+ if size_from_ptr( start) == 0 {
134
+ // use a non-null pointer value
135
+ unsafe { from_raw_parts_mut( NonNull :: dangling( ) . as_ptr( ) , len) }
136
+ } else {
137
+ unsafe { from_raw_parts_mut( start, len) }
138
+ }
139
+ } }
140
+ }
141
+
116
142
#[ lang = "slice" ]
117
143
#[ cfg( not( test) ) ]
118
144
impl < T > [ T ] {
@@ -581,7 +607,7 @@ impl<T> [T] {
581
607
pub fn iter ( & self ) -> Iter < T > {
582
608
unsafe {
583
609
let p = if mem:: size_of :: < T > ( ) == 0 {
584
- 1 as * const _
610
+ NonNull :: dangling ( ) . as_ptr ( ) as * const _
585
611
} else {
586
612
let p = self . as_ptr ( ) ;
587
613
assume ( !p. is_null ( ) ) ;
@@ -612,7 +638,7 @@ impl<T> [T] {
612
638
pub fn iter_mut ( & mut self ) -> IterMut < T > {
613
639
unsafe {
614
640
let p = if mem:: size_of :: < T > ( ) == 0 {
615
- 1 as * mut _
641
+ NonNull :: dangling ( ) . as_ptr ( )
616
642
} else {
617
643
let p = self . as_mut_ptr ( ) ;
618
644
assume ( !p. is_null ( ) ) ;
@@ -2369,6 +2395,11 @@ fn size_from_ptr<T>(_: *const T) -> usize {
2369
2395
mem:: size_of :: < T > ( )
2370
2396
}
2371
2397
2398
+ #[ inline]
2399
+ fn align_from_ptr < T > ( _: * const T ) -> usize {
2400
+ mem:: align_of :: < T > ( )
2401
+ }
2402
+
2372
2403
// The shared definition of the `Iter` and `IterMut` iterators
2373
2404
macro_rules! iterator {
2374
2405
( struct $name: ident -> $ptr: ty, $elem: ty, $mkref: ident) => {
@@ -2547,34 +2578,6 @@ macro_rules! iterator {
2547
2578
}
2548
2579
}
2549
2580
2550
- macro_rules! make_slice {
2551
- ( $start: expr, $end: expr) => { {
2552
- let start = $start;
2553
- let diff = ( $end as usize ) . wrapping_sub( start as usize ) ;
2554
- if size_from_ptr( start) == 0 {
2555
- // use a non-null pointer value
2556
- unsafe { from_raw_parts( 1 as * const _, diff) }
2557
- } else {
2558
- let len = diff / size_from_ptr( start) ;
2559
- unsafe { from_raw_parts( start, len) }
2560
- }
2561
- } }
2562
- }
2563
-
2564
- macro_rules! make_mut_slice {
2565
- ( $start: expr, $end: expr) => { {
2566
- let start = $start;
2567
- let diff = ( $end as usize ) . wrapping_sub( start as usize ) ;
2568
- if size_from_ptr( start) == 0 {
2569
- // use a non-null pointer value
2570
- unsafe { from_raw_parts_mut( 1 as * mut _, diff) }
2571
- } else {
2572
- let len = diff / size_from_ptr( start) ;
2573
- unsafe { from_raw_parts_mut( start, len) }
2574
- }
2575
- } }
2576
- }
2577
-
2578
2581
/// Immutable slice iterator
2579
2582
///
2580
2583
/// This struct is created by the [`iter`] method on [slices].
@@ -2791,11 +2794,10 @@ impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
2791
2794
}
2792
2795
2793
2796
// Return the number of elements of `T` from `start` to `end`.
2794
- // Return the arithmetic difference if `T` is zero size.
2795
2797
#[ inline( always) ]
2796
2798
unsafe fn ptrdistance < T > ( start : * const T , end : * const T ) -> usize {
2797
2799
if mem:: size_of :: < T > ( ) == 0 {
2798
- ( end as usize ) . wrapping_sub ( start as usize )
2800
+ ( end as usize ) . wrapping_sub ( start as usize ) / mem :: align_of :: < T > ( )
2799
2801
} else {
2800
2802
end. offset_from ( start) as usize
2801
2803
}
0 commit comments