Rollup merge of #142668 - hkBst:less-static-mut, r=tgross35
vec_deque/fmt/vec tests: remove static mut More rust-lang/rust#125035. r? ```@tgross35```
This commit is contained in:
commit
52758b7329
9 changed files with 138 additions and 270 deletions
|
|
@ -1,4 +1,3 @@
|
|||
use std::cell::Cell;
|
||||
use std::panic::{AssertUnwindSafe, catch_unwind};
|
||||
use std::thread;
|
||||
|
||||
|
|
@ -6,6 +5,7 @@ use rand::RngCore;
|
|||
|
||||
use super::*;
|
||||
use crate::testing::crash_test::{CrashTestDummy, Panic};
|
||||
use crate::testing::macros::struct_with_counted_drop;
|
||||
use crate::vec::Vec;
|
||||
|
||||
#[test]
|
||||
|
|
@ -1010,22 +1010,6 @@ fn extract_if_drop_panic_leak() {
|
|||
assert_eq!(d7.dropped(), 1);
|
||||
}
|
||||
|
||||
macro_rules! struct_with_counted_drop {
|
||||
($struct_name:ident$(($elt_ty:ty))?, $drop_counter:ident $(=> $drop_stmt:expr)?) => {
|
||||
thread_local! {static $drop_counter: Cell<u32> = Cell::new(0);}
|
||||
|
||||
struct $struct_name$(($elt_ty))?;
|
||||
|
||||
impl Drop for $struct_name {
|
||||
fn drop(&mut self) {
|
||||
$drop_counter.set($drop_counter.get() + 1);
|
||||
|
||||
$($drop_stmt(self))?
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
|
||||
fn extract_if_pred_panic_leak() {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
|
||||
#![allow(static_mut_refs)]
|
||||
|
||||
use core::iter::TrustedLen;
|
||||
|
||||
use super::*;
|
||||
use crate::testing::macros::struct_with_counted_drop;
|
||||
|
||||
#[bench]
|
||||
fn bench_push_back_100(b: &mut test::Bencher) {
|
||||
|
|
@ -1086,36 +1084,24 @@ fn test_clone_from() {
|
|||
|
||||
#[test]
|
||||
fn test_vec_deque_truncate_drop() {
|
||||
static mut DROPS: u32 = 0;
|
||||
#[derive(Clone)]
|
||||
struct Elem(#[allow(dead_code)] i32);
|
||||
impl Drop for Elem {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
struct_with_counted_drop!(Elem, DROPS);
|
||||
|
||||
let v = vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)];
|
||||
for push_front in 0..=v.len() {
|
||||
let v = v.clone();
|
||||
let mut tester = VecDeque::with_capacity(5);
|
||||
for (index, elem) in v.into_iter().enumerate() {
|
||||
const LEN: usize = 5;
|
||||
for push_front in 0..=LEN {
|
||||
let mut tester = VecDeque::with_capacity(LEN);
|
||||
for index in 0..LEN {
|
||||
if index < push_front {
|
||||
tester.push_front(elem);
|
||||
tester.push_front(Elem);
|
||||
} else {
|
||||
tester.push_back(elem);
|
||||
tester.push_back(Elem);
|
||||
}
|
||||
}
|
||||
assert_eq!(unsafe { DROPS }, 0);
|
||||
assert_eq!(DROPS.get(), 0);
|
||||
tester.truncate(3);
|
||||
assert_eq!(unsafe { DROPS }, 2);
|
||||
assert_eq!(DROPS.get(), 2);
|
||||
tester.truncate(0);
|
||||
assert_eq!(unsafe { DROPS }, 5);
|
||||
unsafe {
|
||||
DROPS = 0;
|
||||
}
|
||||
assert_eq!(DROPS.get(), 5);
|
||||
DROPS.set(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
37
library/alloctests/testing/macros.rs
Normal file
37
library/alloctests/testing/macros.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
macro_rules! struct_with_counted_drop {
|
||||
($struct_name:ident $(( $( $elt_ty:ty ),+ ))?, $drop_counter:ident $( => $drop_stmt:expr )? ) => {
|
||||
thread_local! {static $drop_counter: ::core::cell::Cell<u32> = ::core::cell::Cell::new(0);}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
struct $struct_name $(( $( $elt_ty ),+ ))?;
|
||||
|
||||
impl ::std::ops::Drop for $struct_name {
|
||||
fn drop(&mut self) {
|
||||
$drop_counter.set($drop_counter.get() + 1);
|
||||
|
||||
$($drop_stmt(self))?
|
||||
}
|
||||
}
|
||||
};
|
||||
($struct_name:ident $(( $( $elt_ty:ty ),+ ))?, $drop_counter:ident[ $drop_key:expr,$key_ty:ty ] $( => $drop_stmt:expr )? ) => {
|
||||
thread_local! {
|
||||
static $drop_counter: ::core::cell::RefCell<::std::collections::HashMap<$key_ty, u32>> =
|
||||
::core::cell::RefCell::new(::std::collections::HashMap::new());
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
struct $struct_name $(( $( $elt_ty ),+ ))?;
|
||||
|
||||
impl ::std::ops::Drop for $struct_name {
|
||||
fn drop(&mut self) {
|
||||
$drop_counter.with_borrow_mut(|counter| {
|
||||
*counter.entry($drop_key(self)).or_default() += 1;
|
||||
});
|
||||
|
||||
$($drop_stmt(self))?
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use struct_with_counted_drop;
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
pub(crate) mod crash_test;
|
||||
pub(crate) mod macros;
|
||||
pub(crate) mod ord_chaos;
|
||||
pub(crate) mod rng;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
#![deny(warnings)]
|
||||
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
|
||||
#![allow(static_mut_refs)]
|
||||
#![allow(unnecessary_transmutes)]
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
|
@ -285,19 +283,32 @@ fn test_format_args() {
|
|||
t!(s, "args were: hello world");
|
||||
}
|
||||
|
||||
macro_rules! counter_fn {
|
||||
($name:ident) => {
|
||||
fn $name() -> u32 {
|
||||
thread_local! {static COUNTER: ::core::cell::Cell<u32> = ::core::cell::Cell::new(0);}
|
||||
|
||||
COUNTER.set(COUNTER.get() + 1);
|
||||
COUNTER.get()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_order() {
|
||||
// Make sure format!() arguments are always evaluated in a left-to-right
|
||||
// ordering
|
||||
fn foo() -> isize {
|
||||
static mut FOO: isize = 0;
|
||||
unsafe {
|
||||
FOO += 1;
|
||||
FOO
|
||||
}
|
||||
}
|
||||
// Make sure format!() arguments are always evaluated in a left-to-right ordering
|
||||
counter_fn!(count);
|
||||
|
||||
assert_eq!(
|
||||
format!("{} {} {a} {b} {} {c}", foo(), foo(), foo(), a = foo(), b = foo(), c = foo()),
|
||||
format!(
|
||||
"{} {} {a} {b} {} {c}",
|
||||
count(),
|
||||
count(),
|
||||
count(),
|
||||
a = count(),
|
||||
b = count(),
|
||||
c = count()
|
||||
),
|
||||
"1 2 4 5 3 6".to_string()
|
||||
);
|
||||
}
|
||||
|
|
@ -306,14 +317,9 @@ fn test_order() {
|
|||
fn test_once() {
|
||||
// Make sure each argument are evaluated only once even though it may be
|
||||
// formatted multiple times
|
||||
fn foo() -> isize {
|
||||
static mut FOO: isize = 0;
|
||||
unsafe {
|
||||
FOO += 1;
|
||||
FOO
|
||||
}
|
||||
}
|
||||
assert_eq!(format!("{0} {0} {0} {a} {a} {a}", foo(), a = foo()), "1 1 1 2 2 2".to_string());
|
||||
counter_fn!(count);
|
||||
|
||||
assert_eq!(format!("{0} {0} {0} {a} {a} {a}", count(), a = count()), "1 1 1 2 2 2".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -1,2 +1,4 @@
|
|||
#[path = "../../testing/crash_test.rs"]
|
||||
pub mod crash_test;
|
||||
#[path = "../../testing/macros.rs"]
|
||||
pub mod macros;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
|
||||
#![allow(static_mut_refs)]
|
||||
|
||||
use core::alloc::{Allocator, Layout};
|
||||
use core::num::NonZero;
|
||||
use core::ptr::NonNull;
|
||||
|
|
@ -20,6 +17,8 @@ use std::rc::Rc;
|
|||
use std::sync::atomic::{AtomicU32, Ordering};
|
||||
use std::vec::{Drain, IntoIter};
|
||||
|
||||
use crate::testing::macros::struct_with_counted_drop;
|
||||
|
||||
struct DropCounter<'a> {
|
||||
count: &'a mut u32,
|
||||
}
|
||||
|
|
@ -548,32 +547,25 @@ fn test_cmp() {
|
|||
|
||||
#[test]
|
||||
fn test_vec_truncate_drop() {
|
||||
static mut DROPS: u32 = 0;
|
||||
struct Elem(#[allow(dead_code)] i32);
|
||||
impl Drop for Elem {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
struct_with_counted_drop!(Elem(i32), DROPS);
|
||||
|
||||
let mut v = vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)];
|
||||
assert_eq!(unsafe { DROPS }, 0);
|
||||
|
||||
assert_eq!(DROPS.get(), 0);
|
||||
v.truncate(3);
|
||||
assert_eq!(unsafe { DROPS }, 2);
|
||||
assert_eq!(DROPS.get(), 2);
|
||||
v.truncate(0);
|
||||
assert_eq!(unsafe { DROPS }, 5);
|
||||
assert_eq!(DROPS.get(), 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_vec_truncate_fail() {
|
||||
struct BadElem(i32);
|
||||
|
||||
impl Drop for BadElem {
|
||||
fn drop(&mut self) {
|
||||
let BadElem(ref mut x) = *self;
|
||||
if *x == 0xbadbeef {
|
||||
if let BadElem(0xbadbeef) = self {
|
||||
panic!("BadElem panic: 0xbadbeef")
|
||||
}
|
||||
}
|
||||
|
|
@ -812,22 +804,7 @@ fn test_drain_end_overflow() {
|
|||
#[test]
|
||||
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
|
||||
fn test_drain_leak() {
|
||||
static mut DROPS: i32 = 0;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct D(u32, bool);
|
||||
|
||||
impl Drop for D {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
|
||||
if self.1 {
|
||||
panic!("panic in `drop`");
|
||||
}
|
||||
}
|
||||
}
|
||||
struct_with_counted_drop!(D(u32, bool), DROPS => |this: &D| if this.1 { panic!("panic in `drop`"); });
|
||||
|
||||
let mut v = vec![
|
||||
D(0, false),
|
||||
|
|
@ -844,7 +821,7 @@ fn test_drain_leak() {
|
|||
}))
|
||||
.ok();
|
||||
|
||||
assert_eq!(unsafe { DROPS }, 4);
|
||||
assert_eq!(DROPS.get(), 4);
|
||||
assert_eq!(v, vec![D(0, false), D(1, false), D(6, false),]);
|
||||
}
|
||||
|
||||
|
|
@ -1057,27 +1034,13 @@ fn test_into_iter_clone() {
|
|||
#[test]
|
||||
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
|
||||
fn test_into_iter_leak() {
|
||||
static mut DROPS: i32 = 0;
|
||||
|
||||
struct D(bool);
|
||||
|
||||
impl Drop for D {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
|
||||
if self.0 {
|
||||
panic!("panic in `drop`");
|
||||
}
|
||||
}
|
||||
}
|
||||
struct_with_counted_drop!(D(bool), DROPS => |this: &D| if this.0 { panic!("panic in `drop`"); });
|
||||
|
||||
let v = vec![D(false), D(true), D(false)];
|
||||
|
||||
catch_unwind(move || drop(v.into_iter())).ok();
|
||||
|
||||
assert_eq!(unsafe { DROPS }, 3);
|
||||
assert_eq!(DROPS.get(), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -1274,55 +1237,31 @@ fn test_from_iter_specialization_panic_during_iteration_drops() {
|
|||
|
||||
#[test]
|
||||
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
|
||||
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
|
||||
#[allow(static_mut_refs)]
|
||||
fn test_from_iter_specialization_panic_during_drop_doesnt_leak() {
|
||||
static mut DROP_COUNTER_OLD: [usize; 5] = [0; 5];
|
||||
static mut DROP_COUNTER_NEW: [usize; 2] = [0; 2];
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Old(usize);
|
||||
|
||||
impl Drop for Old {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROP_COUNTER_OLD[self.0] += 1;
|
||||
struct_with_counted_drop!(
|
||||
Old(usize), DROP_COUNTER_OLD[|this: &Old| this.0, usize] =>
|
||||
|this: &Old| {
|
||||
if this.0 == 3 { panic!(); } println!("Dropped Old: {}", this.0)
|
||||
}
|
||||
|
||||
if self.0 == 3 {
|
||||
panic!();
|
||||
}
|
||||
|
||||
println!("Dropped Old: {}", self.0);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct New(usize);
|
||||
|
||||
impl Drop for New {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROP_COUNTER_NEW[self.0] += 1;
|
||||
}
|
||||
|
||||
println!("Dropped New: {}", self.0);
|
||||
}
|
||||
}
|
||||
);
|
||||
struct_with_counted_drop!(
|
||||
New(usize), DROP_COUNTER_NEW[|this: &New| this.0, usize] =>
|
||||
|this: &New| println!("Dropped New: {}", this.0)
|
||||
);
|
||||
|
||||
let _ = std::panic::catch_unwind(AssertUnwindSafe(|| {
|
||||
let v = vec![Old(0), Old(1), Old(2), Old(3), Old(4)];
|
||||
let _ = v.into_iter().map(|x| New(x.0)).take(2).collect::<Vec<_>>();
|
||||
}));
|
||||
|
||||
assert_eq!(unsafe { DROP_COUNTER_OLD[0] }, 1);
|
||||
assert_eq!(unsafe { DROP_COUNTER_OLD[1] }, 1);
|
||||
assert_eq!(unsafe { DROP_COUNTER_OLD[2] }, 1);
|
||||
assert_eq!(unsafe { DROP_COUNTER_OLD[3] }, 1);
|
||||
assert_eq!(unsafe { DROP_COUNTER_OLD[4] }, 1);
|
||||
DROP_COUNTER_OLD.with_borrow(|c| assert_eq!(c.get(&0), Some(&1)));
|
||||
DROP_COUNTER_OLD.with_borrow(|c| assert_eq!(c.get(&1), Some(&1)));
|
||||
DROP_COUNTER_OLD.with_borrow(|c| assert_eq!(c.get(&2), Some(&1)));
|
||||
DROP_COUNTER_OLD.with_borrow(|c| assert_eq!(c.get(&3), Some(&1)));
|
||||
DROP_COUNTER_OLD.with_borrow(|c| assert_eq!(c.get(&4), Some(&1)));
|
||||
|
||||
assert_eq!(unsafe { DROP_COUNTER_NEW[0] }, 1);
|
||||
assert_eq!(unsafe { DROP_COUNTER_NEW[1] }, 1);
|
||||
DROP_COUNTER_NEW.with_borrow(|c| assert_eq!(c.get(&0), Some(&1)));
|
||||
DROP_COUNTER_NEW.with_borrow(|c| assert_eq!(c.get(&1), Some(&1)));
|
||||
}
|
||||
|
||||
// regression test for issue #85322. Peekable previously implemented InPlaceIterable,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
|
||||
#![allow(static_mut_refs)]
|
||||
|
||||
use core::num::NonZero;
|
||||
use std::assert_matches::assert_matches;
|
||||
use std::collections::TryReserveErrorKind::*;
|
||||
|
|
@ -14,6 +11,7 @@ use Taggy::*;
|
|||
use Taggypar::*;
|
||||
|
||||
use crate::hash;
|
||||
use crate::testing::macros::struct_with_counted_drop;
|
||||
|
||||
#[test]
|
||||
fn test_simple() {
|
||||
|
|
@ -719,15 +717,7 @@ fn test_show() {
|
|||
|
||||
#[test]
|
||||
fn test_drop() {
|
||||
static mut DROPS: i32 = 0;
|
||||
struct Elem;
|
||||
impl Drop for Elem {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
struct_with_counted_drop!(Elem, DROPS);
|
||||
|
||||
let mut ring = VecDeque::new();
|
||||
ring.push_back(Elem);
|
||||
|
|
@ -736,20 +726,12 @@ fn test_drop() {
|
|||
ring.push_front(Elem);
|
||||
drop(ring);
|
||||
|
||||
assert_eq!(unsafe { DROPS }, 4);
|
||||
assert_eq!(DROPS.get(), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop_with_pop() {
|
||||
static mut DROPS: i32 = 0;
|
||||
struct Elem;
|
||||
impl Drop for Elem {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
struct_with_counted_drop!(Elem, DROPS);
|
||||
|
||||
let mut ring = VecDeque::new();
|
||||
ring.push_back(Elem);
|
||||
|
|
@ -759,23 +741,15 @@ fn test_drop_with_pop() {
|
|||
|
||||
drop(ring.pop_back());
|
||||
drop(ring.pop_front());
|
||||
assert_eq!(unsafe { DROPS }, 2);
|
||||
assert_eq!(DROPS.get(), 2);
|
||||
|
||||
drop(ring);
|
||||
assert_eq!(unsafe { DROPS }, 4);
|
||||
assert_eq!(DROPS.get(), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop_clear() {
|
||||
static mut DROPS: i32 = 0;
|
||||
struct Elem;
|
||||
impl Drop for Elem {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
struct_with_counted_drop!(Elem, DROPS);
|
||||
|
||||
let mut ring = VecDeque::new();
|
||||
ring.push_back(Elem);
|
||||
|
|
@ -783,30 +757,16 @@ fn test_drop_clear() {
|
|||
ring.push_back(Elem);
|
||||
ring.push_front(Elem);
|
||||
ring.clear();
|
||||
assert_eq!(unsafe { DROPS }, 4);
|
||||
assert_eq!(DROPS.get(), 4);
|
||||
|
||||
drop(ring);
|
||||
assert_eq!(unsafe { DROPS }, 4);
|
||||
assert_eq!(DROPS.get(), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
|
||||
fn test_drop_panic() {
|
||||
static mut DROPS: i32 = 0;
|
||||
|
||||
struct D(bool);
|
||||
|
||||
impl Drop for D {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
|
||||
if self.0 {
|
||||
panic!("panic in `drop`");
|
||||
}
|
||||
}
|
||||
}
|
||||
struct_with_counted_drop!(D(bool), DROPS => |this: &D| if this.0 { panic!("panic in `drop`"); } );
|
||||
|
||||
let mut q = VecDeque::new();
|
||||
q.push_back(D(false));
|
||||
|
|
@ -820,7 +780,7 @@ fn test_drop_panic() {
|
|||
|
||||
catch_unwind(move || drop(q)).ok();
|
||||
|
||||
assert_eq!(unsafe { DROPS }, 8);
|
||||
assert_eq!(DROPS.get(), 8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -1655,21 +1615,7 @@ fn test_try_rfold_moves_iter() {
|
|||
#[test]
|
||||
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
|
||||
fn truncate_leak() {
|
||||
static mut DROPS: i32 = 0;
|
||||
|
||||
struct D(bool);
|
||||
|
||||
impl Drop for D {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
|
||||
if self.0 {
|
||||
panic!("panic in `drop`");
|
||||
}
|
||||
}
|
||||
}
|
||||
struct_with_counted_drop!(D(bool), DROPS => |this: &D| if this.0 { panic!("panic in `drop`"); } );
|
||||
|
||||
let mut q = VecDeque::new();
|
||||
q.push_back(D(false));
|
||||
|
|
@ -1683,27 +1629,13 @@ fn truncate_leak() {
|
|||
|
||||
catch_unwind(AssertUnwindSafe(|| q.truncate(1))).ok();
|
||||
|
||||
assert_eq!(unsafe { DROPS }, 7);
|
||||
assert_eq!(DROPS.get(), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
|
||||
fn truncate_front_leak() {
|
||||
static mut DROPS: i32 = 0;
|
||||
|
||||
struct D(bool);
|
||||
|
||||
impl Drop for D {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
|
||||
if self.0 {
|
||||
panic!("panic in `drop`");
|
||||
}
|
||||
}
|
||||
}
|
||||
struct_with_counted_drop!(D(bool), DROPS => |this: &D| if this.0 { panic!("panic in `drop`"); } );
|
||||
|
||||
let mut q = VecDeque::new();
|
||||
q.push_back(D(false));
|
||||
|
|
@ -1717,28 +1649,13 @@ fn truncate_front_leak() {
|
|||
|
||||
catch_unwind(AssertUnwindSafe(|| q.truncate_front(1))).ok();
|
||||
|
||||
assert_eq!(unsafe { DROPS }, 7);
|
||||
assert_eq!(DROPS.get(), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
|
||||
fn test_drain_leak() {
|
||||
static mut DROPS: i32 = 0;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct D(u32, bool);
|
||||
|
||||
impl Drop for D {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
|
||||
if self.1 {
|
||||
panic!("panic in `drop`");
|
||||
}
|
||||
}
|
||||
}
|
||||
struct_with_counted_drop!(D(u32, bool), DROPS => |this: &D| if this.1 { panic!("panic in `drop`"); } );
|
||||
|
||||
let mut v = VecDeque::new();
|
||||
v.push_back(D(4, false));
|
||||
|
|
@ -1754,10 +1671,10 @@ fn test_drain_leak() {
|
|||
}))
|
||||
.ok();
|
||||
|
||||
assert_eq!(unsafe { DROPS }, 4);
|
||||
assert_eq!(DROPS.get(), 4);
|
||||
assert_eq!(v.len(), 3);
|
||||
drop(v);
|
||||
assert_eq!(unsafe { DROPS }, 7);
|
||||
assert_eq!(DROPS.get(), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -228,24 +228,20 @@ fn static_init() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
|
||||
#[allow(static_mut_refs)]
|
||||
fn atomic_access_bool() {
|
||||
static mut ATOMIC: AtomicBool = AtomicBool::new(false);
|
||||
let mut atom = AtomicBool::new(false);
|
||||
|
||||
unsafe {
|
||||
assert_eq!(*ATOMIC.get_mut(), false);
|
||||
ATOMIC.store(true, SeqCst);
|
||||
assert_eq!(*ATOMIC.get_mut(), true);
|
||||
ATOMIC.fetch_or(false, SeqCst);
|
||||
assert_eq!(*ATOMIC.get_mut(), true);
|
||||
ATOMIC.fetch_and(false, SeqCst);
|
||||
assert_eq!(*ATOMIC.get_mut(), false);
|
||||
ATOMIC.fetch_nand(true, SeqCst);
|
||||
assert_eq!(*ATOMIC.get_mut(), true);
|
||||
ATOMIC.fetch_xor(true, SeqCst);
|
||||
assert_eq!(*ATOMIC.get_mut(), false);
|
||||
}
|
||||
assert_eq!(*atom.get_mut(), false);
|
||||
atom.store(true, SeqCst);
|
||||
assert_eq!(*atom.get_mut(), true);
|
||||
atom.fetch_or(false, SeqCst);
|
||||
assert_eq!(*atom.get_mut(), true);
|
||||
atom.fetch_and(false, SeqCst);
|
||||
assert_eq!(*atom.get_mut(), false);
|
||||
atom.fetch_nand(true, SeqCst);
|
||||
assert_eq!(*atom.get_mut(), true);
|
||||
atom.fetch_xor(true, SeqCst);
|
||||
assert_eq!(*atom.get_mut(), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue