|
1 | 1 | //! Tests for the array channel flavor.
|
2 | 2 |
|
3 | 3 | use std::any::Any;
|
| 4 | +use std::cell::Cell; |
4 | 5 | use std::sync::atomic::AtomicUsize;
|
5 | 6 | use std::sync::atomic::Ordering;
|
6 | 7 | use std::thread;
|
@@ -692,53 +693,95 @@ fn channel_through_channel() {
|
692 | 693 |
|
693 | 694 | #[test]
|
694 | 695 | fn panic_on_drop() {
|
695 |
| - struct Msg1<'a>(&'a mut bool); |
| 696 | + struct Msg1<'a>(&'a Cell<bool>); |
696 | 697 | impl Drop for Msg1<'_> {
|
697 | 698 | fn drop(&mut self) {
|
698 |
| - if *self.0 && !std::thread::panicking() { |
| 699 | + if self.0.get() && !std::thread::panicking() { |
699 | 700 | panic!("double drop");
|
700 | 701 | } else {
|
701 |
| - *self.0 = true; |
| 702 | + self.0.set(true); |
702 | 703 | }
|
703 | 704 | }
|
704 | 705 | }
|
705 | 706 |
|
706 |
| - struct Msg2<'a>(&'a mut bool); |
| 707 | + struct Msg2<'a>(&'a Cell<bool>); |
707 | 708 | impl Drop for Msg2<'_> {
|
708 | 709 | fn drop(&mut self) {
|
709 |
| - if *self.0 { |
| 710 | + if self.0.get() { |
710 | 711 | panic!("double drop");
|
711 | 712 | } else {
|
712 |
| - *self.0 = true; |
| 713 | + self.0.set(true); |
713 | 714 | panic!("first drop");
|
714 | 715 | }
|
715 | 716 | }
|
716 | 717 | }
|
717 | 718 |
|
718 |
| - // normal |
| 719 | + // normal (sender first) |
719 | 720 | let (s, r) = bounded(2);
|
720 |
| - let (mut a, mut b) = (false, false); |
721 |
| - s.send(Msg1(&mut a)).unwrap(); |
722 |
| - s.send(Msg1(&mut b)).unwrap(); |
| 721 | + let (a, b) = (Cell::new(false), Cell::new(false)); |
| 722 | + s.send(Msg1(&a)).unwrap(); |
| 723 | + s.send(Msg1(&b)).unwrap(); |
723 | 724 | drop(s);
|
| 725 | + assert!(!a.get()); |
| 726 | + assert!(!b.get()); |
724 | 727 | drop(r);
|
725 |
| - assert!(a); |
726 |
| - assert!(b); |
| 728 | + assert!(a.get()); |
| 729 | + assert!(b.get()); |
727 | 730 |
|
728 |
| - // panic on drop |
| 731 | + // normal (receiver first) |
729 | 732 | let (s, r) = bounded(2);
|
730 |
| - let (mut a, mut b) = (false, false); |
731 |
| - s.send(Msg2(&mut a)).unwrap(); |
732 |
| - s.send(Msg2(&mut b)).unwrap(); |
| 733 | + let (a, b) = (Cell::new(false), Cell::new(false)); |
| 734 | + s.send(Msg1(&a)).unwrap(); |
| 735 | + s.send(Msg1(&b)).unwrap(); |
| 736 | + drop(r); |
| 737 | + // TODO: should be dropped eagerly: https://github.com/rust-lang/rust/issues/107466 |
| 738 | + assert!(!a.get()); |
| 739 | + assert!(!b.get()); |
733 | 740 | drop(s);
|
| 741 | + assert!(a.get()); |
| 742 | + assert!(b.get()); |
| 743 | + |
| 744 | + // panic on drop (sender first) |
| 745 | + let (s, r) = bounded(2); |
| 746 | + let (a, b) = (Cell::new(false), Cell::new(false)); |
| 747 | + s.send(Msg2(&a)).unwrap(); |
| 748 | + s.send(Msg2(&b)).unwrap(); |
| 749 | + drop(s); |
| 750 | + assert!(!a.get()); |
| 751 | + assert!(!b.get()); |
734 | 752 | let res = std::panic::catch_unwind(move || {
|
735 | 753 | drop(r);
|
736 | 754 | });
|
737 | 755 | assert_eq!(
|
738 | 756 | *res.unwrap_err().downcast_ref::<&str>().unwrap(),
|
739 | 757 | "first drop"
|
740 | 758 | );
|
741 |
| - assert!(a); |
| 759 | + assert!(a.get()); |
| 760 | + // Elements after the panicked element will leak. |
| 761 | + assert!(!b.get()); |
| 762 | + |
| 763 | + // panic on drop (receiver first) |
| 764 | + let (s, r) = bounded(2); |
| 765 | + let (a, b) = (Cell::new(false), Cell::new(false)); |
| 766 | + s.send(Msg2(&a)).unwrap(); |
| 767 | + s.send(Msg2(&b)).unwrap(); |
| 768 | + let res = std::panic::catch_unwind(move || { |
| 769 | + drop(r); |
| 770 | + }); |
| 771 | + // This currently doesn't panic, but it should panic when a fix for |
| 772 | + // https://github.com/rust-lang/rust/issues/107466 is implemented. |
| 773 | + assert!(res.is_ok()); |
| 774 | + // TODO: `a` should be dropped eagerly: https://github.com/rust-lang/rust/issues/107466 |
| 775 | + assert!(!a.get()); |
| 776 | + assert!(!b.get()); |
| 777 | + let res = std::panic::catch_unwind(move || { |
| 778 | + drop(s); |
| 779 | + }); |
| 780 | + assert_eq!( |
| 781 | + *res.unwrap_err().downcast_ref::<&str>().unwrap(), |
| 782 | + "first drop" |
| 783 | + ); |
| 784 | + assert!(a.get()); |
742 | 785 | // Elements after the panicked element will leak.
|
743 |
| - assert!(!b); |
| 786 | + assert!(!b.get()); |
744 | 787 | }
|
0 commit comments