diff -Nru rust-scopeguard-0.3.3/Cargo.toml rust-scopeguard-1.0.0/Cargo.toml --- rust-scopeguard-0.3.3/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 +++ rust-scopeguard-1.0.0/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 @@ -12,12 +12,12 @@ [package] name = "scopeguard" -version = "0.3.3" +version = "1.0.0" authors = ["bluss"] -description = "A RAII scope guard that will run a given closure when it goes out of scope,\neven if the code between panics (assuming unwinding panic).\n\nDefines the macros `defer!` and `defer_on_unwind!`; the latter only runs\nif the scope is extited through unwinding on panic.\n" +description = "A RAII scope guard that will run a given closure when it goes out of scope,\neven if the code between panics (assuming unwinding panic).\n\nDefines the macros `defer!`, `defer_on_unwind!`, `defer_on_success!` as\nshorthands for guards with one of the implemented strategies.\n" documentation = "https://docs.rs/scopeguard/" -keywords = ["scope-guard", "defer", "panic"] -categories = ["rust-patterns"] +keywords = ["scope-guard", "defer", "panic", "unwind"] +categories = ["rust-patterns", "no-std"] license = "MIT/Apache-2.0" repository = "https://github.com/bluss/scopeguard" [package.metadata.release] diff -Nru rust-scopeguard-0.3.3/Cargo.toml.orig rust-scopeguard-1.0.0/Cargo.toml.orig --- rust-scopeguard-0.3.3/Cargo.toml.orig 2017-10-13 16:52:56.000000000 +0000 +++ rust-scopeguard-1.0.0/Cargo.toml.orig 2018-12-19 07:58:42.000000000 +0000 @@ -1,6 +1,6 @@ [package] name = "scopeguard" -version = "0.3.3" +version = "1.0.0" license = "MIT/Apache-2.0" repository = "https://github.com/bluss/scopeguard" @@ -11,12 +11,12 @@ A RAII scope guard that will run a given closure when it goes out of scope, even if the code between panics (assuming unwinding panic). -Defines the macros `defer!` and `defer_on_unwind!`; the latter only runs -if the scope is extited through unwinding on panic. +Defines the macros `defer!`, `defer_on_unwind!`, `defer_on_success!` as +shorthands for guards with one of the implemented strategies. """ -keywords = ["scope-guard", "defer", "panic"] -categories = ["rust-patterns"] +keywords = ["scope-guard", "defer", "panic", "unwind"] +categories = ["rust-patterns", "no-std"] [features] default = ["use_std"] diff -Nru rust-scopeguard-0.3.3/.cargo_vcs_info.json rust-scopeguard-1.0.0/.cargo_vcs_info.json --- rust-scopeguard-0.3.3/.cargo_vcs_info.json 1970-01-01 00:00:00.000000000 +0000 +++ rust-scopeguard-1.0.0/.cargo_vcs_info.json 1970-01-01 00:00:00.000000000 +0000 @@ -0,0 +1,5 @@ +{ + "git": { + "sha1": "5792dbfbeaa125978a5c96cce52695f0cc6c34d9" + } +} diff -Nru rust-scopeguard-0.3.3/debian/cargo-checksum.json rust-scopeguard-1.0.0/debian/cargo-checksum.json --- rust-scopeguard-0.3.3/debian/cargo-checksum.json 2018-07-07 21:01:01.000000000 +0000 +++ rust-scopeguard-1.0.0/debian/cargo-checksum.json 2019-10-15 10:55:47.000000000 +0000 @@ -1 +1 @@ -{"package":"94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27","files":{}} +{"package":"b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d","files":{}} diff -Nru rust-scopeguard-0.3.3/debian/changelog rust-scopeguard-1.0.0/debian/changelog --- rust-scopeguard-0.3.3/debian/changelog 2018-07-07 21:01:01.000000000 +0000 +++ rust-scopeguard-1.0.0/debian/changelog 2019-10-15 10:55:47.000000000 +0000 @@ -1,3 +1,15 @@ +rust-scopeguard (1.0.0-2) unstable; urgency=medium + + * Source-only re-upload for migration to testing + + -- kpcyrd Tue, 15 Oct 2019 10:55:47 +0000 + +rust-scopeguard (1.0.0-1) unstable; urgency=medium + + * Package scopeguard 1.0.0 from crates.io using debcargo 2.4.0 + + -- kpcyrd Wed, 04 Sep 2019 23:25:51 -0700 + rust-scopeguard (0.3.3-1) unstable; urgency=medium * Package scopeguard 0.3.3 from crates.io using debcargo 2.2.1 diff -Nru rust-scopeguard-0.3.3/debian/control rust-scopeguard-1.0.0/debian/control --- rust-scopeguard-0.3.3/debian/control 2018-07-07 21:01:01.000000000 +0000 +++ rust-scopeguard-1.0.0/debian/control 2019-10-15 10:55:47.000000000 +0000 @@ -2,18 +2,17 @@ Section: rust Priority: optional Build-Depends: debhelper (>= 11), - dh-cargo (>= 6), + dh-cargo (>= 18), cargo:native , rustc:native , libstd-rust-dev Maintainer: Debian Rust Maintainers -Uploaders: Ximin Luo -Standards-Version: 4.1.5 +Uploaders: + kpcyrd +Standards-Version: 4.2.0 Vcs-Git: https://salsa.debian.org/rust-team/debcargo-conf.git [src/scopeguard] Vcs-Browser: https://salsa.debian.org/rust-team/debcargo-conf/tree/master/src/scopeguard -# FIXME (packages."(name)".section) debcargo auto-generated summaries are very long, consider overriding - Package: librust-scopeguard-dev Architecture: any Multi-Arch: same @@ -22,18 +21,18 @@ Provides: librust-scopeguard+default-dev (= ${binary:Version}), librust-scopeguard+use-std-dev (= ${binary:Version}), - librust-scopeguard-0-dev (= ${binary:Version}), - librust-scopeguard-0+default-dev (= ${binary:Version}), - librust-scopeguard-0+use-std-dev (= ${binary:Version}), - librust-scopeguard-0.3-dev (= ${binary:Version}), - librust-scopeguard-0.3+default-dev (= ${binary:Version}), - librust-scopeguard-0.3+use-std-dev (= ${binary:Version}), - librust-scopeguard-0.3.3-dev (= ${binary:Version}), - librust-scopeguard-0.3.3+default-dev (= ${binary:Version}), - librust-scopeguard-0.3.3+use-std-dev (= ${binary:Version}) -Description: RAII scope guard that will run a given closure when it goes out of scope, even if the code between panics (assuming unwinding panic) - Rust source code - Defines the macros `defer!` and `defer_on_unwind!`; the latter only runs if the - scope is extited through unwinding on panic. + librust-scopeguard-1-dev (= ${binary:Version}), + librust-scopeguard-1+default-dev (= ${binary:Version}), + librust-scopeguard-1+use-std-dev (= ${binary:Version}), + librust-scopeguard-1.0-dev (= ${binary:Version}), + librust-scopeguard-1.0+default-dev (= ${binary:Version}), + librust-scopeguard-1.0+use-std-dev (= ${binary:Version}), + librust-scopeguard-1.0.0-dev (= ${binary:Version}), + librust-scopeguard-1.0.0+default-dev (= ${binary:Version}), + librust-scopeguard-1.0.0+use-std-dev (= ${binary:Version}) +Description: Resource-acquisition-is-initialization scope guard - Rust source code + Defines the macros `defer!`, `defer_on_unwind!`, `defer_on_success!` as + shorthands for guards with one of the implemented strategies. . This package contains the source for the Rust scopeguard crate, packaged by debcargo for use with cargo and dh-cargo. diff -Nru rust-scopeguard-0.3.3/debian/copyright.debcargo.hint rust-scopeguard-1.0.0/debian/copyright.debcargo.hint --- rust-scopeguard-0.3.3/debian/copyright.debcargo.hint 2018-07-07 21:01:01.000000000 +0000 +++ rust-scopeguard-1.0.0/debian/copyright.debcargo.hint 2019-10-15 10:55:47.000000000 +0000 @@ -21,8 +21,8 @@ Files: debian/* Copyright: - 2018 Debian Rust Maintainers - 2018 FIXME (overlay) Your Name + 2018-2019 Debian Rust Maintainers + 2018-2019 kpcyrd License: MIT or Apache-2.0 License: Apache-2.0 diff -Nru rust-scopeguard-0.3.3/debian/debcargo.toml rust-scopeguard-1.0.0/debian/debcargo.toml --- rust-scopeguard-0.3.3/debian/debcargo.toml 2018-07-07 21:01:01.000000000 +0000 +++ rust-scopeguard-1.0.0/debian/debcargo.toml 2019-10-15 10:55:47.000000000 +0000 @@ -1 +1,5 @@ overlay = "." +uploaders = ["kpcyrd "] + +# The auto-generated summary is too long. +summary = "Resource-acquisition-is-initialization scope guard" diff -Nru rust-scopeguard-0.3.3/debian/rules rust-scopeguard-1.0.0/debian/rules --- rust-scopeguard-0.3.3/debian/rules 2018-07-07 21:01:01.000000000 +0000 +++ rust-scopeguard-1.0.0/debian/rules 2019-10-15 10:55:47.000000000 +0000 @@ -1,3 +1,6 @@ #!/usr/bin/make -f %: dh $@ --buildsystem cargo + +override_dh_auto_test: + dh_auto_test -- test --all diff -Nru rust-scopeguard-0.3.3/debian/tests/control rust-scopeguard-1.0.0/debian/tests/control --- rust-scopeguard-0.3.3/debian/tests/control 1970-01-01 00:00:00.000000000 +0000 +++ rust-scopeguard-1.0.0/debian/tests/control 2019-10-15 10:55:47.000000000 +0000 @@ -0,0 +1,7 @@ +Test-Command: /usr/share/cargo/bin/cargo-auto-test scopeguard 1.0.0 --all-targets --all-features +Depends: dh-cargo (>= 18), @ +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test scopeguard 1.0.0 --all-targets --no-default-features +Depends: dh-cargo (>= 18), librust-scopeguard-dev +Restrictions: allow-stderr, skip-not-installable diff -Nru rust-scopeguard-0.3.3/debian/watch rust-scopeguard-1.0.0/debian/watch --- rust-scopeguard-0.3.3/debian/watch 2018-07-07 21:01:01.000000000 +0000 +++ rust-scopeguard-1.0.0/debian/watch 2019-10-15 10:55:47.000000000 +0000 @@ -1,4 +1,5 @@ version=4 -opts=filenamemangle=s/.*\/(.*)\/download/scopeguard-$1\.tar\.gz/g\ - https://qa.debian.org/cgi-bin/fakeupstream.cgi?upstream=crates.io/scopeguard .*/crates/scopeguard/@ANY_VERSION@/download +opts=filenamemangle=s/.*\/(.*)\/download/scopeguard-$1\.tar\.gz/g,\ +uversionmangle=s/(\d)[_\.\-\+]?((RC|rc|pre|dev|beta|alpha)\d*)$/$1~$2/ \ +https://qa.debian.org/cgi-bin/fakeupstream.cgi?upstream=crates.io/scopeguard .*/crates/scopeguard/@ANY_VERSION@/download diff -Nru rust-scopeguard-0.3.3/examples/readme.rs rust-scopeguard-1.0.0/examples/readme.rs --- rust-scopeguard-0.3.3/examples/readme.rs 2016-12-11 16:14:58.000000000 +0000 +++ rust-scopeguard-1.0.0/examples/readme.rs 2018-12-16 13:29:22.000000000 +0000 @@ -18,7 +18,7 @@ let _ = f.sync_all(); }); // Access the file through the scope guard itself - file.write(b"test me\n").unwrap(); + file.write_all(b"test me\n").unwrap(); } fn main() { diff -Nru rust-scopeguard-0.3.3/README.rst rust-scopeguard-1.0.0/README.rst --- rust-scopeguard-0.3.3/README.rst 2017-10-13 16:53:46.000000000 +0000 +++ rust-scopeguard-1.0.0/README.rst 2018-12-19 07:59:31.000000000 +0000 @@ -6,9 +6,9 @@ it goes out of scope, even if the code between panics (assuming unwinding panic). The `defer!` macro and `guard` are `no_std` compatible (require only core), -but the on unwinding strategy requires linking to `std`. +but the on unwinding / not on uwinding strategies requires linking to `std`. -Requires Rust 1.11. +Requires Rust 1.20. Please read the `API documentation here`__ @@ -47,12 +47,29 @@ let _ = f.sync_all(); }); // Access the file through the scope guard itself - file.write(b"test me\n").unwrap(); + file.write_all(b"test me\n").unwrap(); } Recent Changes -------------- +- 1.0.0 + + - Change the closure type from ``FnMut(&mut T)`` to ``FnOnce(T)``: + Passing the inner value by value instead of a mutable reference is a + breaking change, but allows the guard closure to consume it. (by @tormol) + + - Add ``defer_on_success!{}``, ``guard_on_success()`` and ``OnSuccess`` + strategy, which triggers when scope is exited *without* panic. It's the + opposite to ``OnUnwind`` / ``guard_on_unwind()`` / ``defer_on_unwind!{}``. + + - Add ``ScopeGuard::into_inner()``, which "defuses" the guard and returns the + guarded value. (by @tormol) + + - Implement ``Sync`` for guards with non-``Sync`` closures. + + - Require Rust 1.20 + - 0.3.3 - Use ``#[inline]`` on a few more functions by @stjepang (#14) diff -Nru rust-scopeguard-0.3.3/src/lib.rs rust-scopeguard-1.0.0/src/lib.rs --- rust-scopeguard-0.3.3/src/lib.rs 2017-10-13 16:52:56.000000000 +0000 +++ rust-scopeguard-1.0.0/src/lib.rs 2018-12-19 07:59:14.000000000 +0000 @@ -1,4 +1,5 @@ #![cfg_attr(not(any(test, feature = "use_std")), no_std)] +#![doc(html_root_url = "https://docs.rs/scopeguard/1/")] //! A scope guard will run a given closure when it goes out of scope, //! even if the code between panics. @@ -6,6 +7,28 @@ //! //! # Examples //! +//! ## Hello World +//! +//! This example creates a scope guard with an example function: +//! +//! ``` +//! extern crate scopeguard; +//! +//! fn f() { +//! let _guard = scopeguard::guard((), |_| { +//! println!("Hello Scope Exit!"); +//! }); +//! +//! // rest of the code here. +//! +//! // Here, at the end of `_guard`'s scope, the guard's closure is called. +//! // It is also called if we exit this scope through unwinding instead. +//! } +//! # fn main() { +//! # f(); +//! # } +//! ``` +//! //! ## `defer!` //! //! Use the `defer` macro to run an operation at scope exit, @@ -51,8 +74,16 @@ //! ``` //! extern crate scopeguard; //! -//! use std::fs::File; +//! use std::fs::*; //! use std::io::{self, Write}; +//! # // Mock file so that we don't actually write a file +//! # struct MockFile; +//! # impl MockFile { +//! # fn create(_s: &str) -> io::Result { Ok(MockFile) } +//! # fn write_all(&self, _b: &[u8]) -> io::Result<()> { Ok(()) } +//! # fn sync_all(&self) -> io::Result<()> { Ok(()) } +//! # } +//! # use self::MockFile as File; //! //! fn try_main() -> io::Result<()> { //! let f = File::create("newfile.txt")?; @@ -61,7 +92,7 @@ //! let _ = f.sync_all(); //! }); //! // Access the file through the scope guard itself -//! file.write(b"test me\n").map(|_| ()) +//! file.write_all(b"test me\n").map(|_| ()) //! } //! //! fn main() { @@ -143,19 +174,30 @@ //! ``` //! //! -//! # Crate features: +//! # Crate Features //! //! - `use_std` -//! + Enabled by default. Enables the `OnUnwind` strategy. +//! + Enabled by default. Enables the `OnUnwind` and `OnSuccess` strategies. //! + Disable to use `no_std`. +//! +//! # Rust Version +//! +//! This version of the crate requires Rust 1.20 or later. +//! +//! The scopeguard 1.x release series will use a carefully considered version +//! upgrade policy, where in a later 1.x version, we will raise the minimum +//! required Rust version. #[cfg(not(any(test, feature = "use_std")))] extern crate core as std; use std::fmt; use std::marker::PhantomData; +use std::mem::{self, ManuallyDrop}; use std::ops::{Deref, DerefMut}; +use std::ptr; +/// Controls in which cases the associated code should be run pub trait Strategy { /// Return `true` if the guard’s associated code should run /// (in the context where this method is called). @@ -182,8 +224,7 @@ /// Requires crate feature `use_std`. #[cfg(feature = "use_std")] #[derive(Debug)] -#[cfg(test)] -enum OnSuccess {} +pub enum OnSuccess {} impl Strategy for Always { #[inline(always)] @@ -192,14 +233,13 @@ #[cfg(feature = "use_std")] impl Strategy for OnUnwind { - #[inline(always)] + #[inline] fn should_run() -> bool { std::thread::panicking() } } #[cfg(feature = "use_std")] -#[cfg(test)] impl Strategy for OnSuccess { - #[inline(always)] + #[inline] fn should_run() -> bool { !std::thread::panicking() } } @@ -211,7 +251,7 @@ #[macro_export] macro_rules! defer { ($e:expr) => { - let _guard = $crate::guard((), |_| $e); + let _guard = $crate::guard((), |()| $e); } } @@ -222,10 +262,11 @@ /// be a whole block. /// /// Requires crate feature `use_std`. -#[cfg(test)] +#[cfg(feature = "use_std")] +#[macro_export] macro_rules! defer_on_success { ($e:expr) => { - let _guard = $crate::guard_on_success((), |_| $e); + let _guard = $crate::guard_on_success((), |()| $e); } } @@ -236,10 +277,11 @@ /// be a whole block. /// /// Requires crate feature `use_std`. +#[cfg(feature = "use_std")] #[macro_export] macro_rules! defer_on_unwind { ($e:expr) => { - let _guard = $crate::guard_on_unwind((), |_| $e); + let _guard = $crate::guard_on_unwind((), |()| $e); } } @@ -253,19 +295,20 @@ /// The `S` parameter for [`Strategy`](Strategy.t.html) determines if /// the closure actually runs. /// -/// The guard's closure will be called with a mut ref to the held value -/// in the destructor. It's called only once. +/// The guard's closure will be called with the held value in the destructor. /// /// The `ScopeGuard` implements `Deref` so that you can access the inner value. -pub struct ScopeGuard - where F: FnMut(&mut T) +pub struct ScopeGuard + where F: FnOnce(T), + S: Strategy, { - __dropfn: F, - __value: T, - strategy: PhantomData, + value: ManuallyDrop, + dropfn: ManuallyDrop, + strategy: PhantomData S>, } + impl ScopeGuard - where F: FnMut(&mut T), + where F: FnOnce(T), S: Strategy, { /// Create a `ScopeGuard` that owns `v` (accessible through deref) and calls @@ -275,18 +318,55 @@ #[inline] pub fn with_strategy(v: T, dropfn: F) -> ScopeGuard { ScopeGuard { - __value: v, - __dropfn: dropfn, + value: ManuallyDrop::new(v), + dropfn: ManuallyDrop::new(dropfn), strategy: PhantomData, } } + + /// “Defuse” the guard and extract the value without calling the closure. + /// + /// ``` + /// extern crate scopeguard; + /// use scopeguard::{guard, ScopeGuard}; + /// + /// fn conditional() -> bool { true } + /// + /// fn main() { + /// let mut guard = guard(Vec::new(), |mut v| v.clear()); + /// guard.push(1); + /// + /// if conditional() { + /// // a condition maybe makes us decide to + /// // “defuse” the guard and get back its inner parts + /// let value = ScopeGuard::into_inner(guard); + /// } else { + /// // guard still exists in this branch + /// } + /// } + /// ``` + #[inline] + pub fn into_inner(guard: Self) -> T { + // Cannot pattern match out of Drop-implementing types, so + // ptr::read the value and forget the guard. + unsafe { + let value = ptr::read(&*guard.value); + // read the closure so that it is dropped, and assign it to a local + // variable to ensure that it is only dropped after the guard has + // been forgotten. (In case the Drop impl of the closure, or that + // of any consumed captured variable, panics). + let _dropfn = ptr::read(&*guard.dropfn); + mem::forget(guard); + value + } + } } /// Create a new `ScopeGuard` owning `v` and with deferred closure `dropfn`. #[inline] pub fn guard(v: T, dropfn: F) -> ScopeGuard - where F: FnMut(&mut T) + where F: FnOnce(T) { ScopeGuard::with_strategy(v, dropfn) } @@ -295,10 +375,9 @@ /// /// Requires crate feature `use_std`. #[cfg(feature = "use_std")] -#[cfg(test)] #[inline] -fn guard_on_success(v: T, dropfn: F) -> ScopeGuard - where F: FnMut(&mut T) +pub fn guard_on_success(v: T, dropfn: F) -> ScopeGuard + where F: FnOnce(T) { ScopeGuard::with_strategy(v, dropfn) } @@ -306,56 +385,97 @@ /// Create a new `ScopeGuard` owning `v` and with deferred closure `dropfn`. /// /// Requires crate feature `use_std`. +/// +/// ## Examples +/// +/// For performance reasons, or to emulate “only run guard on unwind” in +/// no-std environments, we can also use the default guard and simply manually +/// defuse it at the end of scope like the following example. (The performance +/// reason would be if the [`OnUnwind`]'s call to [std::thread::panicking()] is +/// an issue.) +/// +/// ``` +/// extern crate scopeguard; +/// +/// use scopeguard::ScopeGuard; +/// # fn main() { +/// { +/// let guard = scopeguard::guard((), |_| { }); +/// +/// // rest of the code here +/// +/// // we reached the end of scope without unwinding - defuse it +/// ScopeGuard::into_inner(guard); +/// } +/// # } +/// ``` #[cfg(feature = "use_std")] #[inline] pub fn guard_on_unwind(v: T, dropfn: F) -> ScopeGuard - where F: FnMut(&mut T) + where F: FnOnce(T) { ScopeGuard::with_strategy(v, dropfn) } -impl Deref for ScopeGuard - where F: FnMut(&mut T) +// ScopeGuard can be Sync even if F isn't because the closure is +// not accessible from references. +// The guard does not store any instance of S, so it is also irellevant. +unsafe impl Sync for ScopeGuard + where T: Sync, + F: FnOnce(T), + S: Strategy +{ } + +impl Deref for ScopeGuard + where F: FnOnce(T), + S: Strategy { type Target = T; fn deref(&self) -> &T { - &self.__value + &*self.value } - } -impl DerefMut for ScopeGuard - where F: FnMut(&mut T) +impl DerefMut for ScopeGuard + where F: FnOnce(T), + S: Strategy { fn deref_mut(&mut self) -> &mut T { - &mut self.__value + &mut*self.value } } -impl Drop for ScopeGuard - where F: FnMut(&mut T) +impl Drop for ScopeGuard + where F: FnOnce(T), + S: Strategy { fn drop(&mut self) { + // This is OK because the fields are `ManuallyDrop`s + // which will not be dropped by the compiler. + let (value, dropfn) = unsafe { + (ptr::read(&*self.value), ptr::read(&*self.dropfn)) + }; if S::should_run() { - (self.__dropfn)(&mut self.__value) + dropfn(value); } } } impl fmt::Debug for ScopeGuard where T: fmt::Debug, - F: FnMut(&mut T), - S: Strategy + fmt::Debug, + F: FnOnce(T), + S: Strategy { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("ScopeGuard") - .field("value", &self.__value) + f.debug_struct(stringify!(ScopeGuard)) + .field("value", &*self.value) .finish() } } #[cfg(test)] mod tests { + use super::*; use std::cell::Cell; use std::panic::catch_unwind; use std::panic::AssertUnwindSafe; @@ -367,6 +487,7 @@ assert_eq!(drops.get(), 0); } + #[cfg(feature = "use_std")] #[test] fn test_defer_success_1() { let drops = Cell::new(0); @@ -377,6 +498,7 @@ assert_eq!(drops.get(), 1); } + #[cfg(feature = "use_std")] #[test] fn test_defer_success_2() { let drops = Cell::new(0); @@ -387,6 +509,7 @@ assert_eq!(drops.get(), 0); } + #[cfg(feature = "use_std")] #[test] fn test_defer_unwind_1() { let drops = Cell::new(0); @@ -398,6 +521,7 @@ assert_eq!(drops.get(), 1); } + #[cfg(feature = "use_std")] #[test] fn test_defer_unwind_2() { let drops = Cell::new(0); @@ -406,4 +530,49 @@ } assert_eq!(drops.get(), 0); } + + #[test] + fn test_only_dropped_by_closure_when_run() { + let value_drops = Cell::new(0); + let value = guard((), |()| value_drops.set(1 + value_drops.get())); + let closure_drops = Cell::new(0); + let guard = guard(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); + } + + #[cfg(feature = "use_std")] + #[test] + fn test_dropped_once_when_not_run() { + let value_drops = Cell::new(0); + let value = guard((), |()| value_drops.set(1 + value_drops.get())); + let captured_drops = Cell::new(0); + let captured = guard((), |()| captured_drops.set(1 + captured_drops.get())); + let closure_drops = Cell::new(0); + let guard = guard_on_unwind(value, |value| { + drop(value); + drop(captured); + closure_drops.set(1 + closure_drops.get()) + }); + assert_eq!(value_drops.get(), 0); + assert_eq!(captured_drops.get(), 0); + assert_eq!(closure_drops.get(), 0); + drop(guard); + assert_eq!(value_drops.get(), 1); + assert_eq!(captured_drops.get(), 1); + assert_eq!(closure_drops.get(), 0); + } + + #[test] + fn test_into_inner() { + let dropped = Cell::new(false); + let value = guard(42, |_| dropped.set(true)); + let guard = guard(value, |_| dropped.set(true)); + let inner = ScopeGuard::into_inner(guard); + assert_eq!(dropped.get(), false); + assert_eq!(*inner, 42); + } } diff -Nru rust-scopeguard-0.3.3/.travis.yml rust-scopeguard-1.0.0/.travis.yml --- rust-scopeguard-0.3.3/.travis.yml 2017-10-13 16:41:16.000000000 +0000 +++ rust-scopeguard-1.0.0/.travis.yml 2018-12-17 18:49:35.000000000 +0000 @@ -2,7 +2,7 @@ sudo: false rust: - - 1.11.0 + - 1.20.0 - stable - beta - nightly @@ -15,5 +15,6 @@ script: - | cargo build --no-default-features && + cargo test --no-default-features && cargo build && - ([ "$TRAVIS_RUST_VERSION" != "1.11.0" ] && cargo test ) || cargo test --lib + cargo test