about summary refs log tree commit diff
path: root/src/libstd/sys/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd/sys/windows')
-rw-r--r--src/libstd/sys/windows/thread.rs8
1 files changed, 5 insertions, 3 deletions
diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs
index c828243a59b..052f51a33ce 100644
--- a/src/libstd/sys/windows/thread.rs
+++ b/src/libstd/sys/windows/thread.rs
@@ -20,7 +20,7 @@ pub struct Thread {
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
     pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
-        let p = box p;
+        let mut p = mem::ManuallyDrop::new(box p);
 
         // FIXME On UNIX, we guard against stack sizes that are too small but
         // that's because pthreads enforces that stacks are at least
@@ -34,15 +34,17 @@ impl Thread {
             ptr::null_mut(),
             stack_size,
             thread_start,
-            &*p as *const _ as *mut _,
+            &mut *p as &mut Box<dyn FnOnce()> as *mut _ as *mut _,
             c::STACK_SIZE_PARAM_IS_A_RESERVATION,
             ptr::null_mut(),
         );
 
         return if ret as usize == 0 {
+            // The thread failed to start and as a result p was not consumed. Therefore, it is
+            // safe to manually drop it.
+            mem::ManuallyDrop::drop(&mut p);
             Err(io::Error::last_os_error())
         } else {
-            mem::forget(p); // ownership passed to CreateThread
             Ok(Thread { handle: Handle::new(ret) })
         };