Skip to content

Commit

Permalink
Rollup merge of rust-lang#72628 - MikailBag:array-default-tests, r=sh…
Browse files Browse the repository at this point in the history
…epmaster

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.
  • Loading branch information
Dylan-DPC committed Jun 15, 2020
2 parents b014e35 + 3313bf6 commit ba22791
Showing 1 changed file with 49 additions and 0 deletions.
49 changes: 49 additions & 0 deletions src/libcore/tests/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,52 @@ fn iterator_drops() {
}
assert_eq!(i.get(), 5);
}

// This test does not work on targets without panic=unwind support.
// To work around this problem, test is marked is should_panic, so it will
// be automagically skipped on unsuitable targets, such as
// wasm32-unknown-unkown.
//
// It means that we use panic for indicating success.
#[test]
#[should_panic(expected = "test succeeded")]
fn array_default_impl_avoids_leaks_on_panic() {
use core::sync::atomic::{AtomicUsize, Ordering::Relaxed};
static COUNTER: AtomicUsize = AtomicUsize::new(0);
#[derive(Debug)]
struct Bomb(usize);

impl Default for Bomb {
fn default() -> Bomb {
if COUNTER.load(Relaxed) == 3 {
panic!("bomb limit exceeded");
}

COUNTER.fetch_add(1, Relaxed);
Bomb(COUNTER.load(Relaxed))
}
}

impl Drop for Bomb {
fn drop(&mut self) {
COUNTER.fetch_sub(1, Relaxed);
}
}

let res = std::panic::catch_unwind(|| <[Bomb; 5]>::default());
let panic_msg = match res {
Ok(_) => unreachable!(),
Err(p) => p.downcast::<&'static str>().unwrap(),
};
assert_eq!(*panic_msg, "bomb limit exceeded");
// check that all bombs are successfully dropped
assert_eq!(COUNTER.load(Relaxed), 0);
panic!("test succeeded")
}

#[test]
fn empty_array_is_always_default() {
struct DoesNotImplDefault;

let _arr = <[DoesNotImplDefault; 0]>::default();
}

0 comments on commit ba22791

Please sign in to comment.