summaryrefslogtreecommitdiffstats
path: root/third_party/rust/nodrop
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/nodrop')
-rw-r--r--third_party/rust/nodrop/.cargo-checksum.json1
-rw-r--r--third_party/rust/nodrop/Cargo.toml33
-rw-r--r--third_party/rust/nodrop/README.rst58
-rw-r--r--third_party/rust/nodrop/src/lib.rs186
4 files changed, 278 insertions, 0 deletions
diff --git a/third_party/rust/nodrop/.cargo-checksum.json b/third_party/rust/nodrop/.cargo-checksum.json
new file mode 100644
index 0000000000..ccf2b11d44
--- /dev/null
+++ b/third_party/rust/nodrop/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"518e2e6cea4cec4804a6fc04c8138a2db95783cbc13e0b49526553232f7b9699","README.rst":"68844a4fd6edead8ecd0c0053a8618f89fc5bbe8bc1ee000808358f6f0f4d8ff","src/lib.rs":"96d5ddaf03ccbdff8ddcd79b5fdc015aad4451a8d76d0b9a94dff14f49e2dcc9"},"package":"9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"} \ No newline at end of file
diff --git a/third_party/rust/nodrop/Cargo.toml b/third_party/rust/nodrop/Cargo.toml
new file mode 100644
index 0000000000..d1a5f4a861
--- /dev/null
+++ b/third_party/rust/nodrop/Cargo.toml
@@ -0,0 +1,33 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g. crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "nodrop"
+version = "0.1.12"
+authors = ["bluss"]
+description = "A wrapper type to inhibit drop (destructor). Use std::mem::ManuallyDrop instead!"
+documentation = "https://docs.rs/nodrop/"
+keywords = ["container", "drop", "no_std"]
+categories = ["rust-patterns"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/bluss/arrayvec"
+[package.metadata.release]
+no-dev-version = true
+[dependencies.nodrop-union]
+version = "0.1.8"
+optional = true
+
+[features]
+std = []
+use_union = ["nodrop-union"]
+use_needs_drop = []
+default = ["std"]
diff --git a/third_party/rust/nodrop/README.rst b/third_party/rust/nodrop/README.rst
new file mode 100644
index 0000000000..401a4a6a15
--- /dev/null
+++ b/third_party/rust/nodrop/README.rst
@@ -0,0 +1,58 @@
+
+nodrop
+======
+
+Recent Changes (nodrop)
+-----------------------
+
+- 0.1.12
+
+ - Remove dependency on crate odds.
+
+- 0.1.11
+
+ - Remove erronous assertion in test (#77)
+
+- 0.1.10
+
+ - Update for stable ``needs_drop`` (Rust 1.21, was nightly only)
+
+- 0.1.9
+
+ - Fix issue in recent nightly where ``repr(u8)`` did not work. Use
+ a better way to get rid of the enum layout optimization.
+
+- 0.1.8
+
+ - Add crate feature ``use_union`` that uses untagged unions to implement NoDrop.
+ Finally we have an implementation without hacks, without a runtime flag,
+ and without an actual ``Drop`` impl (which was needed to suppress drop).
+ The crate feature requires nightly and is unstable.
+
+- 0.1.7
+
+ - Remove crate feature ``no_drop_flag``, because it doesn't compile on nightly
+ anymore. Drop flags are gone anyway!
+
+- 0.1.6
+
+ - Add feature std, which you can opt out of to use ``no_std``.
+
+- 0.1.5
+
+ - Added crate feature ``use_needs_drop`` which is a nightly-only
+ optimization, which skips overwriting if the inner value does not need
+ drop.
+
+License
+=======
+
+Dual-licensed to be compatible with the Rust project.
+
+Licensed under the Apache License, Version 2.0
+http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
+http://opensource.org/licenses/MIT, at your
+option. This file may not be copied, modified, or distributed
+except according to those terms.
+
+
diff --git a/third_party/rust/nodrop/src/lib.rs b/third_party/rust/nodrop/src/lib.rs
new file mode 100644
index 0000000000..433905e3fa
--- /dev/null
+++ b/third_party/rust/nodrop/src/lib.rs
@@ -0,0 +1,186 @@
+//!
+//! The **nodrop** crate has the following cargo feature flags:
+//!
+//! - `std`
+//! - Optional, enabled by default
+//! - Use libstd
+//! - `use_needs_drop`
+//! - Optional
+//! - Requires Rust 1.21
+//! - Use `needs_drop` to skip overwriting if not necessary
+//! - `use_union`
+//! - Optional
+//! - Requires nightly channel
+//! - Using untagged union, finally we have an implementation of `NoDrop` without hacks,
+//! for example the fact that `NoDrop<T>` never has a destructor anymore.
+//!
+
+#![cfg_attr(not(any(test, feature="std")), no_std)]
+#[cfg(not(any(test, feature="std")))]
+extern crate core as std;
+
+#[cfg(feature = "use_union")]
+extern crate nodrop_union as imp;
+
+pub use imp::NoDrop;
+
+
+#[cfg(not(feature = "use_union"))]
+mod imp {
+ use std::ptr;
+ use std::mem;
+ use std::ops::{Deref, DerefMut};
+
+ /// repr(u8) - Make sure the non-nullable pointer optimization does not occur!
+ #[repr(u8)]
+ enum Flag<T> {
+ Alive(T),
+ // Dummy u8 field below, again to beat the enum layout opt
+ Dropped(u8),
+ }
+
+
+ /// A type holding **T** that will not call its destructor on drop
+ pub struct NoDrop<T>(Flag<T>);
+
+ impl<T> NoDrop<T> {
+ /// Create a new **NoDrop**.
+ #[inline]
+ pub fn new(value: T) -> NoDrop<T> {
+ NoDrop(Flag::Alive(value))
+ }
+
+ /// Extract the inner value.
+ ///
+ /// Once extracted, the value can of course drop again.
+ #[inline]
+ pub fn into_inner(mut self) -> T {
+ let inner = unsafe {
+ ptr::read(&mut *self)
+ };
+ // skip Drop, so we don't even have to overwrite
+ mem::forget(self);
+ inner
+ }
+ }
+
+ #[cfg(not(feature = "use_needs_drop"))]
+ #[inline]
+ fn needs_drop<T>() -> bool {
+ true
+ }
+
+ #[cfg(feature = "use_needs_drop")]
+ #[inline]
+ fn needs_drop<T>() -> bool {
+ unsafe {
+ ::std::mem::needs_drop::<T>()
+ }
+ }
+
+ impl<T> Drop for NoDrop<T> {
+ fn drop(&mut self) {
+ if needs_drop::<T>() {
+ // inhibit drop
+ unsafe {
+ ptr::write(&mut self.0, Flag::Dropped(0));
+ }
+ }
+ }
+ }
+
+ impl<T> Deref for NoDrop<T> {
+ type Target = T;
+
+ // Use type invariant, always Flag::Alive.
+ #[inline]
+ fn deref(&self) -> &T {
+ match self.0 {
+ Flag::Alive(ref inner) => inner,
+ _ => unsafe { debug_assert_unreachable() }
+ }
+ }
+ }
+
+ impl<T> DerefMut for NoDrop<T> {
+ // Use type invariant, always Flag::Alive.
+ #[inline]
+ fn deref_mut(&mut self) -> &mut T {
+ match self.0 {
+ Flag::Alive(ref mut inner) => inner,
+ _ => unsafe { debug_assert_unreachable() }
+ }
+ }
+ }
+
+ #[cfg(test)]
+ #[test]
+ fn test_no_nonnullable_opt() {
+ // Make sure `Flag` does not apply the non-nullable pointer optimization
+ // as Option would do.
+ assert!(mem::size_of::<Flag<&i32>>() > mem::size_of::<&i32>());
+ assert!(mem::size_of::<Flag<Vec<i32>>>() > mem::size_of::<Vec<i32>>());
+ }
+
+ // copying this code saves us microcrate deps
+ #[inline]
+ unsafe fn debug_assert_unreachable() -> ! {
+ debug_assert!(false, "Reached unreachable section: this is a bug!");
+ enum Void { }
+ match *(1 as *const Void) { }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::NoDrop;
+
+ #[test]
+ fn test_drop() {
+ use std::cell::Cell;
+
+ let flag = &Cell::new(0);
+
+ struct Bump<'a>(&'a Cell<i32>);
+
+ impl<'a> Drop for Bump<'a> {
+ fn drop(&mut self) {
+ let n = self.0.get();
+ self.0.set(n + 1);
+ }
+ }
+
+ {
+ let _ = NoDrop::new([Bump(flag), Bump(flag)]);
+ }
+ assert_eq!(flag.get(), 0);
+
+ // test something with the nullable pointer optimization
+ flag.set(0);
+
+ {
+ let mut array = NoDrop::new(Vec::new());
+ array.push(vec![Bump(flag)]);
+ array.push(vec![Bump(flag), Bump(flag)]);
+ array.push(vec![]);
+ array.push(vec![Bump(flag)]);
+ drop(array.pop());
+ assert_eq!(flag.get(), 1);
+ drop(array.pop());
+ assert_eq!(flag.get(), 1);
+ drop(array.pop());
+ assert_eq!(flag.get(), 3);
+ }
+
+ // last one didn't drop.
+ assert_eq!(flag.get(), 3);
+
+ flag.set(0);
+ {
+ let array = NoDrop::new(Bump(flag));
+ array.into_inner();
+ assert_eq!(flag.get(), 1);
+ }
+ assert_eq!(flag.get(), 1);
+ }
+}