Skip to content

Commit

Permalink
util: make NonCopyable 0 size (instead of 1 byte)
Browse files Browse the repository at this point in the history
this also adds a derived Eq, TotalEq, Ord and TotalOrd along with
removing the useless constructor
  • Loading branch information
thestinger committed Jun 28, 2013
1 parent 927f454 commit 779ee2a
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/libstd/option.rs
Expand Up @@ -447,7 +447,7 @@ fn test_option_dance() {
}
#[test] #[should_fail] #[ignore(cfg(windows))]
fn test_option_too_much_dance() {
let mut y = Some(util::NonCopyable::new());
let mut y = Some(util::NonCopyable);
let _y2 = y.swap_unwrap();
let _y3 = y.swap_unwrap();
}
Expand Down
51 changes: 39 additions & 12 deletions src/libstd/util.rs
Expand Up @@ -75,18 +75,14 @@ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
}

/// A non-copyable dummy type.
#[deriving(Eq, TotalEq, Ord, TotalOrd)]
#[no_drop_flag]
pub struct NonCopyable;

impl NonCopyable {
/// Creates a dummy non-copyable structure and returns it for use.
pub fn new() -> NonCopyable { NonCopyable }
}

impl Drop for NonCopyable {
fn drop(&self) { }
}


/// A type with no inhabitants
pub enum Void { }

Expand Down Expand Up @@ -130,39 +126,70 @@ pub fn unreachable() -> ! {

#[cfg(test)]
mod tests {
use super::*;
use option::{None, Some};
use util::{Void, NonCopyable, id, replace, swap};
use either::{Either, Left, Right};
use sys::size_of;
use kinds::Drop;

#[test]
pub fn identity_crisis() {
fn identity_crisis() {
// Writing a test for the identity function. How did it come to this?
let x = ~[(5, false)];
//FIXME #3387 assert!(x.eq(id(copy x)));
let y = copy x;
assert!(x.eq(&id(y)));
}

#[test]
pub fn test_swap() {
fn test_swap() {
let mut x = 31337;
let mut y = 42;
swap(&mut x, &mut y);
assert_eq!(x, 42);
assert_eq!(y, 31337);
}

#[test]
pub fn test_replace() {
let mut x = Some(NonCopyable::new());
fn test_replace() {
let mut x = Some(NonCopyable);
let y = replace(&mut x, None);
assert!(x.is_none());
assert!(y.is_some());
}

#[test]
pub fn test_uninhabited() {
fn test_uninhabited() {
let could_only_be_coin : Either <Void, ()> = Right (());
match could_only_be_coin {
Right (coin) => coin,
Left (is_void) => is_void.uninhabited ()
}
}

#[test]
fn test_noncopyable() {
assert_eq!(size_of::<NonCopyable>(), 0);

// verify that `#[no_drop_flag]` works as intended on a zero-size struct

static mut did_run: bool = false;

struct Foo { five: int }

impl Drop for Foo {
fn drop(&self) {
assert_eq!(self.five, 5);
unsafe {
did_run = true;
}
}
}

{
let _a = (NonCopyable, Foo { five: 5 }, NonCopyable);
}

unsafe { assert_eq!(did_run, true); }
}
}

0 comments on commit 779ee2a

Please sign in to comment.