about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-04-03 17:17:02 -0700
committerbors <bors@rust-lang.org>2014-04-03 17:17:02 -0700
commite7fe20722904cd2829a65f845ee7a1718cdf7292 (patch)
treede906a26828f4a01fcdec0112047d16250d5c991 /src/libstd
parentbb31cb8d2e4e415cbb71d368918d72902e655e01 (diff)
parent487fa9568b69753fecb74a8460109239f4bf3631 (diff)
downloadrust-e7fe20722904cd2829a65f845ee7a1718cdf7292.tar.gz
rust-e7fe20722904cd2829a65f845ee7a1718cdf7292.zip
auto merge of #13290 : alexcrichton/rust/rollup, r=alexcrichton
Closes #13285 (rustc: Stop using LLVMGetSectionName)
Closes #13280 (std: override clone_from for Vec.)
Closes #13277 (serialize: add a few missing pubs to base64)
Closes #13275 (Add and remove some ignore-win32 flags)
Closes #13273 (Removed managed boxes from libarena.)
Closes #13270 (Minor copy-editing for the tutorial)
Closes #13267 (fix Option<~ZeroSizeType>)
Closes #13265 (Update emacs mode to support new `#![inner(attribute)]` syntax.)
Closes #13263 (syntax: Remove AbiSet, use one Abi)
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/lib.rs1
-rw-r--r--src/libstd/rt/global_heap.rs13
-rw-r--r--src/libstd/vec.rs56
3 files changed, 64 insertions, 6 deletions
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 75d6b83803f..b6e3e56835f 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -232,4 +232,5 @@ mod std {
     pub use to_str;
     pub use ty;
     pub use unstable;
+    pub use vec;
 }
diff --git a/src/libstd/rt/global_heap.rs b/src/libstd/rt/global_heap.rs
index 23b23cf8af0..5c1b6cd4791 100644
--- a/src/libstd/rt/global_heap.rs
+++ b/src/libstd/rt/global_heap.rs
@@ -68,8 +68,17 @@ pub unsafe fn realloc_raw(ptr: *mut u8, size: uint) -> *mut u8 {
 #[cfg(not(test))]
 #[lang="exchange_malloc"]
 #[inline]
-pub unsafe fn exchange_malloc(size: uint) -> *u8 {
-    malloc_raw(size) as *u8
+pub unsafe fn exchange_malloc(size: uint) -> *mut u8 {
+    // The compiler never calls `exchange_free` on ~ZeroSizeType, so zero-size
+    // allocations can point to this `static`. It would be incorrect to use a null
+    // pointer, due to enums assuming types like unique pointers are never null.
+    static EMPTY: () = ();
+
+    if size == 0 {
+        &EMPTY as *() as *mut u8
+    } else {
+        malloc_raw(size)
+    }
 }
 
 // FIXME: #7496
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 69c3a85b2f1..e414ff25d43 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -310,11 +310,24 @@ impl<T: Clone> Vec<T> {
 
 impl<T:Clone> Clone for Vec<T> {
     fn clone(&self) -> Vec<T> {
-        let mut vector = Vec::with_capacity(self.len());
-        for element in self.iter() {
-            vector.push((*element).clone())
+        self.iter().map(|x| x.clone()).collect()
+    }
+
+    fn clone_from(&mut self, other: &Vec<T>) {
+        // drop anything in self that will not be overwritten
+        if self.len() > other.len() {
+            self.truncate(other.len())
         }
-        vector
+
+        // reuse the contained values' allocations/resources.
+        for (place, thing) in self.mut_iter().zip(other.iter()) {
+            place.clone_from(thing)
+        }
+
+        // self.len <= other.len due to the truncate above, so the
+        // slice here is always in-bounds.
+        let len = self.len();
+        self.extend(other.slice_from(len).iter().map(|x| x.clone()));
     }
 }
 
@@ -1475,4 +1488,39 @@ mod tests {
 
         assert!(values == Vec::from_slice([2u8, 3, 5, 6, 7]));
     }
+
+    #[test]
+    fn test_clone() {
+        let v: Vec<int> = vec!();
+        let w = vec!(1, 2, 3);
+
+        assert_eq!(v, v.clone());
+
+        let z = w.clone();
+        assert_eq!(w, z);
+        // they should be disjoint in memory.
+        assert!(w.as_ptr() != z.as_ptr())
+    }
+
+    #[test]
+    fn test_clone_from() {
+        let mut v = vec!();
+        let three = vec!(~1, ~2, ~3);
+        let two = vec!(~4, ~5);
+        // zero, long
+        v.clone_from(&three);
+        assert_eq!(v, three);
+
+        // equal
+        v.clone_from(&three);
+        assert_eq!(v, three);
+
+        // long, short
+        v.clone_from(&two);
+        assert_eq!(v, two);
+
+        // short, long
+        v.clone_from(&three);
+        assert_eq!(v, three)
+    }
 }