about summary refs log tree commit diff
path: root/src/test/ui/drop
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2021-01-21 22:35:05 -0500
committerFelix S. Klock II <pnkfelix@pnkfx.org>2021-02-04 21:29:49 -0500
commita71a81948074f7a3e2b5ce0dee3ad98fa22f793b (patch)
tree0222d8b0134ac0f0c5434d4308e4127ff96fc7b5 /src/test/ui/drop
parentdab3a80f235ed86d64d002e58b35adc3664e21a4 (diff)
downloadrust-a71a81948074f7a3e2b5ce0dee3ad98fa22f793b.tar.gz
rust-a71a81948074f7a3e2b5ce0dee3ad98fa22f793b.zip
Revert "Avoid leaking block expression values"
This reverts commit 4fef39113a514bb270f5661a82fdba17d3e41dbb.
Diffstat (limited to 'src/test/ui/drop')
-rw-r--r--src/test/ui/drop/dynamic-drop-async.rs165
-rw-r--r--src/test/ui/drop/dynamic-drop.rs437
2 files changed, 223 insertions, 379 deletions
diff --git a/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs
index cb6d58a23d9..c0bf0bdf731 100644
--- a/src/test/ui/drop/dynamic-drop-async.rs
+++ b/src/test/ui/drop/dynamic-drop-async.rs
@@ -43,7 +43,6 @@ impl<T: Unpin> Future for Defer<T> {
 /// The `failing_op`-th operation will panic.
 struct Allocator {
     data: RefCell<Vec<bool>>,
-    name: &'static str,
     failing_op: usize,
     cur_ops: Cell<usize>,
 }
@@ -55,28 +54,23 @@ impl Drop for Allocator {
     fn drop(&mut self) {
         let data = self.data.borrow();
         if data.iter().any(|d| *d) {
-            panic!("missing free in {:?}: {:?}", self.name, data);
+            panic!("missing free: {:?}", data);
         }
     }
 }
 
 impl Allocator {
-    fn new(failing_op: usize, name: &'static str) -> Self {
-        Allocator {
-            failing_op,
-            name,
-            cur_ops: Cell::new(0),
-            data: RefCell::new(vec![]),
-        }
+    fn new(failing_op: usize) -> Self {
+        Allocator { failing_op, cur_ops: Cell::new(0), data: RefCell::new(vec![]) }
     }
-    fn alloc(self: &Rc<Allocator>) -> impl Future<Output = Ptr> + 'static {
+    fn alloc(&self) -> impl Future<Output = Ptr<'_>> + '_ {
         self.fallible_operation();
 
         let mut data = self.data.borrow_mut();
 
         let addr = data.len();
         data.push(true);
-        Defer { ready: false, value: Some(Ptr(addr, self.clone())) }
+        Defer { ready: false, value: Some(Ptr(addr, self)) }
     }
     fn fallible_operation(&self) {
         self.cur_ops.set(self.cur_ops.get() + 1);
@@ -89,11 +83,11 @@ impl Allocator {
 
 // Type that tracks whether it was dropped and can panic when it's created or
 // destroyed.
-struct Ptr(usize, Rc<Allocator>);
-impl Drop for Ptr {
+struct Ptr<'a>(usize, &'a Allocator);
+impl<'a> Drop for Ptr<'a> {
     fn drop(&mut self) {
         match self.1.data.borrow_mut()[self.0] {
-            false => panic!("double free in {:?} at index {:?}", self.1.name, self.0),
+            false => panic!("double free at index {:?}", self.0),
             ref mut d => *d = false,
         }
 
@@ -117,7 +111,7 @@ async fn dynamic_drop(a: Rc<Allocator>, c: bool) {
     };
 }
 
-struct TwoPtrs(Ptr, Ptr);
+struct TwoPtrs<'a>(Ptr<'a>, Ptr<'a>);
 async fn struct_dynamic_drop(a: Rc<Allocator>, c0: bool, c1: bool, c: bool) {
     for i in 0..2 {
         let x;
@@ -238,62 +232,21 @@ async fn move_ref_pattern(a: Rc<Allocator>) {
     a.alloc().await;
 }
 
-async fn panic_after_return(a: Rc<Allocator>, c: bool) -> (Ptr,) {
-    a.alloc().await;
-    let p = a.alloc().await;
-    if c {
-        a.alloc().await;
-        let q = a.alloc().await;
-        // We use a return type that isn't used anywhere else to make sure that
-        // the return place doesn't incorrectly end up in the generator state.
-        return (a.alloc().await,);
-    }
-    (a.alloc().await,)
-}
-
-
-async fn panic_after_init_by_loop(a: Rc<Allocator>) {
-    a.alloc().await;
-    let p = a.alloc().await;
-    let q = loop {
-        a.alloc().await;
-        let r = a.alloc().await;
-        break a.alloc().await;
-    };
-}
-
-async fn panic_after_init_by_match_with_bindings_and_guard(a: Rc<Allocator>, b: bool) {
-    a.alloc().await;
-    let p = a.alloc().await;
-    let q = match a.alloc().await {
-        ref _x if b => {
-            a.alloc().await;
-            let r = a.alloc().await;
-            a.alloc().await
-        }
-        _x => {
-            a.alloc().await;
-            let r = a.alloc().await;
-            a.alloc().await
-        },
-    };
-}
-
-fn run_test<F, G, O>(cx: &mut Context<'_>, ref f: F, name: &'static str)
+fn run_test<F, G>(cx: &mut Context<'_>, ref f: F)
 where
     F: Fn(Rc<Allocator>) -> G,
-    G: Future<Output = O>,
+    G: Future<Output = ()>,
 {
     for polls in 0.. {
         // Run without any panics to find which operations happen after the
         // penultimate `poll`.
-        let first_alloc = Rc::new(Allocator::new(usize::MAX, name));
+        let first_alloc = Rc::new(Allocator::new(usize::MAX));
         let mut fut = Box::pin(f(first_alloc.clone()));
         let mut ops_before_last_poll = 0;
         let mut completed = false;
         for _ in 0..polls {
             ops_before_last_poll = first_alloc.cur_ops.get();
-            if let Poll::Ready(_) = fut.as_mut().poll(cx) {
+            if let Poll::Ready(()) = fut.as_mut().poll(cx) {
                 completed = true;
             }
         }
@@ -302,7 +255,7 @@ where
         // Start at `ops_before_last_poll` so that we will always be able to
         // `poll` the expected number of times.
         for failing_op in ops_before_last_poll..first_alloc.cur_ops.get() {
-            let alloc = Rc::new(Allocator::new(failing_op + 1, name));
+            let alloc = Rc::new(Allocator::new(failing_op + 1));
             let f = &f;
             let cx = &mut *cx;
             let result = panic::catch_unwind(panic::AssertUnwindSafe(move || {
@@ -332,58 +285,48 @@ fn clone_waker(data: *const ()) -> RawWaker {
     RawWaker::new(data, &RawWakerVTable::new(clone_waker, drop, drop, drop))
 }
 
-macro_rules! run_test {
-    ($ctxt:expr, $e:expr) => { run_test($ctxt, $e, stringify!($e)); };
-}
-
 fn main() {
     let waker = unsafe { Waker::from_raw(clone_waker(ptr::null())) };
     let context = &mut Context::from_waker(&waker);
 
-    run_test!(context, |a| dynamic_init(a, false));
-    run_test!(context, |a| dynamic_init(a, true));
-    run_test!(context, |a| dynamic_drop(a, false));
-    run_test!(context, |a| dynamic_drop(a, true));
-
-    run_test!(context, |a| assignment(a, false, false));
-    run_test!(context, |a| assignment(a, false, true));
-    run_test!(context, |a| assignment(a, true, false));
-    run_test!(context, |a| assignment(a, true, true));
-
-    run_test!(context, |a| array_simple(a));
-    run_test!(context, |a| vec_simple(a));
-    run_test!(context, |a| vec_unreachable(a));
-
-    run_test!(context, |a| struct_dynamic_drop(a, false, false, false));
-    run_test!(context, |a| struct_dynamic_drop(a, false, false, true));
-    run_test!(context, |a| struct_dynamic_drop(a, false, true, false));
-    run_test!(context, |a| struct_dynamic_drop(a, false, true, true));
-    run_test!(context, |a| struct_dynamic_drop(a, true, false, false));
-    run_test!(context, |a| struct_dynamic_drop(a, true, false, true));
-    run_test!(context, |a| struct_dynamic_drop(a, true, true, false));
-    run_test!(context, |a| struct_dynamic_drop(a, true, true, true));
-
-    run_test!(context, |a| field_assignment(a, false));
-    run_test!(context, |a| field_assignment(a, true));
-
-    run_test!(context, |a| mixed_drop_and_nondrop(a));
-
-    run_test!(context, |a| slice_pattern_one_of(a, 0));
-    run_test!(context, |a| slice_pattern_one_of(a, 1));
-    run_test!(context, |a| slice_pattern_one_of(a, 2));
-    run_test!(context, |a| slice_pattern_one_of(a, 3));
-
-    run_test!(context, |a| subslice_pattern_from_end_with_drop(a, true, true));
-    run_test!(context, |a| subslice_pattern_from_end_with_drop(a, true, false));
-    run_test!(context, |a| subslice_pattern_from_end_with_drop(a, false, true));
-    run_test!(context, |a| subslice_pattern_from_end_with_drop(a, false, false));
-    run_test!(context, |a| subslice_pattern_reassign(a));
-
-    run_test!(context, |a| move_ref_pattern(a));
-
-    run_test!(context, |a| panic_after_return(a, false));
-    run_test!(context, |a| panic_after_return(a, true));
-    run_test!(context, |a| panic_after_init_by_loop(a));
-    run_test!(context, |a| panic_after_init_by_match_with_bindings_and_guard(a, false));
-    run_test!(context, |a| panic_after_init_by_match_with_bindings_and_guard(a, true));
+    run_test(context, |a| dynamic_init(a, false));
+    run_test(context, |a| dynamic_init(a, true));
+    run_test(context, |a| dynamic_drop(a, false));
+    run_test(context, |a| dynamic_drop(a, true));
+
+    run_test(context, |a| assignment(a, false, false));
+    run_test(context, |a| assignment(a, false, true));
+    run_test(context, |a| assignment(a, true, false));
+    run_test(context, |a| assignment(a, true, true));
+
+    run_test(context, |a| array_simple(a));
+    run_test(context, |a| vec_simple(a));
+    run_test(context, |a| vec_unreachable(a));
+
+    run_test(context, |a| struct_dynamic_drop(a, false, false, false));
+    run_test(context, |a| struct_dynamic_drop(a, false, false, true));
+    run_test(context, |a| struct_dynamic_drop(a, false, true, false));
+    run_test(context, |a| struct_dynamic_drop(a, false, true, true));
+    run_test(context, |a| struct_dynamic_drop(a, true, false, false));
+    run_test(context, |a| struct_dynamic_drop(a, true, false, true));
+    run_test(context, |a| struct_dynamic_drop(a, true, true, false));
+    run_test(context, |a| struct_dynamic_drop(a, true, true, true));
+
+    run_test(context, |a| field_assignment(a, false));
+    run_test(context, |a| field_assignment(a, true));
+
+    run_test(context, |a| mixed_drop_and_nondrop(a));
+
+    run_test(context, |a| slice_pattern_one_of(a, 0));
+    run_test(context, |a| slice_pattern_one_of(a, 1));
+    run_test(context, |a| slice_pattern_one_of(a, 2));
+    run_test(context, |a| slice_pattern_one_of(a, 3));
+
+    run_test(context, |a| subslice_pattern_from_end_with_drop(a, true, true));
+    run_test(context, |a| subslice_pattern_from_end_with_drop(a, true, false));
+    run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, true));
+    run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, false));
+    run_test(context, |a| subslice_pattern_reassign(a));
+
+    run_test(context, |a| move_ref_pattern(a));
 }
diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs
index e28bedb982d..e90ea1c55b0 100644
--- a/src/test/ui/drop/dynamic-drop.rs
+++ b/src/test/ui/drop/dynamic-drop.rs
@@ -3,6 +3,7 @@
 
 #![feature(generators, generator_trait)]
 #![feature(bindings_after_at)]
+
 #![allow(unused_assignments)]
 #![allow(unused_variables)]
 
@@ -16,7 +17,6 @@ struct InjectedFailure;
 
 struct Allocator {
     data: RefCell<Vec<bool>>,
-    name: &'static str,
     failing_op: usize,
     cur_ops: Cell<usize>,
 }
@@ -28,18 +28,17 @@ impl Drop for Allocator {
     fn drop(&mut self) {
         let data = self.data.borrow();
         if data.iter().any(|d| *d) {
-            panic!("missing free in {:?}: {:?}", self.name, data);
+            panic!("missing free: {:?}", data);
         }
     }
 }
 
 impl Allocator {
-    fn new(failing_op: usize, name: &'static str) -> Self {
+    fn new(failing_op: usize) -> Self {
         Allocator {
             failing_op: failing_op,
             cur_ops: Cell::new(0),
-            data: RefCell::new(vec![]),
-            name,
+            data: RefCell::new(vec![])
         }
     }
     fn alloc(&self) -> Ptr<'_> {
@@ -54,17 +53,33 @@ impl Allocator {
         data.push(true);
         Ptr(addr, self)
     }
+    // FIXME(#47949) Any use of this indicates a bug in rustc: we should never
+    // be leaking values in the cases here.
+    //
+    // Creates a `Ptr<'_>` and checks that the allocated value is leaked if the
+    // `failing_op` is in the list of exception.
+    fn alloc_leaked(&self, exceptions: Vec<usize>) -> Ptr<'_> {
+        let ptr = self.alloc();
+
+        if exceptions.iter().any(|operation| *operation == self.failing_op) {
+            let mut data = self.data.borrow_mut();
+            data[ptr.0] = false;
+        }
+        ptr
+    }
 }
 
 struct Ptr<'a>(usize, &'a Allocator);
 impl<'a> Drop for Ptr<'a> {
     fn drop(&mut self) {
         match self.1.data.borrow_mut()[self.0] {
-            false => panic!("double free in {:?} at index {:?}", self.1.name, self.0),
-            ref mut d => *d = false,
+            false => {
+                panic!("double free at index {:?}", self.0)
+            }
+            ref mut d => *d = false
         }
 
-        self.1.cur_ops.set(self.1.cur_ops.get() + 1);
+        self.1.cur_ops.set(self.1.cur_ops.get()+1);
 
         if self.1.cur_ops.get() == self.1.failing_op {
             panic::panic_any(InjectedFailure);
@@ -162,7 +177,11 @@ fn generator(a: &Allocator, run_count: usize) {
     assert!(run_count < 4);
 
     let mut gen = || {
-        (a.alloc(), yield a.alloc(), a.alloc(), yield a.alloc());
+        (a.alloc(),
+         yield a.alloc(),
+         a.alloc(),
+         yield a.alloc()
+         );
     };
     for _ in 0..run_count {
         Pin::new(&mut gen).resume(());
@@ -186,40 +205,28 @@ fn vec_unreachable(a: &Allocator) {
 }
 
 fn slice_pattern_first(a: &Allocator) {
-    let [_x, ..] = [a.alloc(), a.alloc(), a.alloc()];
+    let[_x, ..] = [a.alloc(), a.alloc(), a.alloc()];
 }
 
 fn slice_pattern_middle(a: &Allocator) {
-    let [_, _x, _] = [a.alloc(), a.alloc(), a.alloc()];
+    let[_, _x, _] = [a.alloc(), a.alloc(), a.alloc()];
 }
 
 fn slice_pattern_two(a: &Allocator) {
-    let [_x, _, _y, _] = [a.alloc(), a.alloc(), a.alloc(), a.alloc()];
+    let[_x, _, _y, _] = [a.alloc(), a.alloc(), a.alloc(), a.alloc()];
 }
 
 fn slice_pattern_last(a: &Allocator) {
-    let [.., _y] = [a.alloc(), a.alloc(), a.alloc(), a.alloc()];
+    let[.., _y] = [a.alloc(), a.alloc(), a.alloc(), a.alloc()];
 }
 
 fn slice_pattern_one_of(a: &Allocator, i: usize) {
     let array = [a.alloc(), a.alloc(), a.alloc(), a.alloc()];
     let _x = match i {
-        0 => {
-            let [a, ..] = array;
-            a
-        }
-        1 => {
-            let [_, a, ..] = array;
-            a
-        }
-        2 => {
-            let [_, _, a, _] = array;
-            a
-        }
-        3 => {
-            let [_, _, _, a] = array;
-            a
-        }
+        0 => { let [a, ..] = array; a }
+        1 => { let [_, a, ..] = array; a }
+        2 => { let [_, _, a, _] = array; a }
+        3 => { let [_, _, _, a] = array; a }
         _ => panic!("unmatched"),
     };
 }
@@ -227,9 +234,9 @@ fn slice_pattern_one_of(a: &Allocator, i: usize) {
 fn subslice_pattern_from_end(a: &Allocator, arg: bool) {
     let a = [a.alloc(), a.alloc(), a.alloc()];
     if arg {
-        let [.., _x, _] = a;
+        let[.., _x, _] = a;
     } else {
-        let [_, _y @ ..] = a;
+        let[_, _y @ ..] = a;
     }
 }
 
@@ -241,61 +248,45 @@ fn subslice_pattern_from_end_with_drop(a: &Allocator, arg: bool, arg2: bool) {
     }
 
     if arg {
-        let [.., _x, _] = a;
+        let[.., _x, _] = a;
     } else {
-        let [_, _y @ ..] = a;
+        let[_, _y @ ..] = a;
     }
 }
 
 fn slice_pattern_reassign(a: &Allocator) {
     let mut ar = [a.alloc(), a.alloc()];
-    let [_, _x] = ar;
+    let[_, _x] = ar;
     ar = [a.alloc(), a.alloc()];
-    let [.., _y] = ar;
+    let[.., _y] = ar;
 }
 
 fn subslice_pattern_reassign(a: &Allocator) {
     let mut ar = [a.alloc(), a.alloc(), a.alloc()];
-    let [_, _, _x] = ar;
+    let[_, _, _x] = ar;
     ar = [a.alloc(), a.alloc(), a.alloc()];
-    let [_, _y @ ..] = ar;
+    let[_, _y @ ..] = ar;
 }
 
 fn index_field_mixed_ends(a: &Allocator) {
     let ar = [(a.alloc(), a.alloc()), (a.alloc(), a.alloc())];
-    let [(_x, _), ..] = ar;
-    let [(_, _y), _] = ar;
-    let [_, (_, _w)] = ar;
-    let [.., (_z, _)] = ar;
+    let[(_x, _), ..] = ar;
+    let[(_, _y), _] = ar;
+    let[_, (_, _w)] = ar;
+    let[.., (_z, _)] = ar;
 }
 
 fn subslice_mixed_min_lengths(a: &Allocator, c: i32) {
     let ar = [(a.alloc(), a.alloc()), (a.alloc(), a.alloc())];
     match c {
-        0 => {
-            let [_x, ..] = ar;
-        }
-        1 => {
-            let [_x, _, ..] = ar;
-        }
-        2 => {
-            let [_x, _] = ar;
-        }
-        3 => {
-            let [(_x, _), _, ..] = ar;
-        }
-        4 => {
-            let [.., (_x, _)] = ar;
-        }
-        5 => {
-            let [.., (_x, _), _] = ar;
-        }
-        6 => {
-            let [_y @ ..] = ar;
-        }
-        _ => {
-            let [_y @ .., _] = ar;
-        }
+        0 => { let[_x, ..] = ar; }
+        1 => { let[_x, _, ..] = ar; }
+        2 => { let[_x, _] = ar; }
+        3 => { let[(_x, _), _, ..] = ar; }
+        4 => { let[.., (_x, _)] = ar; }
+        5 => { let[.., (_x, _), _] = ar; }
+        6 => { let [_y @ ..] = ar; }
+        _ => { let [_y @ .., _] = ar; }
     }
 }
 
@@ -343,160 +334,87 @@ fn move_ref_pattern(a: &Allocator) {
 }
 
 fn panic_after_return(a: &Allocator) -> Ptr<'_> {
+    // Panic in the drop of `p` or `q` can leak
+    let exceptions = vec![8, 9];
     a.alloc();
     let p = a.alloc();
     {
         a.alloc();
         let p = a.alloc();
-        a.alloc()
+        // FIXME (#47949) We leak values when we panic in a destructor after
+        // evaluating an expression with `rustc_mir::build::Builder::into`.
+        a.alloc_leaked(exceptions)
     }
 }
 
 fn panic_after_return_expr(a: &Allocator) -> Ptr<'_> {
+    // Panic in the drop of `p` or `q` can leak
+    let exceptions = vec![8, 9];
     a.alloc();
     let p = a.alloc();
     {
         a.alloc();
         let q = a.alloc();
-        return a.alloc();
+        // FIXME (#47949)
+        return a.alloc_leaked(exceptions);
     }
 }
 
 fn panic_after_init(a: &Allocator) {
+    // Panic in the drop of `r` can leak
+    let exceptions = vec![8];
     a.alloc();
     let p = a.alloc();
     let q = {
         a.alloc();
         let r = a.alloc();
-        a.alloc()
+        // FIXME (#47949)
+        a.alloc_leaked(exceptions)
     };
 }
 
 fn panic_after_init_temp(a: &Allocator) {
+    // Panic in the drop of `r` can leak
+    let exceptions = vec![8];
     a.alloc();
     let p = a.alloc();
     {
         a.alloc();
         let r = a.alloc();
-        a.alloc()
+        // FIXME (#47949)
+        a.alloc_leaked(exceptions)
     };
 }
 
 fn panic_after_init_by_loop(a: &Allocator) {
+    // Panic in the drop of `r` can leak
+    let exceptions = vec![8];
     a.alloc();
     let p = a.alloc();
     let q = loop {
         a.alloc();
         let r = a.alloc();
-        break a.alloc();
-    };
-}
-
-fn panic_after_init_by_match(a: &Allocator, b: bool) {
-    a.alloc();
-    let p = a.alloc();
-    let _ = loop {
-        let q = match b {
-            true => {
-                a.alloc();
-                let r = a.alloc();
-                a.alloc()
-            }
-            false => {
-                a.alloc();
-                let r = a.alloc();
-                break a.alloc();
-            }
-        };
-        return;
-    };
-}
-
-fn panic_after_init_by_match_with_guard(a: &Allocator, b: bool) {
-    a.alloc();
-    let p = a.alloc();
-    let q = match a.alloc() {
-        _ if b => {
-            a.alloc();
-            let r = a.alloc();
-            a.alloc()
-        }
-        _ => {
-            a.alloc();
-            let r = a.alloc();
-            a.alloc()
-        }
-    };
-}
-
-fn panic_after_init_by_match_with_bindings_and_guard(a: &Allocator, b: bool) {
-    a.alloc();
-    let p = a.alloc();
-    let q = match a.alloc() {
-        _x if b => {
-            a.alloc();
-            let r = a.alloc();
-            a.alloc()
-        }
-        _x => {
-            a.alloc();
-            let r = a.alloc();
-            a.alloc()
-        }
-    };
-}
-
-fn panic_after_init_by_match_with_ref_bindings_and_guard(a: &Allocator, b: bool) {
-    a.alloc();
-    let p = a.alloc();
-    let q = match a.alloc() {
-        ref _x if b => {
-            a.alloc();
-            let r = a.alloc();
-            a.alloc()
-        }
-        ref _x => {
-            a.alloc();
-            let r = a.alloc();
-            a.alloc()
-        }
-    };
-}
-
-fn panic_after_init_by_break_if(a: &Allocator, b: bool) {
-    a.alloc();
-    let p = a.alloc();
-    let q = loop {
-        let r = a.alloc();
-        break if b {
-            let s = a.alloc();
-            a.alloc()
-        } else {
-            a.alloc()
-        };
+        // FIXME (#47949)
+        break a.alloc_leaked(exceptions);
     };
 }
 
-fn run_test<F>(mut f: F, name: &'static str)
-where
-    F: FnMut(&Allocator),
+fn run_test<F>(mut f: F)
+    where F: FnMut(&Allocator)
 {
-    let first_alloc = Allocator::new(usize::MAX, name);
+    let first_alloc = Allocator::new(usize::MAX);
     f(&first_alloc);
 
-    for failing_op in 1..first_alloc.cur_ops.get() + 1 {
-        let alloc = Allocator::new(failing_op, name);
+    for failing_op in 1..first_alloc.cur_ops.get()+1 {
+        let alloc = Allocator::new(failing_op);
         let alloc = &alloc;
         let f = panic::AssertUnwindSafe(&mut f);
         let result = panic::catch_unwind(move || {
             f.0(alloc);
         });
         match result {
-            Ok(..) => panic!(
-                "test executed {} ops but now {}",
-                first_alloc.cur_ops.get(),
-                alloc.cur_ops.get()
-            ),
+            Ok(..) => panic!("test executed {} ops but now {}",
+                             first_alloc.cur_ops.get(), alloc.cur_ops.get()),
             Err(e) => {
                 if e.downcast_ref::<InjectedFailure>().is_none() {
                     panic::resume_unwind(e);
@@ -506,115 +424,98 @@ where
     }
 }
 
-fn run_test_nopanic<F>(mut f: F, name: &'static str)
-where
-    F: FnMut(&Allocator),
+fn run_test_nopanic<F>(mut f: F)
+    where F: FnMut(&Allocator)
 {
-    let first_alloc = Allocator::new(usize::MAX, name);
+    let first_alloc = Allocator::new(usize::MAX);
     f(&first_alloc);
 }
 
-macro_rules! run_test {
-    ($e:expr) => {
-        run_test($e, stringify!($e));
-    };
-}
-
 fn main() {
-    run_test!(|a| dynamic_init(a, false));
-    run_test!(|a| dynamic_init(a, true));
-    run_test!(|a| dynamic_drop(a, false));
-    run_test!(|a| dynamic_drop(a, true));
-
-    run_test!(|a| assignment2(a, false, false));
-    run_test!(|a| assignment2(a, false, true));
-    run_test!(|a| assignment2(a, true, false));
-    run_test!(|a| assignment2(a, true, true));
-
-    run_test!(|a| assignment1(a, false));
-    run_test!(|a| assignment1(a, true));
-
-    run_test!(|a| array_simple(a));
-    run_test!(|a| vec_simple(a));
-    run_test!(|a| vec_unreachable(a));
-
-    run_test!(|a| struct_dynamic_drop(a, false, false, false));
-    run_test!(|a| struct_dynamic_drop(a, false, false, true));
-    run_test!(|a| struct_dynamic_drop(a, false, true, false));
-    run_test!(|a| struct_dynamic_drop(a, false, true, true));
-    run_test!(|a| struct_dynamic_drop(a, true, false, false));
-    run_test!(|a| struct_dynamic_drop(a, true, false, true));
-    run_test!(|a| struct_dynamic_drop(a, true, true, false));
-    run_test!(|a| struct_dynamic_drop(a, true, true, true));
-
-    run_test!(|a| field_assignment(a, false));
-    run_test!(|a| field_assignment(a, true));
-
-    run_test!(|a| generator(a, 0));
-    run_test!(|a| generator(a, 1));
-    run_test!(|a| generator(a, 2));
-    run_test!(|a| generator(a, 3));
-
-    run_test!(|a| mixed_drop_and_nondrop(a));
-
-    run_test!(|a| slice_pattern_first(a));
-    run_test!(|a| slice_pattern_middle(a));
-    run_test!(|a| slice_pattern_two(a));
-    run_test!(|a| slice_pattern_last(a));
-    run_test!(|a| slice_pattern_one_of(a, 0));
-    run_test!(|a| slice_pattern_one_of(a, 1));
-    run_test!(|a| slice_pattern_one_of(a, 2));
-    run_test!(|a| slice_pattern_one_of(a, 3));
-
-    run_test!(|a| subslice_pattern_from_end(a, true));
-    run_test!(|a| subslice_pattern_from_end(a, false));
-    run_test!(|a| subslice_pattern_from_end_with_drop(a, true, true));
-    run_test!(|a| subslice_pattern_from_end_with_drop(a, true, false));
-    run_test!(|a| subslice_pattern_from_end_with_drop(a, false, true));
-    run_test!(|a| subslice_pattern_from_end_with_drop(a, false, false));
-    run_test!(|a| slice_pattern_reassign(a));
-    run_test!(|a| subslice_pattern_reassign(a));
-
-    run_test!(|a| index_field_mixed_ends(a));
-    run_test!(|a| subslice_mixed_min_lengths(a, 0));
-    run_test!(|a| subslice_mixed_min_lengths(a, 1));
-    run_test!(|a| subslice_mixed_min_lengths(a, 2));
-    run_test!(|a| subslice_mixed_min_lengths(a, 3));
-    run_test!(|a| subslice_mixed_min_lengths(a, 4));
-    run_test!(|a| subslice_mixed_min_lengths(a, 5));
-    run_test!(|a| subslice_mixed_min_lengths(a, 6));
-    run_test!(|a| subslice_mixed_min_lengths(a, 7));
-
-    run_test!(|a| move_ref_pattern(a));
-
-    run_test!(|a| {
+    run_test(|a| dynamic_init(a, false));
+    run_test(|a| dynamic_init(a, true));
+    run_test(|a| dynamic_drop(a, false));
+    run_test(|a| dynamic_drop(a, true));
+
+    run_test(|a| assignment2(a, false, false));
+    run_test(|a| assignment2(a, false, true));
+    run_test(|a| assignment2(a, true, false));
+    run_test(|a| assignment2(a, true, true));
+
+    run_test(|a| assignment1(a, false));
+    run_test(|a| assignment1(a, true));
+
+    run_test(|a| array_simple(a));
+    run_test(|a| vec_simple(a));
+    run_test(|a| vec_unreachable(a));
+
+    run_test(|a| struct_dynamic_drop(a, false, false, false));
+    run_test(|a| struct_dynamic_drop(a, false, false, true));
+    run_test(|a| struct_dynamic_drop(a, false, true, false));
+    run_test(|a| struct_dynamic_drop(a, false, true, true));
+    run_test(|a| struct_dynamic_drop(a, true, false, false));
+    run_test(|a| struct_dynamic_drop(a, true, false, true));
+    run_test(|a| struct_dynamic_drop(a, true, true, false));
+    run_test(|a| struct_dynamic_drop(a, true, true, true));
+
+    run_test(|a| field_assignment(a, false));
+    run_test(|a| field_assignment(a, true));
+
+    run_test(|a| generator(a, 0));
+    run_test(|a| generator(a, 1));
+    run_test(|a| generator(a, 2));
+    run_test(|a| generator(a, 3));
+
+    run_test(|a| mixed_drop_and_nondrop(a));
+
+    run_test(|a| slice_pattern_first(a));
+    run_test(|a| slice_pattern_middle(a));
+    run_test(|a| slice_pattern_two(a));
+    run_test(|a| slice_pattern_last(a));
+    run_test(|a| slice_pattern_one_of(a, 0));
+    run_test(|a| slice_pattern_one_of(a, 1));
+    run_test(|a| slice_pattern_one_of(a, 2));
+    run_test(|a| slice_pattern_one_of(a, 3));
+
+    run_test(|a| subslice_pattern_from_end(a, true));
+    run_test(|a| subslice_pattern_from_end(a, false));
+    run_test(|a| subslice_pattern_from_end_with_drop(a, true, true));
+    run_test(|a| subslice_pattern_from_end_with_drop(a, true, false));
+    run_test(|a| subslice_pattern_from_end_with_drop(a, false, true));
+    run_test(|a| subslice_pattern_from_end_with_drop(a, false, false));
+    run_test(|a| slice_pattern_reassign(a));
+    run_test(|a| subslice_pattern_reassign(a));
+
+    run_test(|a| index_field_mixed_ends(a));
+    run_test(|a| subslice_mixed_min_lengths(a, 0));
+    run_test(|a| subslice_mixed_min_lengths(a, 1));
+    run_test(|a| subslice_mixed_min_lengths(a, 2));
+    run_test(|a| subslice_mixed_min_lengths(a, 3));
+    run_test(|a| subslice_mixed_min_lengths(a, 4));
+    run_test(|a| subslice_mixed_min_lengths(a, 5));
+    run_test(|a| subslice_mixed_min_lengths(a, 6));
+    run_test(|a| subslice_mixed_min_lengths(a, 7));
+
+    run_test(|a| move_ref_pattern(a));
+
+    run_test(|a| {
         panic_after_return(a);
     });
-    run_test!(|a| {
+    run_test(|a| {
         panic_after_return_expr(a);
     });
-    run_test!(|a| panic_after_init(a));
-    run_test!(|a| panic_after_init_temp(a));
-    run_test!(|a| panic_after_init_by_loop(a));
-    run_test!(|a| panic_after_init_by_match(a, false));
-    run_test!(|a| panic_after_init_by_match(a, true));
-    run_test!(|a| panic_after_init_by_match_with_guard(a, false));
-    run_test!(|a| panic_after_init_by_match_with_guard(a, true));
-    run_test!(|a| panic_after_init_by_match_with_bindings_and_guard(a, false));
-    run_test!(|a| panic_after_init_by_match_with_bindings_and_guard(a, true));
-    run_test!(|a| panic_after_init_by_match_with_ref_bindings_and_guard(a, false));
-    run_test!(|a| panic_after_init_by_match_with_ref_bindings_and_guard(a, true));
-    run_test!(|a| panic_after_init_by_break_if(a, false));
-    run_test!(|a| panic_after_init_by_break_if(a, true));
-
-    run_test!(|a| bindings_after_at_dynamic_init_move(a, true));
-    run_test!(|a| bindings_after_at_dynamic_init_move(a, false));
-    run_test!(|a| bindings_after_at_dynamic_init_ref(a, true));
-    run_test!(|a| bindings_after_at_dynamic_init_ref(a, false));
-    run_test!(|a| bindings_after_at_dynamic_drop_move(a, true));
-    run_test!(|a| bindings_after_at_dynamic_drop_move(a, false));
-    run_test!(|a| bindings_after_at_dynamic_drop_ref(a, true));
-    run_test!(|a| bindings_after_at_dynamic_drop_ref(a, false));
-
-    run_test_nopanic(|a| union1(a), "|a| union1(a)");
+    run_test(|a| panic_after_init(a));
+    run_test(|a| panic_after_init_temp(a));
+    run_test(|a| panic_after_init_by_loop(a));
+
+    run_test(|a| bindings_after_at_dynamic_init_move(a, true));
+    run_test(|a| bindings_after_at_dynamic_init_move(a, false));
+    run_test(|a| bindings_after_at_dynamic_init_ref(a, true));
+    run_test(|a| bindings_after_at_dynamic_init_ref(a, false));
+    run_test(|a| bindings_after_at_dynamic_drop_move(a, true));
+    run_test(|a| bindings_after_at_dynamic_drop_move(a, false));
+    run_test(|a| bindings_after_at_dynamic_drop_ref(a, true));
+    run_test(|a| bindings_after_at_dynamic_drop_ref(a, false));
+
+    run_test_nopanic(|a| union1(a));
 }