From 1c69721b1ca7fe5cf3bfd45c9380c77193fd4d71 Mon Sep 17 00:00:00 2001 From: alecmocatta Date: Mon, 2 Sep 2019 00:25:18 +0100 Subject: [PATCH 1/2] make on_unwind pub but undocumented --- src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index af4907e..51c032d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -97,8 +97,9 @@ impl Drop for OnUnwind { } } +#[doc(hidden)] #[inline(always)] -fn on_unwind T, T, P: FnOnce()>(f: F, p: P) -> T { +pub fn on_unwind T, T, P: FnOnce()>(f: F, p: P) -> T { let x = OnUnwind(mem::ManuallyDrop::new(p)); let t = f(); let _ = unsafe { ptr::read(&*x.0) }; From 2ebc4310faae8b67a4912cfbfc36d95aab2cf375 Mon Sep 17 00:00:00 2001 From: alecmocatta Date: Mon, 2 Sep 2019 00:25:29 +0100 Subject: [PATCH 2/2] v0.1.4 --- Cargo.toml | 4 ++-- README.md | 12 ++++++------ src/lib.rs | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 452f34c..1d20b60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "replace_with" -version = "0.1.3" +version = "0.1.4" license = "MIT OR Apache-2.0" authors = ["Alec Mocatta "] categories = ["rust-patterns"] @@ -10,7 +10,7 @@ Temporarily take ownership of a value at a mutable location, and replace it with """ repository = "https://github.com/alecmocatta/replace_with" homepage = "https://github.com/alecmocatta/replace_with" -documentation = "https://docs.rs/replace_with/0.1.3" +documentation = "https://docs.rs/replace_with/0.1.4" readme = "README.md" edition = "2018" diff --git a/README.md b/README.md index fb86952..16d4062 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,15 @@ [![MIT / Apache 2.0 licensed](https://img.shields.io/crates/l/replace_with.svg?maxAge=2592000)](#License) [![Build Status](https://dev.azure.com/alecmocatta/replace_with/_apis/build/status/tests?branchName=master)](https://dev.azure.com/alecmocatta/replace_with/_build/latest?branchName=master) -[Docs](https://docs.rs/replace_with/0.1.3) +[Docs](https://docs.rs/replace_with/0.1.4) Temporarily take ownership of a value at a mutable location, and replace it with a new value based on the old one. -This crate provides the function [`replace_with()`](https://docs.rs/replace_with/0.1.3/replace_with/fn.replace_with.html), which is like [`std::mem::replace()`](https://doc.rust-lang.org/std/mem/fn.replace.html) except it allows the replacement value to be mapped from the original value. +This crate provides the function [`replace_with()`](https://docs.rs/replace_with/0.1.4/replace_with/fn.replace_with.html), which is like [`std::mem::replace()`](https://doc.rust-lang.org/std/mem/fn.replace.html) except it allows the replacement value to be mapped from the original value. See [RFC 1736](https://github.com/rust-lang/rfcs/pull/1736) for a lot of discussion as to its merits. It was never merged, and the desired ability to temporarily move out of `&mut T` doesn't exist yet, so this crate is my interim solution. -It's very akin to [`take_mut`](https://github.com/Sgeo/take_mut), though uses `Drop` instead of [`std::panic::catch_unwind()`](https://doc.rust-lang.org/std/panic/fn.catch_unwind.html) to react to unwinding, which avoids the optimisation barrier of calling the `extern "C" __rust_maybe_catch_panic()`. As such it's up to ∞x faster. The API also attempts to make slightly more explicit the behavior on panic – [`replace_with()`](https://docs.rs/replace_with/0.1.3/replace_with/fn.replace_with.html) accepts two closures such that aborting in the "standard case" where the mapping closure (`FnOnce(T) -> T`) panics (as [`take_mut::take()`](https://docs.rs/take_mut/0.2.2/take_mut/fn.take.html) does) is avoided. If the second closure (`FnOnce() -> T`) panics, however, then it does indeed abort. The "abort on first panic" behaviour is available with [`replace_with_or_abort()`](https://docs.rs/replace_with/0.1.3/replace_with/fn.replace_with_or_abort.html). +It's very akin to [`take_mut`](https://github.com/Sgeo/take_mut), though uses `Drop` instead of [`std::panic::catch_unwind()`](https://doc.rust-lang.org/std/panic/fn.catch_unwind.html) to react to unwinding, which avoids the optimisation barrier of calling the `extern "C" __rust_maybe_catch_panic()`. As such it's up to ∞x faster. The API also attempts to make slightly more explicit the behavior on panic – [`replace_with()`](https://docs.rs/replace_with/0.1.4/replace_with/fn.replace_with.html) accepts two closures such that aborting in the "standard case" where the mapping closure (`FnOnce(T) -> T`) panics (as [`take_mut::take()`](https://docs.rs/take_mut/0.2.2/take_mut/fn.take.html) does) is avoided. If the second closure (`FnOnce() -> T`) panics, however, then it does indeed abort. The "abort on first panic" behaviour is available with [`replace_with_or_abort()`](https://docs.rs/replace_with/0.1.4/replace_with/fn.replace_with_or_abort.html). ## Example @@ -70,9 +70,9 @@ features = [] ... ``` -The [`replace_with()`](https://docs.rs/replace_with/0.1.3/replace_with/fn.replace_with.html) & [`replace_with_or_default()`](https://docs.rs/replace_with/0.1.3/replace_with/fn.replace_with_or_default.html) functions are available on stable Rust both, with and without `std`. +The [`replace_with()`](https://docs.rs/replace_with/0.1.4/replace_with/fn.replace_with.html) & [`replace_with_or_default()`](https://docs.rs/replace_with/0.1.4/replace_with/fn.replace_with_or_default.html) functions are available on stable Rust both, with and without `std`. -The [`replace_with_or_abort()`](https://docs.rs/replace_with/0.1.3/replace_with/fn.replace_with_or_abort.html) function however by default makes use of [`std::process::abort()`](https://doc.rust-lang.org/std/process/fn.abort.html) which is not available with `no_std`. +The [`replace_with_or_abort()`](https://docs.rs/replace_with/0.1.4/replace_with/fn.replace_with_or_abort.html) function however by default makes use of [`std::process::abort()`](https://doc.rust-lang.org/std/process/fn.abort.html) which is not available with `no_std`. As such `replace_with` will by default call [`core::intrinsics::abort()`](https://doc.rust-lang.org/core/intrinsics/fn.abort.html) instead, which in turn requires nightly Rust. @@ -102,7 +102,7 @@ features = ["panic_abort"] ... ``` -… the `"panic_abort"` feature enables the [`replace_with_or_abort_unchecked()`](https://docs.rs/replace_with/0.1.3/replace_with/fn.replace_with_or_abort_unchecked.html) function becomes on stable Rust as an `unsafe` function, a simple wrapper around `ptr::write(dest, f(ptr::read(dest)));`. +… the `"panic_abort"` feature enables the [`replace_with_or_abort_unchecked()`](https://docs.rs/replace_with/0.1.4/replace_with/fn.replace_with_or_abort_unchecked.html) function becomes on stable Rust as an `unsafe` function, a simple wrapper around `ptr::write(dest, f(ptr::read(dest)));`. **Word of caution:** It is crucial to only ever use this function having defined `panic = "abort"`, or else bad things may happen. It's *up to you* to uphold this invariant! diff --git a/src/lib.rs b/src/lib.rs index 51c032d..7b2e793 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,7 +69,7 @@ all(not(feature = "std"), feature = "nightly"), feature(core_intrinsics) )] -#![doc(html_root_url = "https://docs.rs/replace_with/0.1.3")] +#![doc(html_root_url = "https://docs.rs/replace_with/0.1.4")] #![warn( missing_copy_implementations, missing_debug_implementations,