Skip to content

Commit 779ee2a

Browse files
committed
util: make NonCopyable 0 size (instead of 1 byte)
this also adds a derived Eq, TotalEq, Ord and TotalOrd along with removing the useless constructor
1 parent 927f454 commit 779ee2a

File tree

2 files changed

+40
-13
lines changed

2 files changed

+40
-13
lines changed

src/libstd/option.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ fn test_option_dance() {
447447
}
448448
#[test] #[should_fail] #[ignore(cfg(windows))]
449449
fn test_option_too_much_dance() {
450-
let mut y = Some(util::NonCopyable::new());
450+
let mut y = Some(util::NonCopyable);
451451
let _y2 = y.swap_unwrap();
452452
let _y3 = y.swap_unwrap();
453453
}

src/libstd/util.rs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,18 +75,14 @@ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
7575
}
7676

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

80-
impl NonCopyable {
81-
/// Creates a dummy non-copyable structure and returns it for use.
82-
pub fn new() -> NonCopyable { NonCopyable }
83-
}
84-
8582
impl Drop for NonCopyable {
8683
fn drop(&self) { }
8784
}
8885

89-
9086
/// A type with no inhabitants
9187
pub enum Void { }
9288

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

131127
#[cfg(test)]
132128
mod tests {
129+
use super::*;
133130
use option::{None, Some};
134-
use util::{Void, NonCopyable, id, replace, swap};
135131
use either::{Either, Left, Right};
132+
use sys::size_of;
133+
use kinds::Drop;
136134

137135
#[test]
138-
pub fn identity_crisis() {
136+
fn identity_crisis() {
139137
// Writing a test for the identity function. How did it come to this?
140138
let x = ~[(5, false)];
141139
//FIXME #3387 assert!(x.eq(id(copy x)));
142140
let y = copy x;
143141
assert!(x.eq(&id(y)));
144142
}
143+
145144
#[test]
146-
pub fn test_swap() {
145+
fn test_swap() {
147146
let mut x = 31337;
148147
let mut y = 42;
149148
swap(&mut x, &mut y);
150149
assert_eq!(x, 42);
151150
assert_eq!(y, 31337);
152151
}
152+
153153
#[test]
154-
pub fn test_replace() {
155-
let mut x = Some(NonCopyable::new());
154+
fn test_replace() {
155+
let mut x = Some(NonCopyable);
156156
let y = replace(&mut x, None);
157157
assert!(x.is_none());
158158
assert!(y.is_some());
159159
}
160+
160161
#[test]
161-
pub fn test_uninhabited() {
162+
fn test_uninhabited() {
162163
let could_only_be_coin : Either <Void, ()> = Right (());
163164
match could_only_be_coin {
164165
Right (coin) => coin,
165166
Left (is_void) => is_void.uninhabited ()
166167
}
167168
}
169+
170+
#[test]
171+
fn test_noncopyable() {
172+
assert_eq!(size_of::<NonCopyable>(), 0);
173+
174+
// verify that `#[no_drop_flag]` works as intended on a zero-size struct
175+
176+
static mut did_run: bool = false;
177+
178+
struct Foo { five: int }
179+
180+
impl Drop for Foo {
181+
fn drop(&self) {
182+
assert_eq!(self.five, 5);
183+
unsafe {
184+
did_run = true;
185+
}
186+
}
187+
}
188+
189+
{
190+
let _a = (NonCopyable, Foo { five: 5 }, NonCopyable);
191+
}
192+
193+
unsafe { assert_eq!(did_run, true); }
194+
}
168195
}

0 commit comments

Comments
 (0)