@@ -9,30 +9,20 @@ macro_rules! is_empty {
99 } ;
1010}
1111
12- // To get rid of some bounds checks (see `position`), we compute the length in a somewhat
13- // unexpected way. (Tested by `codegen/slice-position-bounds-check`.)
1412macro_rules! len {
1513 ( $self: ident) => { {
1614 #![ allow( unused_unsafe) ] // we're sometimes used within an unsafe block
1715
1816 let start = $self. ptr;
19- let size = size_from_ptr( start. as_ptr( ) ) ;
20- if size == 0 {
21- // This _cannot_ use `unchecked_sub` because we depend on wrapping
17+ if T :: IS_ZST {
18+ // This _cannot_ use `ptr_sub` because we depend on wrapping
2219 // to represent the length of long ZST slice iterators.
2320 $self. end. addr( ) . wrapping_sub( start. as_ptr( ) . addr( ) )
2421 } else {
25- // We know that `start <= end`, so can do better than `offset_from`,
26- // which needs to deal in signed. By setting appropriate flags here
27- // we can tell LLVM this, which helps it remove bounds checks.
28- // SAFETY: By the type invariant, `start <= end`
29- let diff = unsafe { unchecked_sub( $self. end. addr( ) , start. as_ptr( ) . addr( ) ) } ;
30- // By also telling LLVM that the pointers are apart by an exact
31- // multiple of the type size, it can optimize `len() == 0` down to
32- // `start == end` instead of `(end - start) < size`.
33- // SAFETY: By the type invariant, the pointers are aligned so the
34- // distance between them must be a multiple of pointee size
35- unsafe { exact_div( diff, size) }
22+ // To get rid of some bounds checks (see `position`), we use ptr_sub instead of
23+ // offset_from (Tested by `codegen/slice-position-bounds-check`.)
24+ // SAFETY: by the type invariant pointers are aligned and `start <= end`
25+ unsafe { $self. end. sub_ptr( start. as_ptr( ) ) }
3626 }
3727 } } ;
3828}
0 commit comments