about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-02-23 20:47:30 +0000
committerbors <bors@rust-lang.org>2015-02-23 20:47:30 +0000
commit91a5a1ab4ad054c8dccf49f6f409542f82683cfc (patch)
tree1c2a90b8e1aac6793a0fbf6350778a5b9ac65dae /src/libstd
parentf0f7ca27de6b4e03f30012656dad270cda55a363 (diff)
parentee6f2a1ad6ab79ed954cd96fff6eaddcdfb6a043 (diff)
downloadrust-91a5a1ab4ad054c8dccf49f6f409542f82683cfc.tar.gz
rust-91a5a1ab4ad054c8dccf49f6f409542f82683cfc.zip
Auto merge of #22724 - Manishearth:rollup, r=alexcrichton
Seems to pass `check-stage1`, but I had to tweak some things so it's going through the test gauntlet again.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/collections/hash/map.rs2
-rw-r--r--src/libstd/collections/mod.rs8
-rw-r--r--src/libstd/ffi/c_str.rs6
-rw-r--r--src/libstd/io/mod.rs35
-rw-r--r--src/libstd/lib.rs1
-rw-r--r--src/libstd/num/mod.rs66
-rw-r--r--src/libstd/num/uint_macros.rs62
-rw-r--r--src/libstd/old_io/stdio.rs9
-rw-r--r--src/libstd/rt/at_exit_imp.rs6
-rw-r--r--src/libstd/rt/unwind.rs6
-rw-r--r--src/libstd/sync/mpsc/mpsc_queue.rs8
-rw-r--r--src/libstd/sync/mpsc/spsc_queue.rs8
-rw-r--r--src/libstd/sys/common/helper_thread.rs6
-rw-r--r--src/libstd/sys/common/thread.rs2
-rw-r--r--src/libstd/sys/unix/thread.rs7
-rw-r--r--src/libstd/sys/windows/thread.rs7
-rw-r--r--src/libstd/sys/windows/thread_local.rs6
-rw-r--r--src/libstd/thread_local/mod.rs10
18 files changed, 152 insertions, 103 deletions
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index f5d2b8aed29..df2fb538c0a 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -203,7 +203,7 @@ fn test_resize_policy() {
 // produces identical results to a linear naive reinsertion from the same
 // element.
 //
-// FIXME(Gankro, pczarn): review the proof and put it all in a separate doc.rs
+// FIXME(Gankro, pczarn): review the proof and put it all in a separate README.md
 
 /// A hash map implementation which uses linear probing with Robin
 /// Hood bucket stealing.
diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs
index 0e64370df60..100d3e6ed4a 100644
--- a/src/libstd/collections/mod.rs
+++ b/src/libstd/collections/mod.rs
@@ -23,9 +23,9 @@
 //!
 //! Rust's collections can be grouped into four major categories:
 //!
-//! * Sequences: `Vec`, `VecDeque`, `LinkedList`, `BitV`
+//! * Sequences: `Vec`, `VecDeque`, `LinkedList`, `BitVec`
 //! * Maps: `HashMap`, `BTreeMap`, `VecMap`
-//! * Sets: `HashSet`, `BTreeSet`, `BitVSet`
+//! * Sets: `HashSet`, `BTreeSet`, `BitSet`
 //! * Misc: `BinaryHeap`
 //!
 //! # When Should You Use Which Collection?
@@ -73,11 +73,11 @@
 //! * There is no meaningful value to associate with your keys.
 //! * You just want a set.
 //!
-//! ### Use a `BitV` when:
+//! ### Use a `BitVec` when:
 //! * You want to store an unbounded number of booleans in a small space.
 //! * You want a bit vector.
 //!
-//! ### Use a `BitVSet` when:
+//! ### Use a `BitSet` when:
 //! * You want a `VecSet`.
 //!
 //! ### Use a `BinaryHeap` when:
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 8976813d3f9..69bcc82f682 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -224,7 +224,7 @@ impl CString {
     /// Returns the contents of this `CString` as a slice of bytes.
     ///
     /// The returned slice does **not** contain the trailing nul separator and
-    /// it is guaranteet to not have any interior nul bytes.
+    /// it is guaranteed to not have any interior nul bytes.
     pub fn as_bytes(&self) -> &[u8] {
         &self.inner[..self.inner.len() - 1]
     }
@@ -333,7 +333,7 @@ impl CStr {
     /// Return the inner pointer to this C string.
     ///
     /// The returned pointer will be valid for as long as `self` is and points
-    /// to a continguous region of memory terminated with a 0 byte to represent
+    /// to a contiguous region of memory terminated with a 0 byte to represent
     /// the end of the string.
     pub fn as_ptr(&self) -> *const libc::c_char {
         self.inner.as_ptr()
@@ -371,7 +371,7 @@ impl CStr {
 
 impl PartialEq for CStr {
     fn eq(&self, other: &CStr) -> bool {
-        self.to_bytes().eq(&other.to_bytes())
+        self.to_bytes().eq(other.to_bytes())
     }
 }
 impl Eq for CStr {}
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 5b319f4c687..3b4e15953c4 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -669,6 +669,11 @@ impl<T> Take<T> {
 
 impl<T: Read> Read for Take<T> {
     fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
+        // Don't call into inner reader at all at EOF because it may still block
+        if self.limit == 0 {
+            return Ok(0);
+        }
+
         let max = cmp::min(buf.len() as u64, self.limit) as usize;
         let n = try!(self.inner.read(&mut buf[..max]));
         self.limit -= n as u64;
@@ -676,6 +681,21 @@ impl<T: Read> Read for Take<T> {
     }
 }
 
+impl<T: BufRead> BufRead for Take<T> {
+    fn fill_buf(&mut self) -> Result<&[u8]> {
+        let buf = try!(self.inner.fill_buf());
+        let cap = cmp::min(buf.len() as u64, self.limit) as usize;
+        Ok(&buf[..cap])
+    }
+
+    fn consume(&mut self, amt: usize) {
+        // Don't let callers reset the limit by passing an overlarge value
+        let amt = cmp::min(amt as u64, self.limit) as usize;
+        self.limit -= amt as u64;
+        self.inner.consume(amt);
+    }
+}
+
 /// An adaptor which will emit all read data to a specified writer as well.
 ///
 /// For more information see `ReadExt::tee`
@@ -846,6 +866,7 @@ impl<B: BufRead> Iterator for Lines<B> {
 mod tests {
     use prelude::v1::*;
     use io::prelude::*;
+    use io;
     use super::Cursor;
 
     #[test]
@@ -943,4 +964,18 @@ mod tests {
         let mut v = String::new();
         assert!(c.read_to_string(&mut v).is_err());
     }
+
+    #[test]
+    fn take_eof() {
+        struct R;
+
+        impl Read for R {
+            fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+                Err(io::Error::new(io::ErrorKind::Other, "", None))
+            }
+        }
+
+        let mut buf = [0; 1];
+        assert_eq!(Ok(0), R.take(0).read(&mut buf));
+    }
 }
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 4b6e9cf76f9..caaedeeb2fc 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -122,6 +122,7 @@
 #![feature(unsafe_destructor)]
 #![feature(unsafe_no_drop_flag)]
 #![feature(macro_reexport)]
+#![feature(hash)]
 #![cfg_attr(test, feature(test, rustc_private, env))]
 
 // Don't link to std. We are std.
diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs
index 968adfafeab..15ae8b027e1 100644
--- a/src/libstd/num/mod.rs
+++ b/src/libstd/num/mod.rs
@@ -1751,6 +1751,72 @@ mod tests {
         assert_pow!((8,     3 ) => 512);
         assert_pow!((2u64,   50) => 1125899906842624);
     }
+
+    #[test]
+    fn test_uint_to_str_overflow() {
+        let mut u8_val: u8 = 255_u8;
+        assert_eq!(u8_val.to_string(), "255");
+
+        u8_val += 1 as u8;
+        assert_eq!(u8_val.to_string(), "0");
+
+        let mut u16_val: u16 = 65_535_u16;
+        assert_eq!(u16_val.to_string(), "65535");
+
+        u16_val += 1 as u16;
+        assert_eq!(u16_val.to_string(), "0");
+
+        let mut u32_val: u32 = 4_294_967_295_u32;
+        assert_eq!(u32_val.to_string(), "4294967295");
+
+        u32_val += 1 as u32;
+        assert_eq!(u32_val.to_string(), "0");
+
+        let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
+        assert_eq!(u64_val.to_string(), "18446744073709551615");
+
+        u64_val += 1 as u64;
+        assert_eq!(u64_val.to_string(), "0");
+    }
+
+    fn from_str<T: ::str::FromStr>(t: &str) -> Option<T> {
+        ::str::FromStr::from_str(t).ok()
+    }
+
+    #[test]
+    fn test_uint_from_str_overflow() {
+        let mut u8_val: u8 = 255_u8;
+        assert_eq!(from_str::<u8>("255"), Some(u8_val));
+        assert_eq!(from_str::<u8>("256"), None);
+
+        u8_val += 1 as u8;
+        assert_eq!(from_str::<u8>("0"), Some(u8_val));
+        assert_eq!(from_str::<u8>("-1"), None);
+
+        let mut u16_val: u16 = 65_535_u16;
+        assert_eq!(from_str::<u16>("65535"), Some(u16_val));
+        assert_eq!(from_str::<u16>("65536"), None);
+
+        u16_val += 1 as u16;
+        assert_eq!(from_str::<u16>("0"), Some(u16_val));
+        assert_eq!(from_str::<u16>("-1"), None);
+
+        let mut u32_val: u32 = 4_294_967_295_u32;
+        assert_eq!(from_str::<u32>("4294967295"), Some(u32_val));
+        assert_eq!(from_str::<u32>("4294967296"), None);
+
+        u32_val += 1 as u32;
+        assert_eq!(from_str::<u32>("0"), Some(u32_val));
+        assert_eq!(from_str::<u32>("-1"), None);
+
+        let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
+        assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val));
+        assert_eq!(from_str::<u64>("18446744073709551616"), None);
+
+        u64_val += 1 as u64;
+        assert_eq!(from_str::<u64>("0"), Some(u64_val));
+        assert_eq!(from_str::<u64>("-1"), None);
+    }
 }
 
 
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index 8d4f0344beb..c9e6a8f66d1 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -48,68 +48,6 @@ mod tests {
         assert_eq!(FromStrRadix::from_str_radix("Z", 10).ok(), None::<$T>);
         assert_eq!(FromStrRadix::from_str_radix("_", 2).ok(), None::<$T>);
     }
-
-    #[test]
-    fn test_uint_to_str_overflow() {
-        let mut u8_val: u8 = 255_u8;
-        assert_eq!(u8_val.to_string(), "255");
-
-        u8_val += 1 as u8;
-        assert_eq!(u8_val.to_string(), "0");
-
-        let mut u16_val: u16 = 65_535_u16;
-        assert_eq!(u16_val.to_string(), "65535");
-
-        u16_val += 1 as u16;
-        assert_eq!(u16_val.to_string(), "0");
-
-        let mut u32_val: u32 = 4_294_967_295_u32;
-        assert_eq!(u32_val.to_string(), "4294967295");
-
-        u32_val += 1 as u32;
-        assert_eq!(u32_val.to_string(), "0");
-
-        let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
-        assert_eq!(u64_val.to_string(), "18446744073709551615");
-
-        u64_val += 1 as u64;
-        assert_eq!(u64_val.to_string(), "0");
-    }
-
-    #[test]
-    fn test_uint_from_str_overflow() {
-        let mut u8_val: u8 = 255_u8;
-        assert_eq!(from_str::<u8>("255"), Some(u8_val));
-        assert_eq!(from_str::<u8>("256"), None);
-
-        u8_val += 1 as u8;
-        assert_eq!(from_str::<u8>("0"), Some(u8_val));
-        assert_eq!(from_str::<u8>("-1"), None);
-
-        let mut u16_val: u16 = 65_535_u16;
-        assert_eq!(from_str::<u16>("65535"), Some(u16_val));
-        assert_eq!(from_str::<u16>("65536"), None);
-
-        u16_val += 1 as u16;
-        assert_eq!(from_str::<u16>("0"), Some(u16_val));
-        assert_eq!(from_str::<u16>("-1"), None);
-
-        let mut u32_val: u32 = 4_294_967_295_u32;
-        assert_eq!(from_str::<u32>("4294967295"), Some(u32_val));
-        assert_eq!(from_str::<u32>("4294967296"), None);
-
-        u32_val += 1 as u32;
-        assert_eq!(from_str::<u32>("0"), Some(u32_val));
-        assert_eq!(from_str::<u32>("-1"), None);
-
-        let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
-        assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val));
-        assert_eq!(from_str::<u64>("18446744073709551616"), None);
-
-        u64_val += 1 as u64;
-        assert_eq!(from_str::<u64>("0"), Some(u64_val));
-        assert_eq!(from_str::<u64>("-1"), None);
-    }
 }
 
 ) }
diff --git a/src/libstd/old_io/stdio.rs b/src/libstd/old_io/stdio.rs
index e3d0232684f..56a707c24a6 100644
--- a/src/libstd/old_io/stdio.rs
+++ b/src/libstd/old_io/stdio.rs
@@ -27,6 +27,7 @@
 
 use self::StdSource::*;
 
+use boxed;
 use boxed::Box;
 use cell::RefCell;
 use clone::Clone;
@@ -218,7 +219,7 @@ impl Reader for StdinReader {
 /// See `stdout()` for more notes about this function.
 pub fn stdin() -> StdinReader {
     // We're following the same strategy as kimundi's lazy_static library
-    static mut STDIN: *const StdinReader = 0 as *const StdinReader;
+    static mut STDIN: *mut StdinReader = 0 as *mut StdinReader;
     static ONCE: Once = ONCE_INIT;
 
     unsafe {
@@ -235,12 +236,12 @@ pub fn stdin() -> StdinReader {
             let stdin = StdinReader {
                 inner: Arc::new(Mutex::new(RaceBox(stdin)))
             };
-            STDIN = mem::transmute(box stdin);
+            STDIN = boxed::into_raw(box stdin);
 
             // Make sure to free it at exit
             rt::at_exit(|| {
-                mem::transmute::<_, Box<StdinReader>>(STDIN);
-                STDIN = ptr::null();
+                Box::from_raw(STDIN);
+                STDIN = ptr::null_mut();
             });
         });
 
diff --git a/src/libstd/rt/at_exit_imp.rs b/src/libstd/rt/at_exit_imp.rs
index 72486fc55d4..08755ba829f 100644
--- a/src/libstd/rt/at_exit_imp.rs
+++ b/src/libstd/rt/at_exit_imp.rs
@@ -14,9 +14,9 @@
 
 use core::prelude::*;
 
+use boxed;
 use boxed::Box;
 use vec::Vec;
-use mem;
 use thunk::Thunk;
 use sys_common::mutex::{Mutex, MUTEX_INIT};
 
@@ -32,7 +32,7 @@ static mut QUEUE: *mut Queue = 0 as *mut Queue;
 unsafe fn init() {
     if QUEUE.is_null() {
         let state: Box<Queue> = box Vec::new();
-        QUEUE = mem::transmute(state);
+        QUEUE = boxed::into_raw(state);
     } else {
         // can't re-init after a cleanup
         rtassert!(QUEUE as uint != 1);
@@ -57,7 +57,7 @@ pub fn cleanup() {
 
         // If we never called init, not need to cleanup!
         if queue as uint != 0 {
-            let queue: Box<Queue> = mem::transmute(queue);
+            let queue: Box<Queue> = Box::from_raw(queue);
             for to_run in *queue {
                 to_run.invoke(());
             }
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
index 1f5eb3af695..4dda3ea8c99 100644
--- a/src/libstd/rt/unwind.rs
+++ b/src/libstd/rt/unwind.rs
@@ -60,6 +60,7 @@
 use prelude::v1::*;
 
 use any::Any;
+use boxed;
 use cell::Cell;
 use cmp;
 use panicking;
@@ -173,7 +174,8 @@ fn rust_panic(cause: Box<Any + Send + 'static>) -> ! {
             },
             cause: Some(cause),
         };
-        let error = uw::_Unwind_RaiseException(mem::transmute(exception));
+        let exception_param = boxed::into_raw(exception) as *mut uw::_Unwind_Exception;
+        let error = uw::_Unwind_RaiseException(exception_param);
         rtabort!("Could not unwind stack, error = {}", error as int)
     }
 
@@ -181,7 +183,7 @@ fn rust_panic(cause: Box<Any + Send + 'static>) -> ! {
                                 exception: *mut uw::_Unwind_Exception) {
         rtdebug!("exception_cleanup()");
         unsafe {
-            let _: Box<Exception> = mem::transmute(exception);
+            let _: Box<Exception> = Box::from_raw(exception as *mut Exception);
         }
     }
 }
diff --git a/src/libstd/sync/mpsc/mpsc_queue.rs b/src/libstd/sync/mpsc/mpsc_queue.rs
index 6eb7c8c5961..59fa2e6bc9a 100644
--- a/src/libstd/sync/mpsc/mpsc_queue.rs
+++ b/src/libstd/sync/mpsc/mpsc_queue.rs
@@ -44,8 +44,8 @@ pub use self::PopResult::*;
 
 use core::prelude::*;
 
+use alloc::boxed;
 use alloc::boxed::Box;
-use core::mem;
 use core::ptr;
 use core::cell::UnsafeCell;
 
@@ -82,7 +82,7 @@ unsafe impl<T: Send> Sync for Queue<T> { }
 
 impl<T> Node<T> {
     unsafe fn new(v: Option<T>) -> *mut Node<T> {
-        mem::transmute(box Node {
+        boxed::into_raw(box Node {
             next: AtomicPtr::new(ptr::null_mut()),
             value: v,
         })
@@ -129,7 +129,7 @@ impl<T: Send> Queue<T> {
                 assert!((*tail).value.is_none());
                 assert!((*next).value.is_some());
                 let ret = (*next).value.take().unwrap();
-                let _: Box<Node<T>> = mem::transmute(tail);
+                let _: Box<Node<T>> = Box::from_raw(tail);
                 return Data(ret);
             }
 
@@ -146,7 +146,7 @@ impl<T: Send> Drop for Queue<T> {
             let mut cur = *self.tail.get();
             while !cur.is_null() {
                 let next = (*cur).next.load(Ordering::Relaxed);
-                let _: Box<Node<T>> = mem::transmute(cur);
+                let _: Box<Node<T>> = Box::from_raw(cur);
                 cur = next;
             }
         }
diff --git a/src/libstd/sync/mpsc/spsc_queue.rs b/src/libstd/sync/mpsc/spsc_queue.rs
index f111e13975f..7b5c614536d 100644
--- a/src/libstd/sync/mpsc/spsc_queue.rs
+++ b/src/libstd/sync/mpsc/spsc_queue.rs
@@ -37,8 +37,8 @@
 
 use core::prelude::*;
 
+use alloc::boxed;
 use alloc::boxed::Box;
-use core::mem;
 use core::ptr;
 use core::cell::UnsafeCell;
 
@@ -81,7 +81,7 @@ unsafe impl<T: Send> Sync for Queue<T> { }
 impl<T: Send> Node<T> {
     fn new() -> *mut Node<T> {
         unsafe {
-            mem::transmute(box Node {
+            boxed::into_raw(box Node {
                 value: None,
                 next: AtomicPtr::new(ptr::null_mut::<Node<T>>()),
             })
@@ -200,7 +200,7 @@ impl<T: Send> Queue<T> {
                           .next.store(next, Ordering::Relaxed);
                     // We have successfully erased all references to 'tail', so
                     // now we can safely drop it.
-                    let _: Box<Node<T>> = mem::transmute(tail);
+                    let _: Box<Node<T>> = Box::from_raw(tail);
                 }
             }
             return ret;
@@ -233,7 +233,7 @@ impl<T: Send> Drop for Queue<T> {
             let mut cur = *self.first.get();
             while !cur.is_null() {
                 let next = (*cur).next.load(Ordering::Relaxed);
-                let _n: Box<Node<T>> = mem::transmute(cur);
+                let _n: Box<Node<T>> = Box::from_raw(cur);
                 cur = next;
             }
         }
diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs
index dc1ae85efe0..5faaa928ee9 100644
--- a/src/libstd/sys/common/helper_thread.rs
+++ b/src/libstd/sys/common/helper_thread.rs
@@ -22,8 +22,8 @@
 
 use prelude::v1::*;
 
+use boxed;
 use cell::UnsafeCell;
-use mem;
 use ptr;
 use rt;
 use sync::{StaticMutex, StaticCondvar};
@@ -88,7 +88,7 @@ impl<M: Send> Helper<M> {
             let _guard = self.lock.lock().unwrap();
             if !*self.initialized.get() {
                 let (tx, rx) = channel();
-                *self.chan.get() = mem::transmute(box tx);
+                *self.chan.get() = boxed::into_raw(box tx);
                 let (receive, send) = helper_signal::new();
                 *self.signal.get() = send as uint;
 
@@ -132,7 +132,7 @@ impl<M: Send> Helper<M> {
             let mut guard = self.lock.lock().unwrap();
 
             // Close the channel by destroying it
-            let chan: Box<Sender<M>> = mem::transmute(*self.chan.get());
+            let chan: Box<Sender<M>> = Box::from_raw(*self.chan.get());
             *self.chan.get() = ptr::null_mut();
             drop(chan);
             helper_signal::signal(*self.signal.get() as helper_signal::signal);
diff --git a/src/libstd/sys/common/thread.rs b/src/libstd/sys/common/thread.rs
index b725b6c7e6e..731617858e9 100644
--- a/src/libstd/sys/common/thread.rs
+++ b/src/libstd/sys/common/thread.rs
@@ -27,7 +27,7 @@ pub fn start_thread(main: *mut libc::c_void) -> thread::rust_thread_return {
     unsafe {
         stack::record_os_managed_stack_bounds(0, usize::MAX);
         let handler = stack_overflow::Handler::new();
-        let f: Box<Thunk> = mem::transmute(main);
+        let f: Box<Thunk> = Box::from_raw(main as *mut Thunk);
         f.invoke(());
         drop(handler);
         mem::transmute(0 as thread::rust_thread_return)
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index c42d6d0e641..f4791d39da1 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -11,6 +11,7 @@
 use core::prelude::*;
 
 use io;
+use boxed;
 use boxed::Box;
 use cmp;
 use mem;
@@ -241,13 +242,15 @@ pub unsafe fn create(stack: uint, p: Thunk) -> io::Result<rust_thread> {
         },
     };
 
-    let arg: *mut libc::c_void = mem::transmute(box p); // must box since sizeof(p)=2*uint
+    // must box since sizeof(p)=2*uint
+    let raw_p = boxed::into_raw(box p);
+    let arg = raw_p as *mut libc::c_void;
     let ret = pthread_create(&mut native, &attr, thread_start, arg);
     assert_eq!(pthread_attr_destroy(&mut attr), 0);
 
     if ret != 0 {
         // be sure to not leak the closure
-        let _p: Box<Box<FnOnce()+Send>> = mem::transmute(arg);
+        let _p: Box<Thunk> = Box::from_raw(raw_p);
         Err(io::Error::from_os_error(ret))
     } else {
         Ok(native)
diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs
index f3a27877e5c..aa22b6b1307 100644
--- a/src/libstd/sys/windows/thread.rs
+++ b/src/libstd/sys/windows/thread.rs
@@ -10,9 +10,9 @@
 
 use prelude::v1::*;
 
+use boxed;
 use cmp;
 use io;
-use mem;
 use ptr;
 use libc;
 use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES, SIZE_T, BOOL,
@@ -45,7 +45,8 @@ pub mod guard {
 }
 
 pub unsafe fn create(stack: uint, p: Thunk) -> io::Result<rust_thread> {
-    let arg: *mut libc::c_void = mem::transmute(box p);
+    let raw_p = boxed::into_raw(box p);
+    let arg = raw_p as *mut libc::c_void;
     // FIXME On UNIX, we guard against stack sizes that are too small but
     // that's because pthreads enforces that stacks are at least
     // PTHREAD_STACK_MIN bytes big.  Windows has no such lower limit, it's
@@ -61,7 +62,7 @@ pub unsafe fn create(stack: uint, p: Thunk) -> io::Result<rust_thread> {
 
     if ret as uint == 0 {
         // be sure to not leak the closure
-        let _p: Box<Thunk> = mem::transmute(arg);
+        let _p: Box<Thunk> = Box::from_raw(raw_p);
         Err(io::Error::last_os_error())
     } else {
         Ok(ret)
diff --git a/src/libstd/sys/windows/thread_local.rs b/src/libstd/sys/windows/thread_local.rs
index 0c24ab1fa09..30c483ac52f 100644
--- a/src/libstd/sys/windows/thread_local.rs
+++ b/src/libstd/sys/windows/thread_local.rs
@@ -12,7 +12,7 @@ use prelude::v1::*;
 
 use libc::types::os::arch::extra::{DWORD, LPVOID, BOOL};
 
-use mem;
+use boxed;
 use ptr;
 use rt;
 use sys_common::mutex::{MUTEX_INIT, Mutex};
@@ -133,13 +133,13 @@ unsafe fn init_dtors() {
     if !DTORS.is_null() { return }
 
     let dtors = box Vec::<(Key, Dtor)>::new();
-    DTORS = mem::transmute(dtors);
+    DTORS = boxed::into_raw(dtors);
 
     rt::at_exit(move|| {
         DTOR_LOCK.lock();
         let dtors = DTORS;
         DTORS = ptr::null_mut();
-        mem::transmute::<_, Box<Vec<(Key, Dtor)>>>(dtors);
+        Box::from_raw(dtors);
         assert!(DTORS.is_null()); // can't re-init after destructing
         DTOR_LOCK.unlock();
     });
diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs
index 2ed296e081c..cdd71d440fe 100644
--- a/src/libstd/thread_local/mod.rs
+++ b/src/libstd/thread_local/mod.rs
@@ -388,6 +388,7 @@ mod imp {
     // Due to rust-lang/rust#18804, make sure this is not generic!
     #[cfg(target_os = "linux")]
     unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
+        use boxed;
         use mem;
         use libc;
         use sys_common::thread_local as os;
@@ -422,14 +423,14 @@ mod imp {
         type List = Vec<(*mut u8, unsafe extern fn(*mut u8))>;
         if DTORS.get().is_null() {
             let v: Box<List> = box Vec::new();
-            DTORS.set(mem::transmute(v));
+            DTORS.set(boxed::into_raw(v) as *mut u8);
         }
         let list: &mut List = &mut *(DTORS.get() as *mut List);
         list.push((t, dtor));
 
         unsafe extern fn run_dtors(mut ptr: *mut u8) {
             while !ptr.is_null() {
-                let list: Box<List> = mem::transmute(ptr);
+                let list: Box<List> = Box::from_raw(ptr as *mut List);
                 for &(ptr, dtor) in &*list {
                     dtor(ptr);
                 }
@@ -467,6 +468,7 @@ mod imp {
 mod imp {
     use prelude::v1::*;
 
+    use alloc::boxed;
     use cell::UnsafeCell;
     use mem;
     use ptr;
@@ -517,7 +519,7 @@ mod imp {
                 key: self,
                 value: mem::transmute_copy(&self.inner),
             };
-            let ptr: *mut Value<T> = mem::transmute(ptr);
+            let ptr: *mut Value<T> = boxed::into_raw(ptr);
             self.os.set(ptr as *mut u8);
             Some(&mut (*ptr).value as *mut T)
         }
@@ -533,7 +535,7 @@ mod imp {
         //
         // Note that to prevent an infinite loop we reset it back to null right
         // before we return from the destructor ourselves.
-        let ptr: Box<Value<T>> = mem::transmute(ptr);
+        let ptr: Box<Value<T>> = Box::from_raw(ptr as *mut Value<T>);
         let key = ptr.key;
         key.os.set(1 as *mut u8);
         drop(ptr);