diff --git a/src/doc/guide-unsafe.md b/src/doc/guide-unsafe.md index d78e2103dac..3ff05ef3fd0 100644 --- a/src/doc/guide-unsafe.md +++ b/src/doc/guide-unsafe.md @@ -216,9 +216,9 @@ impl Unique { // 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} } } diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index f49bffe06d3..3c93cdac8bb 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -35,7 +35,6 @@ use std::cmp; 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 @@ impl Arena { #[inline] fn alloc_copy<'a, T>(&'a mut self, op: || -> T) -> &'a T { unsafe { - let ptr = self.alloc_copy_inner(mem::size_of::(), min_align_of::()); + let ptr = self.alloc_copy_inner(mem::size_of::(), + mem::min_align_of::()); let ptr = ptr as *mut T; - mem::move_val_init(&mut (*ptr), op()); + mem::overwrite(&mut (*ptr), op()); return &*ptr; } } @@ -239,7 +239,7 @@ impl Arena { 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 @@ impl Arena { unsafe { let tydesc = get_tydesc::(); let (ty_ptr, ptr) = - self.alloc_noncopy_inner(mem::size_of::(), min_align_of::()); + self.alloc_noncopy_inner(mem::size_of::(), + mem::min_align_of::()); 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 @@ impl TypedArenaChunk { size = size.checked_add(&elems_size).unwrap(); let mut chunk = unsafe { - let chunk = exchange_malloc(size, min_align_of::>()); + let chunk = exchange_malloc(size, + mem::min_align_of::>()); let mut chunk: Box> = mem::transmute(chunk); - mem::move_val_init(&mut chunk.next, next); + mem::overwrite(&mut chunk.next, next); chunk }; @@ -396,7 +398,8 @@ impl TypedArenaChunk { fn start(&self) -> *u8 { let this: *TypedArenaChunk = self; unsafe { - mem::transmute(round_up(this.offset(1) as uint, min_align_of::())) + mem::transmute(round_up(this.offset(1) as uint, + mem::min_align_of::())) } } @@ -440,7 +443,7 @@ impl TypedArena { } 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 diff --git a/src/libcollections/priority_queue.rs b/src/libcollections/priority_queue.rs index 2e8178cd931..4a0daf529de 100644 --- a/src/libcollections/priority_queue.rs +++ b/src/libcollections/priority_queue.rs @@ -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 @@ impl PriorityQueue { // 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 @@ impl PriorityQueue { 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); } } diff --git a/src/libcollections/trie.rs b/src/libcollections/trie.rs index f7fed0224a2..9d64b3c2394 100644 --- a/src/libcollections/trie.rs +++ b/src/libcollections/trie.rs @@ -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 @@ macro_rules! iterator_impl { 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 @@ macro_rules! iterator_impl { 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()] } } } diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index c5c6d751777..aa7a8f0f8b6 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -19,31 +19,36 @@ use intrinsics::{bswap16, bswap32, bswap64}; /// Returns the size of a type in bytes. #[inline] +#[stable] pub fn size_of() -> uint { unsafe { intrinsics::size_of::() } } /// 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(_val: &T) -> uint { size_of::() } -/// 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() -> uint { match size_of::() { 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(_val: &T) -> uint { - nonzero_size_of::() +#[deprecated = "this function will be removed soon"] +pub fn nonzero_size_of_val(val: &T) -> uint { + match size_of_val::(val) { + 0 => 1, + n => n, + } } /// Returns the ABI-required minimum alignment of a type @@ -51,6 +56,7 @@ pub fn nonzero_size_of_val(_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() -> uint { unsafe { intrinsics::min_align_of::() } } @@ -58,44 +64,100 @@ pub fn min_align_of() -> 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(_val: &T) -> uint { min_align_of::() } -/// 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() -> uint { +#[stable] +pub fn align_of() -> 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::() } } -/// 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(_val: &T) -> uint { - pref_align_of::() +#[unstable = "the name of this function may change slightly before stabilizing"] +pub fn align_of_val(_val: &T) -> uint { + align_of::() } +/// Deprecated, this function has been renamed to align_of +#[inline] +#[deprecated = "use mem::align_of instead"] +pub fn pref_align_of() -> uint { align_of::() } + +/// Deprecated, this function has been renamed to align_of_val +#[inline] +#[deprecated = "use mem::align_of_val instead"] +pub fn pref_align_of_val(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 { +#[unstable = "the name of this function is subject to change"] +pub unsafe fn zeroed() -> T { intrinsics::init() } -/// Create an uninitialized value. +/// Deprecated, use zeroed() instead #[inline] +#[deprecated = "this function has been renamed to zeroed()"] +pub unsafe fn init() -> 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 { 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(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(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(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(x: &mut T, y: &mut T) { unsafe { // Give ourselves some scratch space to work with @@ -279,6 +365,7 @@ pub fn swap(x: &mut T, y: &mut T) { * ``` */ #[inline] +#[stable] pub fn replace(dest: &mut T, mut src: T) -> T { swap(dest, &mut src); src @@ -304,6 +391,7 @@ pub fn replace(dest: &mut T, mut src: T) -> T { /// println!("{}", *borrow); /// ``` #[inline] +#[stable] pub fn drop(_x: T) { } /// Moves a thing into the void. @@ -415,27 +503,11 @@ mod tests { assert_eq!(size_of_val(&1u64), 8); } - #[test] - fn nonzero_size_of_basic() { - type Z = [i8, ..0]; - assert_eq!(size_of::(), 0u); - assert_eq!(nonzero_size_of::(), 1u); - assert_eq!(nonzero_size_of::(), size_of::()); - } - - #[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::(), 1u); - assert_eq!(pref_align_of::(), 2u); - assert_eq!(pref_align_of::(), 4u); + assert_eq!(align_of::(), 1u); + assert_eq!(align_of::(), 2u); + assert_eq!(align_of::(), 4u); } #[test] @@ -443,22 +515,22 @@ mod tests { #[cfg(target_arch = "arm")] #[cfg(target_arch = "mips")] fn align_of_32() { - assert_eq!(pref_align_of::(), 4u); - assert_eq!(pref_align_of::<*uint>(), 4u); + assert_eq!(align_of::(), 4u); + assert_eq!(align_of::<*uint>(), 4u); } #[test] #[cfg(target_arch = "x86_64")] fn align_of_64() { - assert_eq!(pref_align_of::(), 8u); - assert_eq!(pref_align_of::<*uint>(), 8u); + assert_eq!(align_of::(), 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] diff --git a/src/libcore/should_not_exist.rs b/src/libcore/should_not_exist.rs index b55952e7059..ccca52c573d 100644 --- a/src/libcore/should_not_exist.rs +++ b/src/libcore/should_not_exist.rs @@ -171,15 +171,17 @@ impl Clone for ~[A] { unsafe { let ret = alloc(size) as *mut Vec; - (*ret).fill = len * mem::nonzero_size_of::(); - (*ret).alloc = len * mem::nonzero_size_of::(); + let a_size = mem::size_of::(); + 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; diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index d08e5492c82..755c6738b4a 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -1122,7 +1122,7 @@ impl<'a,T> MutableVector<'a, T> for &'a mut [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 @@ macro_rules! iterator { #[inline] fn size_hint(&self) -> (uint, Option) { let diff = (self.end as uint) - (self.ptr as uint); - let exact = diff / mem::nonzero_size_of::(); + let size = mem::size_of::(); + let exact = diff / (if size == 0 {1} else {size}); (exact, Some(exact)) } } diff --git a/src/libnative/io/file_win32.rs b/src/libnative/io/file_win32.rs index 3222c912dd0..3bfd70a0a8b 100644 --- a/src/libnative/io/file_win32.rs +++ b/src/libnative/io/file_win32.rs @@ -118,7 +118,7 @@ impl rtio::RtioFileStream for FileDesc { fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result { 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 @@ impl rtio::RtioFileStream for FileDesc { 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; diff --git a/src/libnative/io/net.rs b/src/libnative/io/net.rs index 40b66cc526f..6ba92009c39 100644 --- a/src/libnative/io/net.rs +++ b/src/libnative/io/net.rs @@ -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(fd: sock_t, opt: libc::c_int, val: libc::c_int, pub fn getsockopt(fd: sock_t, opt: libc::c_int, val: libc::c_int) -> IoResult { unsafe { - let mut slot: T = mem::init(); + let mut slot: T = mem::zeroed(); let mut len = mem::size_of::() 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 { - let mut storage: libc::sockaddr_storage = unsafe { mem::init() }; + let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() }; let mut len = mem::size_of::() 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 @@ impl TcpAcceptor { 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::(); let mut size = size as libc::socklen_t; @@ -622,7 +622,7 @@ impl rtio::RtioSocket for UdpSocket { 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::() as libc::socklen_t; diff --git a/src/libnative/io/pipe_win32.rs b/src/libnative/io/pipe_win32.rs index af80c7174f2..5acb48a5f39 100644 --- a/src/libnative/io/pipe_win32.rs +++ b/src/libnative/io/pipe_win32.rs @@ -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 @@ impl rtio::RtioPipe for UnixStream { } 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 @@ impl rtio::RtioPipe for UnixStream { } 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 @@ impl UnixAcceptor { // 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() }; diff --git a/src/libnative/io/process.rs b/src/libnative/io/process.rs index 0eebd3380e6..04911bc5f1b 100644 --- a/src/libnative/io/process.rs +++ b/src/libnative/io/process.rs @@ -896,8 +896,8 @@ fn waitpid(pid: pid_t, deadline: u64) -> IoResult { // 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(pid: pid_t, deadline: u64) -> IoResult { messages: Receiver, (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, u64)>::new(); let max = cmp::max(input, read_fd) + 1; diff --git a/src/libnative/io/timer_unix.rs b/src/libnative/io/timer_unix.rs index 2c5b7984827..ed218022b2e 100644 --- a/src/libnative/io/timer_unix.rs +++ b/src/libnative/io/timer_unix.rs @@ -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, _: ()) { - 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 diff --git a/src/libnative/io/util.rs b/src/libnative/io/util.rs index 0d032f9f4bc..fe7a58a5e68 100644 --- a/src/libnative/io/util.rs +++ b/src/libnative/io/util.rs @@ -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 @@ pub fn connect_timeout(fd: net::sock_t, pub fn await(fd: net::sock_t, deadline: Option, 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(); diff --git a/src/librustdoc/flock.rs b/src/librustdoc/flock.rs index 76341d21e9a..f24bd661c8c 100644 --- a/src/librustdoc/flock.rs +++ b/src/librustdoc/flock.rs @@ -176,7 +176,7 @@ mod imp { 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 @@ mod imp { 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); diff --git a/src/librustuv/net.rs b/src/librustuv/net.rs index 0b31010020b..9c77c7eb56b 100644 --- a/src/librustuv/net.rs +++ b/src/librustuv/net.rs @@ -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::() as c_int; let sockaddr_p = &mut sockaddr as *mut libc::sockaddr_storage; diff --git a/src/libstd/slice.rs b/src/libstd/slice.rs index 66471ee3923..e78122f699d 100644 --- a/src/libstd/slice.rs +++ b/src/libstd/slice.rs @@ -306,8 +306,10 @@ impl<'a, T: Clone> CloneableVector for &'a [T] { // this should pass the real required alignment let ret = exchange_malloc(size, 8) as *mut RawVec<()>; - (*ret).fill = len * mem::nonzero_size_of::(); - (*ret).alloc = len * mem::nonzero_size_of::(); + let a_size = mem::size_of::(); + 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 @@ impl<'a, T: Clone> CloneableVector for &'a [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; diff --git a/src/libstd/unstable/mutex.rs b/src/libstd/unstable/mutex.rs index c9d70915694..760214eb8f8 100644 --- a/src/libstd/unstable/mutex.rs +++ b/src/libstd/unstable/mutex.rs @@ -390,8 +390,8 @@ mod imp { 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); diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 57f8d78948f..32883707615 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -117,7 +117,7 @@ impl Vec { 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 @@ impl Vec { 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 @@ impl Clone for Vec { 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 @@ impl Vec { 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 @@ impl Vec { 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 @@ impl FromVec for ~[T] { unsafe { let ret = allocate(size, 8) as *mut RawVec<()>; - (*ret).fill = len * mem::nonzero_size_of::(); - (*ret).alloc = len * mem::nonzero_size_of::(); + let a_size = mem::size_of::(); + 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); diff --git a/src/test/run-pass/type-use-i1-versus-i8.rs b/src/test/run-pass/type-use-i1-versus-i8.rs index ea067bc65cb..97bf9e9e8e2 100644 --- a/src/test/run-pass/type-use-i1-versus-i8.rs +++ b/src/test/run-pass/type-use-i1-versus-i8.rs @@ -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); } }