about summary refs log tree commit diff
path: root/library/coretests
diff options
context:
space:
mode:
authorYosh <github@yosh.is>2025-07-21 03:04:17 +0200
committerYosh <github@yosh.is>2025-07-28 12:12:40 +0200
commit68f08c5dd9f5bee706a221df13660cc9b3a71c93 (patch)
treefa46d29906a6d932e87b2df2b14aa8dafd57648f /library/coretests
parent9982d6462bedf1e793f7b2dbd655a4e57cdf67d4 (diff)
downloadrust-68f08c5dd9f5bee706a221df13660cc9b3a71c93.tar.gz
rust-68f08c5dd9f5bee706a221df13660cc9b3a71c93.zip
Add `core::mem::DropGuard`
Fix CI for drop_guard

fix CI

fix all tidy lints

fix tidy link

add first batch of feedback from review

Add second batch of feedback from review

add third batch of feedback from review

fix failing test

Update library/core/src/mem/drop_guard.rs

Co-authored-by: Ruby Lazuli <general@patchmixolydic.com>

fix doctests

Implement changes from T-Libs-API review

And start tracking based on the tracking issue.

fix tidy lint
Diffstat (limited to 'library/coretests')
-rw-r--r--library/coretests/tests/lib.rs1
-rw-r--r--library/coretests/tests/mem.rs46
2 files changed, 47 insertions, 0 deletions
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
index 4cfac9ecc2a..c8f516f0a95 100644
--- a/library/coretests/tests/lib.rs
+++ b/library/coretests/tests/lib.rs
@@ -30,6 +30,7 @@
 #![feature(core_private_diy_float)]
 #![feature(cstr_display)]
 #![feature(dec2flt)]
+#![feature(drop_guard)]
 #![feature(duration_constants)]
 #![feature(duration_constructors)]
 #![feature(duration_constructors_lite)]
diff --git a/library/coretests/tests/mem.rs b/library/coretests/tests/mem.rs
index 9c15be4a8c4..e896c61ef48 100644
--- a/library/coretests/tests/mem.rs
+++ b/library/coretests/tests/mem.rs
@@ -1,5 +1,6 @@
 use core::mem::*;
 use core::{array, ptr};
+use std::cell::Cell;
 #[cfg(panic = "unwind")]
 use std::rc::Rc;
 
@@ -795,3 +796,48 @@ fn const_maybe_uninit_zeroed() {
 
     assert_eq!(unsafe { (*UNINIT.0.cast::<[[u8; SIZE]; 1]>())[0] }, [0u8; SIZE]);
 }
+
+#[test]
+fn drop_guards_only_dropped_by_closure_when_run() {
+    let value_drops = Cell::new(0);
+    let value = DropGuard::new((), |()| value_drops.set(1 + value_drops.get()));
+    let closure_drops = Cell::new(0);
+    let guard = DropGuard::new(value, |_| closure_drops.set(1 + closure_drops.get()));
+    assert_eq!(value_drops.get(), 0);
+    assert_eq!(closure_drops.get(), 0);
+    drop(guard);
+    assert_eq!(value_drops.get(), 1);
+    assert_eq!(closure_drops.get(), 1);
+}
+
+#[test]
+fn drop_guard_into_inner() {
+    let dropped = Cell::new(false);
+    let value = DropGuard::new(42, |_| dropped.set(true));
+    let guard = DropGuard::new(value, |_| dropped.set(true));
+    let inner = DropGuard::into_inner(guard);
+    assert_eq!(dropped.get(), false);
+    assert_eq!(*inner, 42);
+}
+
+#[test]
+#[cfg(panic = "unwind")]
+fn drop_guard_always_drops_value_if_closure_drop_unwinds() {
+    // Create a value with a destructor, which we will validate ran successfully.
+    let mut value_was_dropped = false;
+    let value_with_tracked_destruction = DropGuard::new((), |_| value_was_dropped = true);
+
+    // Create a closure that will begin unwinding when dropped.
+    let drop_bomb = DropGuard::new((), |_| panic!());
+    let closure_that_panics_on_drop = move |_| {
+        let _drop_bomb = drop_bomb;
+    };
+
+    // This will run the closure, which will panic when dropped. This should
+    // run the destructor of the value we passed, which we validate.
+    let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
+        let guard = DropGuard::new(value_with_tracked_destruction, closure_that_panics_on_drop);
+        DropGuard::into_inner(guard);
+    }));
+    assert!(value_was_dropped);
+}