MAINT: Delete historical nodrop, nodrop-union directories
These crates are deprecated (use ManuallyDrop and/or MaybeUninit instead).
This commit is contained in:
@@ -2,7 +2,6 @@
|
|||||||
arrayvec
|
arrayvec
|
||||||
========
|
========
|
||||||
[](https://crates.io/crates/arrayvec)
|
[](https://crates.io/crates/arrayvec)
|
||||||
[](https://crates.io/crates/nodrop)
|
|
||||||
[](https://docs.rs/arrayvec)
|
[](https://docs.rs/arrayvec)
|
||||||
[](https://github.com/bluss/arrayvec/actions)
|
[](https://github.com/bluss/arrayvec/actions)
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "nodrop-union"
|
|
||||||
version = "0.1.11"
|
|
||||||
authors = ["bluss"]
|
|
||||||
|
|
||||||
license = "MIT/Apache-2.0"
|
|
||||||
|
|
||||||
description = """
|
|
||||||
A wrapper type to inhibit drop (destructor). Implementation crate for nodrop, the untagged unions implementation (which is unstable / requires nightly) as of this writing.
|
|
||||||
|
|
||||||
***Deprecated: Use ManuallyDrop or MaybeUninit instead!***
|
|
||||||
"""
|
|
||||||
repository = "https://github.com/bluss/arrayvec"
|
|
||||||
|
|
||||||
keywords = []
|
|
||||||
|
|
||||||
[package.metadata.release]
|
|
||||||
no-dev-version = true
|
|
||||||
tag-name = "nodrop-union-{{version}}"
|
|
||||||
|
|
||||||
[badges.maintenance]
|
|
||||||
status = "deprecated"
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../LICENSE-APACHE
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../LICENSE-MIT
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
|
|
||||||
Recent Changes (nodrop-union)
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
- 0.1.11
|
|
||||||
|
|
||||||
- Mark nodrop deprecated
|
|
||||||
|
|
||||||
With the release of arrayvec 0.5, nodrop is unused.
|
|
||||||
|
|
||||||
With the release of Rust 1.36 and MaybeUninit, nodrop-union has no
|
|
||||||
purpose at all (it was only for nightly releases).
|
|
||||||
|
|
||||||
- 0.1.10
|
|
||||||
|
|
||||||
- Update to include license files in the crate by @ignatenkobrain
|
|
||||||
|
|
||||||
- 0.1.9
|
|
||||||
|
|
||||||
- Add ``Copy, Clone`` implementations
|
|
||||||
|
|
||||||
- 0.1.8
|
|
||||||
|
|
||||||
- Initial release
|
|
||||||
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
//! A wrapper type to inhibit drop (destructor).
|
|
||||||
//!
|
|
||||||
//! ***Deprecated: Use ManuallyDrop or MaybeUninit instead!***
|
|
||||||
//!
|
|
||||||
//! **nodrop-union** is the untagged unions (requires Rust nightly channel and
|
|
||||||
//! unstable as of this writing) implementation for the **nodrop** crate.
|
|
||||||
//!
|
|
||||||
//! It is intended you use this through the **nodrop** crate with the `use_union`
|
|
||||||
//! crate feature enabled.
|
|
||||||
//!
|
|
||||||
//! This is the future implementation of nodrop, once it is stable.
|
|
||||||
//!
|
|
||||||
//! This implementation is a lot better:
|
|
||||||
//!
|
|
||||||
//! - Does not have a destructor at all
|
|
||||||
//! - Can be Copy if T is Copy
|
|
||||||
//! - No space overhead / no runtime flag
|
|
||||||
//!
|
|
||||||
//! This means that this implementation has extensions that the
|
|
||||||
//! stable nodrop does not yet have, which is something to be aware of if
|
|
||||||
//! you are switching.
|
|
||||||
//!
|
|
||||||
|
|
||||||
#![feature(untagged_unions)]
|
|
||||||
|
|
||||||
#![cfg_attr(not(test), no_std)]
|
|
||||||
#[cfg(not(test))]
|
|
||||||
extern crate core as std;
|
|
||||||
|
|
||||||
use std::ops::{Deref, DerefMut};
|
|
||||||
|
|
||||||
#[allow(unions_with_drop_fields)]
|
|
||||||
#[derive(Copy)]
|
|
||||||
union UnionFlag<T> {
|
|
||||||
value: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Clone> Clone for UnionFlag<T> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
unsafe {
|
|
||||||
UnionFlag { value: self.value.clone() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A type holding **T** that will not call its destructor on drop
|
|
||||||
///
|
|
||||||
/// The untagged unions implementation of `NoDrop<T>` is Copy where T: Copy,
|
|
||||||
/// which was not possible in the stable implementation.
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct NoDrop<T>(UnionFlag<T>);
|
|
||||||
|
|
||||||
impl<T> NoDrop<T> {
|
|
||||||
/// Create a new **NoDrop**.
|
|
||||||
#[inline]
|
|
||||||
pub fn new(value: T) -> Self {
|
|
||||||
NoDrop(UnionFlag { value: value })
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extract the inner value.
|
|
||||||
///
|
|
||||||
/// Once extracted, the value can of course drop again.
|
|
||||||
#[inline]
|
|
||||||
pub fn into_inner(self) -> T {
|
|
||||||
unsafe {
|
|
||||||
self.0.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Deref for NoDrop<T> {
|
|
||||||
type Target = T;
|
|
||||||
|
|
||||||
// Use type invariant, always initialized
|
|
||||||
#[inline]
|
|
||||||
fn deref(&self) -> &T {
|
|
||||||
unsafe {
|
|
||||||
&self.0.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> DerefMut for NoDrop<T> {
|
|
||||||
// Use type invariant, always initialized
|
|
||||||
#[inline]
|
|
||||||
fn deref_mut(&mut self) -> &mut T {
|
|
||||||
unsafe {
|
|
||||||
&mut self.0.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::NoDrop;
|
|
||||||
use std::mem;
|
|
||||||
|
|
||||||
#[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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_size_of() {
|
|
||||||
assert!(mem::size_of::<NoDrop<&i32>>() == mem::size_of::<&i32>());
|
|
||||||
assert!(mem::size_of::<NoDrop<Vec<i32>>>() == mem::size_of::<Vec<i32>>());
|
|
||||||
// No non-nullable pointer optimization!
|
|
||||||
assert!(mem::size_of::<Option<NoDrop<&i32>>>() > mem::size_of::<NoDrop<&i32>>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "nodrop"
|
|
||||||
version = "0.1.14"
|
|
||||||
authors = ["bluss"]
|
|
||||||
|
|
||||||
license = "MIT/Apache-2.0"
|
|
||||||
|
|
||||||
description = """
|
|
||||||
A wrapper type to inhibit drop (destructor).
|
|
||||||
|
|
||||||
***Deprecated: Use ManuallyDrop or MaybeUninit instead!***
|
|
||||||
"""
|
|
||||||
documentation = "https://docs.rs/nodrop/"
|
|
||||||
repository = "https://github.com/bluss/arrayvec"
|
|
||||||
|
|
||||||
keywords = []
|
|
||||||
categories = ["rust-patterns"]
|
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["std"]
|
|
||||||
|
|
||||||
# Default, requires Rust 1.6+ to disable
|
|
||||||
# Use libstd
|
|
||||||
std = []
|
|
||||||
|
|
||||||
# Optional, Rust 1.21.0
|
|
||||||
# Use `needs_drop` to skip overwriting if not necessary
|
|
||||||
use_needs_drop = []
|
|
||||||
|
|
||||||
# Optional, nightly channel
|
|
||||||
use_union = ["nodrop-union"]
|
|
||||||
|
|
||||||
[dependencies.nodrop-union]
|
|
||||||
path = "../nodrop-union"
|
|
||||||
version = "0.1.8"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[package.metadata.release]
|
|
||||||
no-dev-version = true
|
|
||||||
tag-name = "nodrop-{{version}}"
|
|
||||||
|
|
||||||
|
|
||||||
[badges.maintenance]
|
|
||||||
status = "deprecated"
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../LICENSE-APACHE
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../LICENSE-MIT
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
|
|
||||||
nodrop
|
|
||||||
======
|
|
||||||
|
|
||||||
Recent Changes (nodrop)
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
- 0.1.14
|
|
||||||
|
|
||||||
- Mark nodrop deprecated
|
|
||||||
|
|
||||||
With the release of arrayvec 0.5, nodrop is unused.
|
|
||||||
|
|
||||||
With the release of Rust 1.36 and MaybeUninit, nodrop has no
|
|
||||||
purpose (but for older Rust releases).
|
|
||||||
|
|
||||||
- 0.1.13
|
|
||||||
|
|
||||||
- Update to include license files in the crate by @ignatenkobrain
|
|
||||||
|
|
||||||
- 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.
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,189 +0,0 @@
|
|||||||
//! A wrapper type to inhibit drop (destructor).
|
|
||||||
//!
|
|
||||||
//! ***Deprecated: Use ManuallyDrop or MaybeUninit instead!***
|
|
||||||
//!
|
|
||||||
//! 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user