diff options
| author | Yosh <github@yosh.is> | 2025-07-21 03:04:17 +0200 |
|---|---|---|
| committer | Yosh <github@yosh.is> | 2025-07-28 12:12:40 +0200 |
| commit | 68f08c5dd9f5bee706a221df13660cc9b3a71c93 (patch) | |
| tree | fa46d29906a6d932e87b2df2b14aa8dafd57648f /library/coretests | |
| parent | 9982d6462bedf1e793f7b2dbd655a4e57cdf67d4 (diff) | |
| download | rust-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.rs | 1 | ||||
| -rw-r--r-- | library/coretests/tests/mem.rs | 46 |
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); +} |
