Skip to content

Commit e4193fb

Browse files
authored
Rollup merge of rust-lang#72628 - MikailBag:array-default-tests, r=shepmaster
Add tests for 'impl Default for [T; N]' Related: rust-lang#71690. This pull request adds two tests: - Even it T::default() panics, no leaks occur. - [T; 0] is Default even if T is not. I believe at some moment `Default` impl for arrays will be rewritten to use const generics instead of macros, and these tests will help to prevent behavior changes.
2 parents 874a176 + 591584e commit e4193fb

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

src/libcore/tests/array.rs

+41
Original file line numberDiff line numberDiff line change
@@ -241,3 +241,44 @@ fn iterator_drops() {
241241
}
242242
assert_eq!(i.get(), 5);
243243
}
244+
245+
#[test]
246+
fn array_default_impl_avoids_leaks_on_panic() {
247+
use core::sync::atomic::{AtomicUsize, Ordering::Relaxed};
248+
static COUNTER: AtomicUsize = AtomicUsize::new(0);
249+
#[derive(Debug)]
250+
struct Bomb(usize);
251+
252+
impl Default for Bomb {
253+
fn default() -> Bomb {
254+
if COUNTER.load(Relaxed) == 3 {
255+
panic!("bomb limit exceeded");
256+
}
257+
258+
COUNTER.fetch_add(1, Relaxed);
259+
Bomb(COUNTER.load(Relaxed))
260+
}
261+
}
262+
263+
impl Drop for Bomb {
264+
fn drop(&mut self) {
265+
COUNTER.fetch_sub(1, Relaxed);
266+
}
267+
}
268+
269+
let res = std::panic::catch_unwind(|| <[Bomb; 5]>::default());
270+
let panic_msg = match res {
271+
Ok(_) => unreachable!(),
272+
Err(p) => p.downcast::<&'static str>().unwrap(),
273+
};
274+
assert_eq!(*panic_msg, "bomb limit exceeded");
275+
// check that all bombs are successfully dropped
276+
assert_eq!(COUNTER.load(Relaxed), 0);
277+
}
278+
279+
#[test]
280+
fn empty_array_is_always_default() {
281+
struct DoesNotImplDefault;
282+
283+
let _arr = <[DoesNotImplDefault; 0]>::default();
284+
}

0 commit comments

Comments
 (0)