]> git.lizzy.rs Git - rust.git/commitdiff
core: Stabilize the mem module
authorAlex Crichton <alex@alexcrichton.com>
Sat, 17 May 2014 07:56:00 +0000 (00:56 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Wed, 21 May 2014 06:06:54 +0000 (23:06 -0700)
Excluding the functions inherited from the cast module last week (with marked
stability levels), these functions received the following treatment.

* size_of - this method has become #[stable]
* nonzero_size_of/nonzero_size_of_val - these methods have been removed
* min_align_of - this method is now #[stable]
* pref_align_of - this method has been renamed without the
  `pref_` prefix, and it is the "default alignment" now. This decision is in line
  with what clang does (see url linked in comment on function). This function
  is now #[stable].
* init - renamed to zeroed and marked #[stable]
* uninit - marked #[stable]
* move_val_init - renamed to overwrite and marked #[stable]
* {from,to}_{be,le}{16,32,64} - all functions marked #[stable]
* swap/replace/drop - marked #[stable]
* size_of_val/min_align_of_val/align_of_val - these functions are marked
  #[unstable], but will continue to exist in some form. Concerns have been
  raised about their `_val` prefix.

[breaking-change]

19 files changed:
src/doc/guide-unsafe.md
src/libarena/lib.rs
src/libcollections/priority_queue.rs
src/libcollections/trie.rs
src/libcore/mem.rs
src/libcore/should_not_exist.rs
src/libcore/slice.rs
src/libnative/io/file_win32.rs
src/libnative/io/net.rs
src/libnative/io/pipe_win32.rs
src/libnative/io/process.rs
src/libnative/io/timer_unix.rs
src/libnative/io/util.rs
src/librustdoc/flock.rs
src/librustuv/net.rs
src/libstd/slice.rs
src/libstd/unstable/mutex.rs
src/libstd/vec.rs
src/test/run-pass/type-use-i1-versus-i8.rs

index d78e2103daca1584d227aef27cdb4d8da57169cf..3ff05ef3fd0644796b39006e313495cbffaa6df9 100644 (file)
@@ -216,9 +216,9 @@ impl<T: Send> Unique<T> {
             // we *need* valid pointer.
             assert!(!ptr.is_null());
             // `*ptr` is uninitialized, and `*ptr = value` would attempt to destroy it
-            // move_val_init moves a value into this memory without
+            // `overwrite` moves a value into this memory without
             // attempting to drop the original value.
-            mem::move_val_init(&mut *ptr, value);
+            mem::overwrite(&mut *ptr, value);
             Unique{ptr: ptr}
         }
     }
index f49bffe06d3930cc07f1aec9c87732b91f00771b..3c93cdac8bbc97109f36282fa501f51b185ffce3 100644 (file)
@@ -35,7 +35,6 @@
 use std::intrinsics::{TyDesc, get_tydesc};
 use std::intrinsics;
 use std::mem;
-use std::mem::min_align_of;
 use std::num;
 use std::ptr::read;
 use std::rc::Rc;
@@ -155,7 +154,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
         }
 
         // Find where the next tydesc lives
-        idx = round_up(start + size, mem::pref_align_of::<*TyDesc>());
+        idx = round_up(start + size, mem::align_of::<*TyDesc>());
     }
 }
 
@@ -207,9 +206,10 @@ fn alloc_copy_inner(&mut self, n_bytes: uint, align: uint) -> *u8 {
     #[inline]
     fn alloc_copy<'a, T>(&'a mut self, op: || -> T) -> &'a T {
         unsafe {
-            let ptr = self.alloc_copy_inner(mem::size_of::<T>(), min_align_of::<T>());
+            let ptr = self.alloc_copy_inner(mem::size_of::<T>(),
+                                            mem::min_align_of::<T>());
             let ptr = ptr as *mut T;
-            mem::move_val_init(&mut (*ptr), op());
+            mem::overwrite(&mut (*ptr), op());
             return &*ptr;
         }
     }
@@ -239,7 +239,7 @@ fn alloc_noncopy_inner(&mut self, n_bytes: uint, align: uint)
                 return self.alloc_noncopy_grow(n_bytes, align);
             }
 
-            self.head.fill.set(round_up(end, mem::pref_align_of::<*TyDesc>()));
+            self.head.fill.set(round_up(end, mem::align_of::<*TyDesc>()));
 
             //debug!("idx = {}, size = {}, align = {}, fill = {}",
             //       start, n_bytes, align, head.fill);
@@ -254,14 +254,15 @@ fn alloc_noncopy<'a, T>(&'a mut self, op: || -> T) -> &'a T {
         unsafe {
             let tydesc = get_tydesc::<T>();
             let (ty_ptr, ptr) =
-                self.alloc_noncopy_inner(mem::size_of::<T>(), min_align_of::<T>());
+                self.alloc_noncopy_inner(mem::size_of::<T>(),
+                                         mem::min_align_of::<T>());
             let ty_ptr = ty_ptr as *mut uint;
             let ptr = ptr as *mut T;
             // Write in our tydesc along with a bit indicating that it
             // has *not* been initialized yet.
             *ty_ptr = mem::transmute(tydesc);
             // Actually initialize it
-            mem::move_val_init(&mut(*ptr), op());
+            mem::overwrite(&mut(*ptr), op());
             // Now that we are done, update the tydesc to indicate that
             // the object is there.
             *ty_ptr = bitpack_tydesc_ptr(tydesc, true);
@@ -357,9 +358,10 @@ fn new(next: Option<Box<TypedArenaChunk<T>>>, capacity: uint)
         size = size.checked_add(&elems_size).unwrap();
 
         let mut chunk = unsafe {
-            let chunk = exchange_malloc(size, min_align_of::<TypedArenaChunk<T>>());
+            let chunk = exchange_malloc(size,
+                                        mem::min_align_of::<TypedArenaChunk<T>>());
             let mut chunk: Box<TypedArenaChunk<T>> = mem::transmute(chunk);
-            mem::move_val_init(&mut chunk.next, next);
+            mem::overwrite(&mut chunk.next, next);
             chunk
         };
 
@@ -396,7 +398,8 @@ unsafe fn destroy(&mut self, len: uint) {
     fn start(&self) -> *u8 {
         let this: *TypedArenaChunk<T> = self;
         unsafe {
-            mem::transmute(round_up(this.offset(1) as uint, min_align_of::<T>()))
+            mem::transmute(round_up(this.offset(1) as uint,
+                                    mem::min_align_of::<T>()))
         }
     }
 
@@ -440,7 +443,7 @@ pub fn alloc<'a>(&'a self, object: T) -> &'a T {
             }
 
             let ptr: &'a mut T = mem::transmute(this.ptr);
-            mem::move_val_init(ptr, object);
+            mem::overwrite(ptr, object);
             this.ptr = this.ptr.offset(1);
             let ptr: &'a T = ptr;
             ptr
index 2e8178cd931e555f9895f0baba3ea6aa468715d1..4a0daf529de88bd18b71ef16bc8d5157118cbe0a 100644 (file)
@@ -13,7 +13,7 @@
 #![allow(missing_doc)]
 
 use std::clone::Clone;
-use std::mem::{move_val_init, init, replace, swap};
+use std::mem::{overwrite, zeroed, replace, swap};
 use std::slice;
 
 /// A priority queue implemented with a binary heap
@@ -157,26 +157,26 @@ pub fn from_vec(xs: Vec<T>) -> PriorityQueue<T> {
     // compared to using swaps, which involves twice as many moves.
     fn siftup(&mut self, start: uint, mut pos: uint) {
         unsafe {
-            let new = replace(self.data.get_mut(pos), init());
+            let new = replace(self.data.get_mut(pos), zeroed());
 
             while pos > start {
                 let parent = (pos - 1) >> 1;
                 if new > *self.data.get(parent) {
-                    let x = replace(self.data.get_mut(parent), init());
-                    move_val_init(self.data.get_mut(pos), x);
+                    let x = replace(self.data.get_mut(parent), zeroed());
+                    overwrite(self.data.get_mut(pos), x);
                     pos = parent;
                     continue
                 }
                 break
             }
-            move_val_init(self.data.get_mut(pos), new);
+            overwrite(self.data.get_mut(pos), new);
         }
     }
 
     fn siftdown_range(&mut self, mut pos: uint, end: uint) {
         unsafe {
             let start = pos;
-            let new = replace(self.data.get_mut(pos), init());
+            let new = replace(self.data.get_mut(pos), zeroed());
 
             let mut child = 2 * pos + 1;
             while child < end {
@@ -184,13 +184,13 @@ fn siftdown_range(&mut self, mut pos: uint, end: uint) {
                 if right < end && !(*self.data.get(child) > *self.data.get(right)) {
                     child = right;
                 }
-                let x = replace(self.data.get_mut(child), init());
-                move_val_init(self.data.get_mut(pos), x);
+                let x = replace(self.data.get_mut(child), zeroed());
+                overwrite(self.data.get_mut(pos), x);
                 pos = child;
                 child = 2 * pos + 1;
             }
 
-            move_val_init(self.data.get_mut(pos), new);
+            overwrite(self.data.get_mut(pos), new);
             self.siftup(start, pos);
         }
     }
index f7fed0224a2ec32e989c970dc5295a2386a2bd76..9d64b3c2394b02d7cf47c93deeb47cdfff52809f 100644 (file)
@@ -10,7 +10,7 @@
 
 //! Ordered containers with integer keys, implemented as radix tries (`TrieSet` and `TrieMap` types)
 
-use std::mem::init;
+use std::mem::zeroed;
 use std::mem;
 use std::slice::{Items, MutItems};
 use std::slice;
@@ -522,7 +522,8 @@ unsafe fn new() -> $name<'a, T> {
                     remaining_max: 0,
                     length: 0,
                     // ick :( ... at least the compiler will tell us if we screwed up.
-                    stack: [init(), init(), init(), init(), init(), init(), init(), init()]
+                    stack: [zeroed(), zeroed(), zeroed(), zeroed(), zeroed(),
+                            zeroed(), zeroed(), zeroed()]
                 }
             }
 
@@ -532,8 +533,10 @@ unsafe fn new() -> $name<'a, T> {
                     remaining_min: 0,
                     remaining_max: 0,
                     length: 0,
-                    stack: [init(), init(), init(), init(), init(), init(), init(), init(),
-                            init(), init(), init(), init(), init(), init(), init(), init()]
+                    stack: [zeroed(), zeroed(), zeroed(), zeroed(),
+                            zeroed(), zeroed(), zeroed(), zeroed(),
+                            zeroed(), zeroed(), zeroed(), zeroed(),
+                            zeroed(), zeroed(), zeroed(), zeroed()]
                 }
             }
         }
index c5c6d751777288618469afdbf6fc8bb6568e2fe0..aa7a8f0f8b63af28ae33f0ebaf12cca34eae4306 100644 (file)
 
 /// Returns the size of a type in bytes.
 #[inline]
+#[stable]
 pub fn size_of<T>() -> uint {
     unsafe { intrinsics::size_of::<T>() }
 }
 
 /// Returns the size of the type that `_val` points to in bytes.
 #[inline]
+#[unstable = "the name of this function may change slightly before stabilizing"]
 pub fn size_of_val<T>(_val: &T) -> uint {
     size_of::<T>()
 }
 
-/// Returns the size of a type in bytes, or 1 if the actual size is zero.
-///
-/// Useful for building structures containing variable-length arrays.
+/// Deprecated, this function will be removed soon
 #[inline]
+#[deprecated = "this function will be removed soon"]
 pub fn nonzero_size_of<T>() -> uint {
     match size_of::<T>() {
         0 => 1,
-        x => x
+        n => n,
     }
 }
 
-/// Returns the size in bytes of the type of the value that `_val` points to.
+/// Deprecated, this function will be removed soon
 #[inline]
-pub fn nonzero_size_of_val<T>(_val: &T) -> uint {
-    nonzero_size_of::<T>()
+#[deprecated = "this function will be removed soon"]
+pub fn nonzero_size_of_val<T>(val: &T) -> uint {
+    match size_of_val::<T>(val) {
+        0 => 1,
+        n => n,
+    }
 }
 
 /// Returns the ABI-required minimum alignment of a type
@@ -51,6 +56,7 @@ pub fn nonzero_size_of_val<T>(_val: &T) -> uint {
 /// This is the alignment used for struct fields. It may be smaller
 /// than the preferred alignment.
 #[inline]
+#[stable]
 pub fn min_align_of<T>() -> uint {
     unsafe { intrinsics::min_align_of::<T>() }
 }
@@ -58,44 +64,100 @@ pub fn min_align_of<T>() -> uint {
 /// Returns the ABI-required minimum alignment of the type of the value that
 /// `_val` points to
 #[inline]
+#[unstable = "the name of this function may change slightly before stabilizing"]
 pub fn min_align_of_val<T>(_val: &T) -> uint {
     min_align_of::<T>()
 }
 
-/// Returns the preferred alignment of a type
+/// Returns the alignment in memory for a type.
+///
+/// This function will return the alignment, in bytes, of a type in memory. If
+/// the alignment returned is adhered to, then the type is guaranteed to
+/// function properly.
 #[inline]
-pub fn pref_align_of<T>() -> uint {
+#[stable]
+pub fn align_of<T>() -> uint {
+    // We use the preferred alignment as the default alignment for a type. This
+    // appears to be what clang migrated towards as well:
+    //
+    // http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110725/044411.html
     unsafe { intrinsics::pref_align_of::<T>() }
 }
 
-/// Returns the preferred alignment of the type of the value that
-/// `_val` points to
+/// Returns the alignment of the type of the value that `_val` points to.
+///
+/// This is similar to `align_of`, but function will properly handle types such
+/// as trait objects (in the future), returning the alignment for an arbitrary
+/// value at runtime.
 #[inline]
-pub fn pref_align_of_val<T>(_val: &T) -> uint {
-    pref_align_of::<T>()
+#[unstable = "the name of this function may change slightly before stabilizing"]
+pub fn align_of_val<T>(_val: &T) -> uint {
+    align_of::<T>()
 }
 
+/// Deprecated, this function has been renamed to align_of
+#[inline]
+#[deprecated = "use mem::align_of instead"]
+pub fn pref_align_of<T>() -> uint { align_of::<T>() }
+
+/// Deprecated, this function has been renamed to align_of_val
+#[inline]
+#[deprecated = "use mem::align_of_val instead"]
+pub fn pref_align_of_val<T>(val: &T) -> uint { align_of_val(val) }
+
 /// Create a value initialized to zero.
 ///
-/// `init` is unsafe because it returns a zeroed-out datum,
-/// which is unsafe unless T is Copy.
+/// This function is similar to allocating space for a a local variable and
+/// zeroing it out (an unsafe operation).
+///
+/// Care must be taken when using this function, if the type `T` has a
+/// destructor and the value falls out of scope (due to unwinding or returning)
+/// before being initialized, then the destructor will run on zeroed
+/// data, likely leading to crashes.
+///
+/// This is useful for FFI functions sometimes, but should generally be avoided.
 #[inline]
-pub unsafe fn init<T>() -> T {
+#[unstable = "the name of this function is subject to change"]
+pub unsafe fn zeroed<T>() -> T {
     intrinsics::init()
 }
 
+/// Deprecated, use zeroed() instead
+#[inline]
+#[deprecated = "this function has been renamed to zeroed()"]
+pub unsafe fn init<T>() -> T { zeroed() }
+
 /// Create an uninitialized value.
+///
+/// Care must be taken when using this function, if the type `T` has a
+/// destructor and the value falls out of scope (due to unwinding or returning)
+/// before being initialized, then the destructor will run on uninitialized
+/// data, likely leading to crashes.
+///
+/// This is useful for FFI functions sometimes, but should generally be avoided.
 #[inline]
+#[unstable = "the name of this function is subject to change"]
 pub unsafe fn uninit<T>() -> T {
     intrinsics::uninit()
 }
 
-/// Move a value to an uninitialized memory location.
+/// Unsafely overwrite a memory location with the given value without destroying
+/// the old value.
 ///
-/// Drop glue is not run on the destination.
+/// This operation is unsafe because it does not destroy the previous value
+/// contained at the location `dst`. This could leak allocations or resources,
+/// so care must be taken to previously deallocate the value at `dst`.
+#[inline]
+#[unstable = "the name of this function is subject to change"]
+pub unsafe fn overwrite<T>(dst: *mut T, src: T) {
+    intrinsics::move_val_init(&mut *dst, src)
+}
+
+/// Deprecated, use move_val_init() instead
 #[inline]
+#[deprecated = "this function has been renamed to move_val_init()"]
 pub unsafe fn move_val_init<T>(dst: &mut T, src: T) {
-    intrinsics::move_val_init(dst, src)
+    overwrite(dst, src)
 }
 
 /// Convert an u16 to little endian from the target's endianness.
@@ -106,126 +168,150 @@ pub unsafe fn move_val_init<T>(dst: &mut T, src: T) {
 /// Convert an u16 to little endian from the target's endianness.
 ///
 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "big")]    #[inline] pub fn to_le16(x: u16) -> u16 { unsafe { bswap16(x) } }
+#[cfg(target_endian = "big")] #[inline] #[stable]
+pub fn to_le16(x: u16) -> u16 { unsafe { bswap16(x) } }
 
 /// Convert an u32 to little endian from the target's endianness.
 ///
 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] pub fn to_le32(x: u32) -> u32 { x }
+#[cfg(target_endian = "little")] #[inline] #[stable]
+pub fn to_le32(x: u32) -> u32 { x }
 
 /// Convert an u32 to little endian from the target's endianness.
 ///
 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "big")]    #[inline] pub fn to_le32(x: u32) -> u32 { unsafe { bswap32(x) } }
+#[cfg(target_endian = "big")] #[inline] #[stable]
+pub fn to_le32(x: u32) -> u32 { unsafe { bswap32(x) } }
 
 /// Convert an u64 to little endian from the target's endianness.
 ///
 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] pub fn to_le64(x: u64) -> u64 { x }
+#[cfg(target_endian = "little")] #[inline] #[stable]
+pub fn to_le64(x: u64) -> u64 { x }
 
 /// Convert an u64 to little endian from the target's endianness.
 ///
 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "big")]    #[inline] pub fn to_le64(x: u64) -> u64 { unsafe { bswap64(x) } }
+#[cfg(target_endian = "big")] #[inline] #[stable]
+pub fn to_le64(x: u64) -> u64 { unsafe { bswap64(x) } }
 
 
 /// Convert an u16 to big endian from the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] pub fn to_be16(x: u16) -> u16 { unsafe { bswap16(x) } }
+#[cfg(target_endian = "little")] #[inline] #[stable]
+pub fn to_be16(x: u16) -> u16 { unsafe { bswap16(x) } }
 
 /// Convert an u16 to big endian from the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "big")]    #[inline] pub fn to_be16(x: u16) -> u16 { x }
+#[cfg(target_endian = "big")] #[inline] #[stable]
+pub fn to_be16(x: u16) -> u16 { x }
 
 /// Convert an u32 to big endian from the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] pub fn to_be32(x: u32) -> u32 { unsafe { bswap32(x) } }
+#[cfg(target_endian = "little")] #[inline] #[stable]
+pub fn to_be32(x: u32) -> u32 { unsafe { bswap32(x) } }
 
 /// Convert an u32 to big endian from the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "big")]    #[inline] pub fn to_be32(x: u32) -> u32 { x }
+#[cfg(target_endian = "big")] #[inline] #[stable]
+pub fn to_be32(x: u32) -> u32 { x }
 
 /// Convert an u64 to big endian from the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] pub fn to_be64(x: u64) -> u64 { unsafe { bswap64(x) } }
+#[cfg(target_endian = "little")] #[inline] #[stable]
+pub fn to_be64(x: u64) -> u64 { unsafe { bswap64(x) } }
 
 /// Convert an u64 to big endian from the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "big")]    #[inline] pub fn to_be64(x: u64) -> u64 { x }
+#[cfg(target_endian = "big")] #[inline] #[stable]
+pub fn to_be64(x: u64) -> u64 { x }
 
 
 /// Convert an u16 from little endian to the target's endianness.
 ///
 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] pub fn from_le16(x: u16) -> u16 { x }
+#[cfg(target_endian = "little")] #[inline] #[stable]
+pub fn from_le16(x: u16) -> u16 { x }
 
 /// Convert an u16 from little endian to the target's endianness.
 ///
 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "big")]    #[inline] pub fn from_le16(x: u16) -> u16 { unsafe { bswap16(x) } }
+#[cfg(target_endian = "big")] #[inline] #[stable]
+pub fn from_le16(x: u16) -> u16 { unsafe { bswap16(x) } }
 
 /// Convert an u32 from little endian to the target's endianness.
 ///
 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] pub fn from_le32(x: u32) -> u32 { x }
+#[cfg(target_endian = "little")] #[inline] #[stable]
+pub fn from_le32(x: u32) -> u32 { x }
 
 /// Convert an u32 from little endian to the target's endianness.
 ///
 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "big")]    #[inline] pub fn from_le32(x: u32) -> u32 { unsafe { bswap32(x) } }
+#[cfg(target_endian = "big")] #[inline] #[stable]
+pub fn from_le32(x: u32) -> u32 { unsafe { bswap32(x) } }
 
 /// Convert an u64 from little endian to the target's endianness.
 ///
 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] pub fn from_le64(x: u64) -> u64 { x }
+#[cfg(target_endian = "little")] #[inline] #[stable]
+pub fn from_le64(x: u64) -> u64 { x }
 
 /// Convert an u64 from little endian to the target's endianness.
 ///
 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
-#[cfg(target_endian = "big")]    #[inline] pub fn from_le64(x: u64) -> u64 { unsafe { bswap64(x) } }
+#[cfg(target_endian = "big")] #[inline] #[stable]
+pub fn from_le64(x: u64) -> u64 { unsafe { bswap64(x) } }
 
 
 /// Convert an u16 from big endian to the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] pub fn from_be16(x: u16) -> u16 { unsafe { bswap16(x) } }
+#[cfg(target_endian = "little")] #[inline] #[stable]
+pub fn from_be16(x: u16) -> u16 { unsafe { bswap16(x) } }
 
 /// Convert an u16 from big endian to the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "big")]    #[inline] pub fn from_be16(x: u16) -> u16 { x }
+#[cfg(target_endian = "big")] #[inline] #[stable]
+pub fn from_be16(x: u16) -> u16 { x }
 
 /// Convert an u32 from big endian to the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] pub fn from_be32(x: u32) -> u32 { unsafe { bswap32(x) } }
+#[cfg(target_endian = "little")] #[inline] #[stable]
+pub fn from_be32(x: u32) -> u32 { unsafe { bswap32(x) } }
 
 /// Convert an u32 from big endian to the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "big")]    #[inline] pub fn from_be32(x: u32) -> u32 { x }
+#[cfg(target_endian = "big")] #[inline] #[stable]
+pub fn from_be32(x: u32) -> u32 { x }
 
 /// Convert an u64 from big endian to the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "little")] #[inline] pub fn from_be64(x: u64) -> u64 { unsafe { bswap64(x) } }
+#[cfg(target_endian = "little")] #[inline] #[stable]
+pub fn from_be64(x: u64) -> u64 { unsafe { bswap64(x) } }
 
 /// Convert an u64 from big endian to the target's endianness.
 ///
 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
-#[cfg(target_endian = "big")]    #[inline] pub fn from_be64(x: u64) -> u64 { x }
+#[cfg(target_endian = "big")] #[inline] #[stable]
+pub fn from_be64(x: u64) -> u64 { x }
 
 /**
  * Swap the values at two mutable locations of the same type, without
  * deinitialising or copying either one.
  */
 #[inline]
+#[stable]
 pub fn swap<T>(x: &mut T, y: &mut T) {
     unsafe {
         // Give ourselves some scratch space to work with
@@ -279,6 +365,7 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
  * ```
  */
 #[inline]
+#[stable]
 pub fn replace<T>(dest: &mut T, mut src: T) -> T {
     swap(dest, &mut src);
     src
@@ -304,6 +391,7 @@ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
 /// println!("{}", *borrow);
 /// ```
 #[inline]
+#[stable]
 pub fn drop<T>(_x: T) { }
 
 /// Moves a thing into the void.
@@ -415,27 +503,11 @@ fn size_of_val_basic() {
         assert_eq!(size_of_val(&1u64), 8);
     }
 
-    #[test]
-    fn nonzero_size_of_basic() {
-        type Z = [i8, ..0];
-        assert_eq!(size_of::<Z>(), 0u);
-        assert_eq!(nonzero_size_of::<Z>(), 1u);
-        assert_eq!(nonzero_size_of::<uint>(), size_of::<uint>());
-    }
-
-    #[test]
-    fn nonzero_size_of_val_basic() {
-        let z = [0u8, ..0];
-        assert_eq!(size_of_val(&z), 0u);
-        assert_eq!(nonzero_size_of_val(&z), 1u);
-        assert_eq!(nonzero_size_of_val(&1u), size_of_val(&1u));
-    }
-
     #[test]
     fn align_of_basic() {
-        assert_eq!(pref_align_of::<u8>(), 1u);
-        assert_eq!(pref_align_of::<u16>(), 2u);
-        assert_eq!(pref_align_of::<u32>(), 4u);
+        assert_eq!(align_of::<u8>(), 1u);
+        assert_eq!(align_of::<u16>(), 2u);
+        assert_eq!(align_of::<u32>(), 4u);
     }
 
     #[test]
@@ -443,22 +515,22 @@ fn align_of_basic() {
     #[cfg(target_arch = "arm")]
     #[cfg(target_arch = "mips")]
     fn align_of_32() {
-        assert_eq!(pref_align_of::<uint>(), 4u);
-        assert_eq!(pref_align_of::<*uint>(), 4u);
+        assert_eq!(align_of::<uint>(), 4u);
+        assert_eq!(align_of::<*uint>(), 4u);
     }
 
     #[test]
     #[cfg(target_arch = "x86_64")]
     fn align_of_64() {
-        assert_eq!(pref_align_of::<uint>(), 8u);
-        assert_eq!(pref_align_of::<*uint>(), 8u);
+        assert_eq!(align_of::<uint>(), 8u);
+        assert_eq!(align_of::<*uint>(), 8u);
     }
 
     #[test]
     fn align_of_val_basic() {
-        assert_eq!(pref_align_of_val(&1u8), 1u);
-        assert_eq!(pref_align_of_val(&1u16), 2u);
-        assert_eq!(pref_align_of_val(&1u32), 4u);
+        assert_eq!(align_of_val(&1u8), 1u);
+        assert_eq!(align_of_val(&1u16), 2u);
+        assert_eq!(align_of_val(&1u32), 4u);
     }
 
     #[test]
index b55952e70598a85a069f8ab6c7015802bb4630a7..ccca52c573d215725ef3d56b6ce01a7a08f100c7 100644 (file)
@@ -171,15 +171,17 @@ fn clone(&self) -> ~[A] {
         unsafe {
             let ret = alloc(size) as *mut Vec<A>;
 
-            (*ret).fill = len * mem::nonzero_size_of::<A>();
-            (*ret).alloc = len * mem::nonzero_size_of::<A>();
+            let a_size = mem::size_of::<A>();
+            let a_size = if a_size == 0 {1} else {a_size};
+            (*ret).fill = len * a_size;
+            (*ret).alloc = len * a_size;
 
             let mut i = 0;
             let p = &mut (*ret).data as *mut _ as *mut A;
             try_finally(
                 &mut i, (),
                 |i, ()| while *i < len {
-                    mem::move_val_init(
+                    mem::overwrite(
                         &mut(*p.offset(*i as int)),
                         self.unsafe_ref(*i).clone());
                     *i += 1;
index d08e5492c82ad9e3f5fafac00f9bf171835bd112..755c6738b4a626f7608d2739ec6858646538fb83 100644 (file)
@@ -1122,7 +1122,7 @@ unsafe fn unsafe_set(self, index: uint, val: T) {
 
     #[inline]
     unsafe fn init_elem(self, i: uint, val: T) {
-        mem::move_val_init(&mut (*self.as_mut_ptr().offset(i as int)), val);
+        mem::overwrite(&mut (*self.as_mut_ptr().offset(i as int)), val);
     }
 
     #[inline]
@@ -1306,7 +1306,8 @@ fn next(&mut self) -> Option<$elem> {
             #[inline]
             fn size_hint(&self) -> (uint, Option<uint>) {
                 let diff = (self.end as uint) - (self.ptr as uint);
-                let exact = diff / mem::nonzero_size_of::<T>();
+                let size = mem::size_of::<T>();
+                let exact = diff / (if size == 0 {1} else {size});
                 (exact, Some(exact))
             }
         }
index 3222c912dd0857fe6f3afea505dd7b47c6d7eef8..3bfd70a0a8b0c92a353d6dc3a0d84794b15cb73c 100644 (file)
@@ -118,7 +118,7 @@ fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
 
     fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError> {
         let mut read = 0;
-        let mut overlap: libc::OVERLAPPED = unsafe { mem::init() };
+        let mut overlap: libc::OVERLAPPED = unsafe { mem::zeroed() };
         overlap.Offset = offset as libc::DWORD;
         overlap.OffsetHigh = (offset >> 32) as libc::DWORD;
         let ret = unsafe {
@@ -135,7 +135,7 @@ fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError> {
     fn pwrite(&mut self, buf: &[u8], mut offset: u64) -> Result<(), IoError> {
         let mut cur = buf.as_ptr();
         let mut remaining = buf.len();
-        let mut overlap: libc::OVERLAPPED = unsafe { mem::init() };
+        let mut overlap: libc::OVERLAPPED = unsafe { mem::zeroed() };
         while remaining > 0 {
             overlap.Offset = offset as libc::DWORD;
             overlap.OffsetHigh = (offset >> 32) as libc::DWORD;
index 40b66cc526f2aa8968d3b086418fe3aac370cda7..6ba92009c39d56638d57da414abfb33d3add616f 100644 (file)
@@ -68,7 +68,7 @@ fn ip_to_inaddr(ip: ip::IpAddr) -> InAddr {
 
 fn addr_to_sockaddr(addr: ip::SocketAddr) -> (libc::sockaddr_storage, uint) {
     unsafe {
-        let storage: libc::sockaddr_storage = mem::init();
+        let storage: libc::sockaddr_storage = mem::zeroed();
         let len = match ip_to_inaddr(addr.ip) {
             InAddr(inaddr) => {
                 let storage: *mut libc::sockaddr_in = mem::transmute(&storage);
@@ -120,7 +120,7 @@ fn setsockopt<T>(fd: sock_t, opt: libc::c_int, val: libc::c_int,
 pub fn getsockopt<T: Copy>(fd: sock_t, opt: libc::c_int,
                            val: libc::c_int) -> IoResult<T> {
     unsafe {
-        let mut slot: T = mem::init();
+        let mut slot: T = mem::zeroed();
         let mut len = mem::size_of::<T>() as libc::socklen_t;
         let ret = c::getsockopt(fd, opt, val,
                                 &mut slot as *mut _ as *mut _,
@@ -152,7 +152,7 @@ fn sockname(fd: sock_t,
                                          *mut libc::socklen_t) -> libc::c_int)
     -> IoResult<ip::SocketAddr>
 {
-    let mut storage: libc::sockaddr_storage = unsafe { mem::init() };
+    let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
     let mut len = mem::size_of::<libc::sockaddr_storage>() as libc::socklen_t;
     unsafe {
         let storage = &mut storage as *mut libc::sockaddr_storage;
@@ -221,7 +221,7 @@ pub fn init() {
 
         let _guard = LOCK.lock();
         if !INITIALIZED {
-            let mut data: c::WSADATA = mem::init();
+            let mut data: c::WSADATA = mem::zeroed();
             let ret = c::WSAStartup(0x202,      // version 2.2
                                     &mut data);
             assert_eq!(ret, 0);
@@ -497,7 +497,7 @@ pub fn native_accept(&mut self) -> IoResult<TcpStream> {
             try!(util::await(self.fd(), Some(self.deadline), util::Readable));
         }
         unsafe {
-            let mut storage: libc::sockaddr_storage = mem::init();
+            let mut storage: libc::sockaddr_storage = mem::zeroed();
             let storagep = &mut storage as *mut libc::sockaddr_storage;
             let size = mem::size_of::<libc::sockaddr_storage>();
             let mut size = size as libc::socklen_t;
@@ -622,7 +622,7 @@ fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
 impl rtio::RtioUdpSocket for UdpSocket {
     fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, ip::SocketAddr)> {
         let fd = self.fd();
-        let mut storage: libc::sockaddr_storage = unsafe { mem::init() };
+        let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
         let storagep = &mut storage as *mut _ as *mut libc::sockaddr;
         let mut addrlen: libc::socklen_t =
                 mem::size_of::<libc::sockaddr_storage>() as libc::socklen_t;
index af80c7174f21cba3c3c413ee2ca41dc1e85c9b47..5acb48a5f391e82c639138a3d69c15b77004c9c2 100644 (file)
@@ -86,8 +86,8 @@
 
 use libc;
 use std::c_str::CString;
-use std::intrinsics;
 use std::io;
+use std::mem;
 use std::os::win32::as_utf16_p;
 use std::os;
 use std::ptr;
@@ -345,7 +345,7 @@ fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         }
 
         let mut bytes_read = 0;
-        let mut overlapped: libc::OVERLAPPED = unsafe { intrinsics::init() };
+        let mut overlapped: libc::OVERLAPPED = unsafe { mem::zeroed() };
         overlapped.hEvent = self.read.get_ref().handle();
 
         // Pre-flight check to see if the reading half has been closed. This
@@ -417,7 +417,7 @@ fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         }
 
         let mut offset = 0;
-        let mut overlapped: libc::OVERLAPPED = unsafe { intrinsics::init() };
+        let mut overlapped: libc::OVERLAPPED = unsafe { mem::zeroed() };
         overlapped.hEvent = self.write.get_ref().handle();
 
         while offset < buf.len() {
@@ -633,7 +633,7 @@ pub fn native_accept(&mut self) -> IoResult<UnixStream> {
         // someone on the other end connects. This function can "fail" if a
         // client connects after we created the pipe but before we got down
         // here. Thanks windows.
-        let mut overlapped: libc::OVERLAPPED = unsafe { intrinsics::init() };
+        let mut overlapped: libc::OVERLAPPED = unsafe { mem::zeroed() };
         overlapped.hEvent = self.event.handle();
         if unsafe { libc::ConnectNamedPipe(handle, &mut overlapped) == 0 } {
             let mut err = unsafe { libc::GetLastError() };
index 0eebd3380e626c21953780729dd82e9e11ed3aa1..04911bc5f1bd670648c9c4a3e47cdd6af2e078a4 100644 (file)
@@ -896,8 +896,8 @@ fn waitpid(pid: pid_t, deadline: u64) -> IoResult<p::ProcessExit> {
     // self-pipe plus the old handler registered (return value of sigaction).
     fn register_sigchld() -> (libc::c_int, c::sigaction) {
         unsafe {
-            let mut old: c::sigaction = mem::init();
-            let mut new: c::sigaction = mem::init();
+            let mut old: c::sigaction = mem::zeroed();
+            let mut new: c::sigaction = mem::zeroed();
             new.sa_handler = sigchld_handler;
             new.sa_flags = c::SA_NOCLDSTOP;
             assert_eq!(c::sigaction(c::SIGCHLD, &new, &mut old), 0);
@@ -916,7 +916,7 @@ fn waitpid_helper(input: libc::c_int,
                       messages: Receiver<Req>,
                       (read_fd, old): (libc::c_int, c::sigaction)) {
         util::set_nonblocking(input, true).unwrap();
-        let mut set: c::fd_set = unsafe { mem::init() };
+        let mut set: c::fd_set = unsafe { mem::zeroed() };
         let mut tv: libc::timeval;
         let mut active = Vec::<(libc::pid_t, Sender<p::ProcessExit>, u64)>::new();
         let max = cmp::max(input, read_fd) + 1;
index 2c5b798482777657c11770ffb002ea608d2f6210..ed218022b2edecfa2aaa467c7a2a3d43bd69f229 100644 (file)
@@ -87,17 +87,17 @@ pub enum Req {
 // returns the current time (in milliseconds)
 pub fn now() -> u64 {
     unsafe {
-        let mut now: libc::timeval = mem::init();
+        let mut now: libc::timeval = mem::zeroed();
         assert_eq!(c::gettimeofday(&mut now, ptr::null()), 0);
         return (now.tv_sec as u64) * 1000 + (now.tv_usec as u64) / 1000;
     }
 }
 
 fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) {
-    let mut set: c::fd_set = unsafe { mem::init() };
+    let mut set: c::fd_set = unsafe { mem::zeroed() };
 
     let mut fd = FileDesc::new(input, true);
-    let mut timeout: libc::timeval = unsafe { mem::init() };
+    let mut timeout: libc::timeval = unsafe { mem::zeroed() };
 
     // active timers are those which are able to be selected upon (and it's a
     // sorted list, and dead timers are those which have expired, but ownership
index 0d032f9f4bcda7dd09abf9ec1712f79ad0e2371c..fe7a58a5e6868f705f38dc485239f89839584669 100644 (file)
@@ -89,7 +89,7 @@ pub fn connect_timeout(fd: net::sock_t,
         // to use select() with a timeout.
         -1 if os::errno() as int == INPROGRESS as int ||
               os::errno() as int == WOULDBLOCK as int => {
-            let mut set: c::fd_set = unsafe { mem::init() };
+            let mut set: c::fd_set = unsafe { mem::zeroed() };
             c::fd_set(&mut set, fd);
             match await(fd, &mut set, timeout_ms) {
                 0 => Err(timeout("connection timed out")),
@@ -137,13 +137,13 @@ fn await(_fd: net::sock_t, set: &mut c::fd_set,
 
 pub fn await(fd: net::sock_t, deadline: Option<u64>,
              status: SocketStatus) -> IoResult<()> {
-    let mut set: c::fd_set = unsafe { mem::init() };
+    let mut set: c::fd_set = unsafe { mem::zeroed() };
     c::fd_set(&mut set, fd);
     let (read, write) = match status {
         Readable => (&set as *_, ptr::null()),
         Writable => (ptr::null(), &set as *_),
     };
-    let mut tv: libc::timeval = unsafe { mem::init() };
+    let mut tv: libc::timeval = unsafe { mem::zeroed() };
 
     match retry(|| {
         let now = ::io::timer::now();
index 76341d21e9ac6395e421c87fdfddf849fd3f883d..f24bd661c8c178c9bfd6806542d66695c32c8374 100644 (file)
@@ -176,7 +176,7 @@ pub fn new(p: &Path) -> Lock {
             if handle as uint == libc::INVALID_HANDLE_VALUE as uint {
                 fail!("create file error: {}", os::last_os_error());
             }
-            let mut overlapped: libc::OVERLAPPED = unsafe { mem::init() };
+            let mut overlapped: libc::OVERLAPPED = unsafe { mem::zeroed() };
             let ret = unsafe {
                 LockFileEx(handle, LOCKFILE_EXCLUSIVE_LOCK, 0, 100, 0,
                            &mut overlapped)
@@ -192,7 +192,7 @@ pub fn new(p: &Path) -> Lock {
 
     impl Drop for Lock {
         fn drop(&mut self) {
-            let mut overlapped: libc::OVERLAPPED = unsafe { mem::init() };
+            let mut overlapped: libc::OVERLAPPED = unsafe { mem::zeroed() };
             unsafe {
                 UnlockFileEx(self.handle, 0, 100, 0, &mut overlapped);
                 libc::CloseHandle(self.handle);
index 0b31010020be15e362364111fe240b0861165661..9c77c7eb56be3a855c22b027158eae18c3c5c05e 100644 (file)
@@ -79,7 +79,7 @@ pub fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
 
 fn addr_to_sockaddr(addr: ip::SocketAddr) -> (libc::sockaddr_storage, uint) {
     unsafe {
-        let mut storage: libc::sockaddr_storage = mem::init();
+        let mut storage: libc::sockaddr_storage = mem::zeroed();
         let len = match addr.ip {
             ip::Ipv4Addr(a, b, c, d) => {
                 let storage: &mut libc::sockaddr_in =
@@ -133,7 +133,7 @@ fn socket_name(sk: SocketNameKind,
     };
 
     // Allocate a sockaddr_storage since we don't know if it's ipv4 or ipv6
-    let mut sockaddr: libc::sockaddr_storage = unsafe { mem::init() };
+    let mut sockaddr: libc::sockaddr_storage = unsafe { mem::zeroed() };
     let mut namelen = mem::size_of::<libc::sockaddr_storage>() as c_int;
 
     let sockaddr_p = &mut sockaddr as *mut libc::sockaddr_storage;
index 66471ee3923ce2c5c70773fd2de71177950d15f1..e78122f699d408cd585143352c4092331f21d2eb 100644 (file)
@@ -306,8 +306,10 @@ fn to_owned(&self) -> ~[T] {
             // this should pass the real required alignment
             let ret = exchange_malloc(size, 8) as *mut RawVec<()>;
 
-            (*ret).fill = len * mem::nonzero_size_of::<T>();
-            (*ret).alloc = len * mem::nonzero_size_of::<T>();
+            let a_size = mem::size_of::<T>();
+            let a_size = if a_size == 0 {1} else {a_size};
+            (*ret).fill = len * a_size;
+            (*ret).alloc = len * a_size;
 
             // Be careful with the following loop. We want it to be optimized
             // to a memcpy (or something similarly fast) when T is Copy. LLVM
@@ -318,7 +320,7 @@ fn to_owned(&self) -> ~[T] {
             try_finally(
                 &mut i, (),
                 |i, ()| while *i < len {
-                    mem::move_val_init(
+                    mem::overwrite(
                         &mut(*p.offset(*i as int)),
                         self.unsafe_ref(*i).clone());
                     *i += 1;
index c9d70915694e532ac4ee258f88bf66bd72df3e39..760214eb8f842f34c8cb1e9e50baade600c6a2a5 100644 (file)
@@ -390,8 +390,8 @@ pub struct Mutex {
     impl Mutex {
         pub unsafe fn new() -> Mutex {
             let m = Mutex {
-                lock: Unsafe::new(mem::init()),
-                cond: Unsafe::new(mem::init()),
+                lock: Unsafe::new(mem::zeroed()),
+                cond: Unsafe::new(mem::zeroed()),
             };
 
             pthread_mutex_init(m.lock.get(), 0 as *libc::c_void);
index 57f8d78948fa0ac5faab057f25693e42daf2c9c4..32883707615d535b839265a7f89df14942bcd999 100644 (file)
@@ -117,7 +117,7 @@ pub fn from_fn(length: uint, op: |uint| -> T) -> Vec<T> {
         unsafe {
             let mut xs = Vec::with_capacity(length);
             while xs.len < length {
-                mem::move_val_init(xs.as_mut_slice().unsafe_mut_ref(xs.len),
+                mem::overwrite(xs.as_mut_slice().unsafe_mut_ref(xs.len),
                                    op(xs.len));
                 xs.len += 1;
             }
@@ -214,7 +214,7 @@ pub fn from_elem(length: uint, value: T) -> Vec<T> {
         unsafe {
             let mut xs = Vec::with_capacity(length);
             while xs.len < length {
-                mem::move_val_init(xs.as_mut_slice().unsafe_mut_ref(xs.len),
+                mem::overwrite(xs.as_mut_slice().unsafe_mut_ref(xs.len),
                                    value.clone());
                 xs.len += 1;
             }
@@ -325,7 +325,7 @@ fn clone(&self) -> Vec<T> {
             let this_slice = self.as_slice();
             while vector.len < len {
                 unsafe {
-                    mem::move_val_init(
+                    mem::overwrite(
                         vector.as_mut_slice().unsafe_mut_ref(vector.len),
                         this_slice.unsafe_ref(vector.len).clone());
                 }
@@ -600,7 +600,7 @@ pub fn push(&mut self, value: T) {
 
         unsafe {
             let end = (self.ptr as *T).offset(self.len as int) as *mut T;
-            mem::move_val_init(&mut *end, value);
+            mem::overwrite(&mut *end, value);
             self.len += 1;
         }
     }
@@ -963,7 +963,7 @@ pub fn insert(&mut self, index: uint, element: T) {
                 ptr::copy_memory(p.offset(1), &*p, len - index);
                 // Write it in, overwriting the first copy of the `index`th
                 // element.
-                mem::move_val_init(&mut *p, element);
+                mem::overwrite(&mut *p, element);
             }
             self.set_len(len + 1);
         }
@@ -1542,8 +1542,10 @@ fn from_vec(mut v: Vec<T>) -> ~[T] {
         unsafe {
             let ret = allocate(size, 8) as *mut RawVec<()>;
 
-            (*ret).fill = len * mem::nonzero_size_of::<T>();
-            (*ret).alloc = len * mem::nonzero_size_of::<T>();
+            let a_size = mem::size_of::<T>();
+            let a_size = if a_size == 0 {1} else {a_size};
+            (*ret).fill = len * a_size;
+            (*ret).alloc = len * a_size;
 
             ptr::copy_nonoverlapping_memory(&mut (*ret).data as *mut _ as *mut u8,
                                             vp as *u8, data_size);
index ea067bc65cb7417292ffa39135cf3cf6663dd372..97bf9e9e8e2a66e72e30a6c6dbb83fd6832a4cf5 100644 (file)
@@ -14,6 +14,6 @@ pub fn main() {
     unsafe {
         let mut x: bool = false;
         // this line breaks it
-        mem::move_val_init(&mut x, false);
+        mem::overwrite(&mut x, false);
     }
 }