1717#![ deny( clippy:: undocumented_unsafe_blocks) ]
1818
1919extern crate alloc;
20- use alloc:: {
21- vec,
22- vec:: { IntoIter , Vec } ,
23- } ;
20+ use alloc:: { vec, vec:: Vec } ;
2421
2522mod block;
2623mod range;
@@ -30,8 +27,8 @@ extern crate serde;
3027#[ cfg( feature = "serde" ) ]
3128mod serde_impl;
3229
30+ use core:: fmt:: Write ;
3331use core:: fmt:: { Binary , Display , Error , Formatter } ;
34- use core:: { fmt:: Write , mem:: ManuallyDrop } ;
3532
3633use core:: cmp:: { Ord , Ordering } ;
3734use core:: iter:: { Chain , FusedIterator } ;
@@ -545,33 +542,24 @@ impl FixedBitSet {
545542 /// Iterator element is the index of the `1` bit, type `usize`.
546543 /// Unlike `ones`, this function consumes the `FixedBitset`.
547544 pub fn into_ones ( self ) -> IntoOnes {
548- // SAFETY: This is using the exact same allocation pattern, size, and capacity
549- // making this reconstruction of the Vec safe.
550- let mut data = unsafe {
551- let mut data = ManuallyDrop :: new ( self . data ) ;
552- let ptr = data. as_mut_ptr ( ) . cast ( ) ;
553- let len = data. len ( ) * SimdBlock :: USIZE_COUNT ;
554- let capacity = data. capacity ( ) * SimdBlock :: USIZE_COUNT ;
555- Vec :: from_raw_parts ( ptr, len, capacity)
556- } ;
557- if data. is_empty ( ) {
558- IntoOnes {
559- bitset_front : 0 ,
560- bitset_back : 0 ,
561- block_idx_front : 0 ,
562- block_idx_back : 0 ,
563- remaining_blocks : data. into_iter ( ) ,
564- }
565- } else {
566- let first_block = data. remove ( 0 ) ;
567- let last_block = data. pop ( ) . unwrap_or ( 0 ) ;
568- IntoOnes {
569- bitset_front : first_block,
570- bitset_back : last_block,
571- block_idx_front : 0 ,
572- block_idx_back : ( 1 + data. len ( ) ) * BITS ,
573- remaining_blocks : data. into_iter ( ) ,
574- }
545+ let ptr = self . data . as_ptr ( ) . cast ( ) ;
546+ let len = self . data . len ( ) * SimdBlock :: USIZE_COUNT ;
547+ // SAFETY:
548+ // - ptr comes from self.data, so it is valid;
549+ // - self.data is valid for self.data.len() SimdBlocks,
550+ // which is exactly self.data.len() * SimdBlock::USIZE_COUNT usizes;
551+ // - we will keep this slice around only as long as self.data is,
552+ // so it won't become dangling.
553+ let slice = unsafe { core:: slice:: from_raw_parts ( ptr, len) } ;
554+ let mut iter = slice. iter ( ) . copied ( ) ;
555+
556+ IntoOnes {
557+ bitset_front : iter. next ( ) . unwrap_or ( 0 ) ,
558+ bitset_back : iter. next_back ( ) . unwrap_or ( 0 ) ,
559+ block_idx_front : 0 ,
560+ block_idx_back : len. saturating_sub ( 1 ) * BITS ,
561+ remaining_blocks : iter,
562+ _buf : self . data ,
575563 }
576564 }
577565
@@ -1151,7 +1139,9 @@ pub struct IntoOnes {
11511139 bitset_back : Block ,
11521140 block_idx_front : usize ,
11531141 block_idx_back : usize ,
1154- remaining_blocks : IntoIter < usize > ,
1142+ remaining_blocks : core:: iter:: Copied < core:: slice:: Iter < ' static , usize > > ,
1143+ // Keep buf along so that `remaining_blocks` remains valid.
1144+ _buf : Vec < SimdBlock > ,
11551145}
11561146
11571147impl IntoOnes {
@@ -1605,7 +1595,8 @@ mod tests {
16051595
16061596 #[ test]
16071597 fn size_hint ( ) {
1608- for s in 0 ..1000 {
1598+ let iters = if cfg ! ( miri) { 250 } else { 1000 } ;
1599+ for s in 0 ..iters {
16091600 let mut bitset = FixedBitSet :: with_capacity ( s) ;
16101601 bitset. insert_range ( ..) ;
16111602 let mut t = s;
@@ -1627,7 +1618,8 @@ mod tests {
16271618
16281619 #[ test]
16291620 fn size_hint_alternate ( ) {
1630- for s in 0 ..1000 {
1621+ let iters = if cfg ! ( miri) { 250 } else { 1000 } ;
1622+ for s in 0 ..iters {
16311623 let mut bitset = FixedBitSet :: with_capacity ( s) ;
16321624 bitset. insert_range ( ..) ;
16331625 let mut t = s;
@@ -1688,7 +1680,8 @@ mod tests {
16881680
16891681 #[ test]
16901682 fn count_ones_panic ( ) {
1691- for i in 1 ..128 {
1683+ let iters = if cfg ! ( miri) { 48 } else { 128 } ;
1684+ for i in 1 ..iters {
16921685 let fb = FixedBitSet :: with_capacity ( i) ;
16931686 for j in 0 ..fb. len ( ) + 1 {
16941687 for k in j..fb. len ( ) + 1 {
0 commit comments