@@ -288,75 +288,64 @@ fn test_retain() {
288288}
289289
290290#[ test]
291- fn test_retain_pred_panic ( ) {
292- use std:: sync:: atomic:: { AtomicU64 , Ordering } ;
293-
294- struct Wrap < ' a > ( & ' a AtomicU64 , u64 , bool ) ;
295-
296- impl Drop for Wrap < ' _ > {
297- fn drop ( & mut self ) {
298- self . 0 . fetch_or ( self . 1 , Ordering :: SeqCst ) ;
299- }
300- }
301-
302- let dropped = AtomicU64 :: new ( 0 ) ;
291+ fn test_retain_pred_panic_with_hole ( ) {
292+ let v = ( 0 ..5 ) . map ( Rc :: new) . collect :: < Vec < _ > > ( ) ;
293+ catch_unwind ( AssertUnwindSafe ( || {
294+ let mut v = v. clone ( ) ;
295+ v. retain ( |r| match * * r {
296+ 0 => true ,
297+ 1 => false ,
298+ 2 => true ,
299+ _ => panic ! ( ) ,
300+ } ) ;
301+ } ) )
302+ . unwrap_err ( ) ;
303+ // Everything is dropped when predicate panicked.
304+ assert ! ( v. iter( ) . all( |r| Rc :: strong_count( r) == 1 ) ) ;
305+ }
303306
304- let ret = std:: panic:: catch_unwind ( || {
305- let mut v = vec ! [
306- Wrap ( & dropped, 1 , false ) ,
307- Wrap ( & dropped, 2 , false ) ,
308- Wrap ( & dropped, 4 , false ) ,
309- Wrap ( & dropped, 8 , false ) ,
310- Wrap ( & dropped, 16 , false ) ,
311- ] ;
312- v. retain ( |w| match w. 1 {
313- 1 => true ,
314- 2 => false ,
315- 4 => true ,
307+ #[ test]
308+ fn test_retain_pred_panic_no_hole ( ) {
309+ let v = ( 0 ..5 ) . map ( Rc :: new) . collect :: < Vec < _ > > ( ) ;
310+ catch_unwind ( AssertUnwindSafe ( || {
311+ let mut v = v. clone ( ) ;
312+ v. retain ( |r| match * * r {
313+ 0 | 1 | 2 => true ,
316314 _ => panic ! ( ) ,
317315 } ) ;
318- } ) ;
319- assert ! ( ret . is_err ( ) ) ;
316+ } ) )
317+ . unwrap_err ( ) ;
320318 // Everything is dropped when predicate panicked.
321- assert_eq ! ( dropped . load ( Ordering :: SeqCst ) , 1 | 2 | 4 | 8 | 16 ) ;
319+ assert ! ( v . iter ( ) . all ( |r| Rc :: strong_count ( r ) == 1 ) ) ;
322320}
323321
324322#[ test]
325323fn test_retain_drop_panic ( ) {
326- use std:: sync:: atomic:: { AtomicU64 , Ordering } ;
327-
328- struct Wrap < ' a > ( & ' a AtomicU64 , u64 ) ;
324+ struct Wrap ( Rc < i32 > ) ;
329325
330- impl Drop for Wrap < ' _ > {
326+ impl Drop for Wrap {
331327 fn drop ( & mut self ) {
332- if self . 1 == 8 {
328+ if * self . 0 == 3 {
333329 panic ! ( ) ;
334330 }
335- self . 0 . fetch_or ( self . 1 , Ordering :: SeqCst ) ;
336331 }
337332 }
338333
339- let dropped = AtomicU64 :: new ( 0 ) ;
340-
341- let ret = std:: panic:: catch_unwind ( || {
342- let mut v = vec ! [
343- Wrap ( & dropped, 1 ) ,
344- Wrap ( & dropped, 2 ) ,
345- Wrap ( & dropped, 4 ) ,
346- Wrap ( & dropped, 8 ) ,
347- Wrap ( & dropped, 16 ) ,
348- ] ;
349- v. retain ( |w| match w. 1 {
350- 1 => true ,
351- 2 => false ,
352- 4 => true ,
353- 8 => false ,
334+ let v = ( 0 ..5 ) . map ( |x| Rc :: new ( x) ) . collect :: < Vec < _ > > ( ) ;
335+ catch_unwind ( AssertUnwindSafe ( || {
336+ let mut v = v. iter ( ) . map ( |r| Wrap ( r. clone ( ) ) ) . collect :: < Vec < _ > > ( ) ;
337+ v. retain ( |w| match * w. 0 {
338+ 0 => true ,
339+ 1 => false ,
340+ 2 => true ,
341+ 3 => false , // Drop panic.
354342 _ => true ,
355343 } ) ;
356- } ) ;
357- assert ! ( ret . is_err ( ) ) ;
344+ } ) )
345+ . unwrap_err ( ) ;
358346 // Other elements are dropped when `drop` of one element panicked.
359- assert_eq ! ( dropped. load( Ordering :: SeqCst ) , 1 | 2 | 4 | 16 ) ;
347+ // The panicked wrapper also has its Rc dropped.
348+ assert ! ( v. iter( ) . all( |r| Rc :: strong_count( r) == 1 ) ) ;
360349}
361350
362351#[ test]
0 commit comments