@@ -288,75 +288,64 @@ fn test_retain() {
288
288
}
289
289
290
290
#[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
+ }
303
306
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,
316
314
_ => panic!(),
317
315
});
318
- });
319
- assert!(ret.is_err() );
316
+ }))
317
+ .unwrap_err( );
320
318
// 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) );
322
320
}
323
321
324
322
#[test]
325
323
fn test_retain_drop_panic() {
326
- use std::sync::atomic::{AtomicU64, Ordering};
327
-
328
- struct Wrap<'a>(&'a AtomicU64, u64);
324
+ struct Wrap(Rc<i32>);
329
325
330
- impl Drop for Wrap<'_> {
326
+ impl Drop for Wrap {
331
327
fn drop(&mut self) {
332
- if self.1 == 8 {
328
+ if * self.0 == 3 {
333
329
panic!();
334
330
}
335
- self.0.fetch_or(self.1, Ordering::SeqCst);
336
331
}
337
332
}
338
333
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.
354
342
_ => true,
355
343
});
356
- });
357
- assert!(ret.is_err() );
344
+ }))
345
+ .unwrap_err( );
358
346
// 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));
360
349
}
361
350
362
351
#[test]
0 commit comments