Rollup merge of #22696 - stepancheg:use-box, r=alexcrichton
e. g. ``` let b: Box<Foo> = Box::from_raw(p); ``` instead of ``` let b: Box<Foo> = mem::transmute(p); ``` Patch also changes closure release code in `src/libstd/sys/unix/thread.rs` when `pthread_create` failed. Raw pointer was transmuted to box of `FnOnce()` instead of `Thunk`. This code was probably never executed, because `pthread_create` rarely fails. (And there are two more patches in PR: fix typo in doc and mark `from_raw` and `into_raw` functions inline.)
This commit is contained in:
commit
db04229d23
@ -105,15 +105,16 @@ impl<T : ?Sized> Box<T> {
|
||||
/// After this function call, pointer is owned by resulting box.
|
||||
/// In particular, it means that `Box` destructor calls destructor
|
||||
/// of `T` and releases memory. Since the way `Box` allocates and
|
||||
/// releases memory is unspecified, so the only valid pointer to
|
||||
/// pass to this function is the one taken from another `Box` with
|
||||
/// `box::into_raw` function.
|
||||
/// releases memory is unspecified, the only valid pointer to pass
|
||||
/// to this function is the one taken from another `Box` with
|
||||
/// `boxed::into_raw` function.
|
||||
///
|
||||
/// Function is unsafe, because improper use of this function may
|
||||
/// lead to memory problems like double-free, for example if the
|
||||
/// function is called twice on the same raw pointer.
|
||||
#[unstable(feature = "alloc",
|
||||
reason = "may be renamed or moved out of Box scope")]
|
||||
#[inline]
|
||||
pub unsafe fn from_raw(raw: *mut T) -> Self {
|
||||
mem::transmute(raw)
|
||||
}
|
||||
@ -141,6 +142,7 @@ impl<T : ?Sized> Box<T> {
|
||||
/// ```
|
||||
#[unstable(feature = "alloc",
|
||||
reason = "may be renamed")]
|
||||
#[inline]
|
||||
pub unsafe fn into_raw<T : ?Sized>(b: Box<T>) -> *mut T {
|
||||
mem::transmute(b)
|
||||
}
|
||||
@ -248,11 +250,12 @@ impl BoxAny for Box<Any> {
|
||||
if self.is::<T>() {
|
||||
unsafe {
|
||||
// Get the raw representation of the trait object
|
||||
let raw = into_raw(self);
|
||||
let to: TraitObject =
|
||||
mem::transmute::<Box<Any>, TraitObject>(self);
|
||||
mem::transmute::<*mut Any, TraitObject>(raw);
|
||||
|
||||
// Extract the data pointer
|
||||
Ok(mem::transmute(to.data))
|
||||
Ok(Box::from_raw(to.data as *mut T))
|
||||
}
|
||||
} else {
|
||||
Err(self)
|
||||
|
@ -144,6 +144,7 @@
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use boxed;
|
||||
use core::cell::Cell;
|
||||
use core::clone::Clone;
|
||||
use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
|
||||
@ -151,7 +152,7 @@ use core::default::Default;
|
||||
use core::fmt;
|
||||
use core::hash::{Hasher, Hash};
|
||||
use core::marker;
|
||||
use core::mem::{transmute, min_align_of, size_of, forget};
|
||||
use core::mem::{min_align_of, size_of, forget};
|
||||
use core::nonzero::NonZero;
|
||||
use core::ops::{Deref, Drop};
|
||||
use core::option::Option;
|
||||
@ -201,7 +202,7 @@ impl<T> Rc<T> {
|
||||
// there is an implicit weak pointer owned by all the strong pointers, which
|
||||
// ensures that the weak destructor never frees the allocation while the strong
|
||||
// destructor is running, even if the weak pointer is stored inside the strong one.
|
||||
_ptr: NonZero::new(transmute(box RcBox {
|
||||
_ptr: NonZero::new(boxed::into_raw(box RcBox {
|
||||
value: value,
|
||||
strong: Cell::new(1),
|
||||
weak: Cell::new(1)
|
||||
|
@ -388,7 +388,7 @@ impl<T> Vec<T> {
|
||||
pub fn into_boxed_slice(mut self) -> Box<[T]> {
|
||||
self.shrink_to_fit();
|
||||
unsafe {
|
||||
let xs: Box<[T]> = mem::transmute(&mut *self);
|
||||
let xs: Box<[T]> = Box::from_raw(&mut *self);
|
||||
mem::forget(self);
|
||||
xs
|
||||
}
|
||||
|
@ -167,6 +167,7 @@
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![deny(missing_docs)]
|
||||
|
||||
#![feature(alloc)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(int_uint)]
|
||||
@ -175,6 +176,7 @@
|
||||
#![feature(std_misc)]
|
||||
#![feature(env)]
|
||||
|
||||
use std::boxed;
|
||||
use std::cell::RefCell;
|
||||
use std::fmt;
|
||||
use std::old_io::LineBufferedWriter;
|
||||
@ -205,11 +207,11 @@ const DEFAULT_LOG_LEVEL: u32 = 1;
|
||||
/// logging statement should be run.
|
||||
static mut LOG_LEVEL: u32 = MAX_LOG_LEVEL;
|
||||
|
||||
static mut DIRECTIVES: *const Vec<directive::LogDirective> =
|
||||
0 as *const Vec<directive::LogDirective>;
|
||||
static mut DIRECTIVES: *mut Vec<directive::LogDirective> =
|
||||
0 as *mut Vec<directive::LogDirective>;
|
||||
|
||||
/// Optional filter.
|
||||
static mut FILTER: *const String = 0 as *const _;
|
||||
static mut FILTER: *mut String = 0 as *mut _;
|
||||
|
||||
/// Debug log level
|
||||
pub const DEBUG: u32 = 4;
|
||||
@ -419,23 +421,23 @@ fn init() {
|
||||
|
||||
assert!(FILTER.is_null());
|
||||
match filter {
|
||||
Some(f) => FILTER = mem::transmute(box f),
|
||||
Some(f) => FILTER = boxed::into_raw(box f),
|
||||
None => {}
|
||||
}
|
||||
|
||||
assert!(DIRECTIVES.is_null());
|
||||
DIRECTIVES = mem::transmute(box directives);
|
||||
DIRECTIVES = boxed::into_raw(box directives);
|
||||
|
||||
// Schedule the cleanup for the globals for when the runtime exits.
|
||||
rt::at_exit(move || {
|
||||
assert!(!DIRECTIVES.is_null());
|
||||
let _directives: Box<Vec<directive::LogDirective>> =
|
||||
mem::transmute(DIRECTIVES);
|
||||
DIRECTIVES = ptr::null();
|
||||
Box::from_raw(DIRECTIVES);
|
||||
DIRECTIVES = ptr::null_mut();
|
||||
|
||||
if !FILTER.is_null() {
|
||||
let _filter: Box<String> = mem::transmute(FILTER);
|
||||
FILTER = 0 as *const _;
|
||||
let _filter: Box<String> = Box::from_raw(FILTER);
|
||||
FILTER = 0 as *mut _;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -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(());
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
use prelude::v1::*;
|
||||
|
||||
use boxed;
|
||||
use boxed::Box;
|
||||
use cmp;
|
||||
use io;
|
||||
use mem;
|
||||
@ -45,7 +47,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 +64,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)
|
||||
|
@ -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);
|
||||
Boxed::from_raw(dtors);
|
||||
assert!(DTORS.is_null()); // can't re-init after destructing
|
||||
DTOR_LOCK.unlock();
|
||||
});
|
||||
|
@ -330,6 +330,7 @@ impl<T: 'static> Key<T> {
|
||||
mod imp {
|
||||
use prelude::v1::*;
|
||||
|
||||
use alloc::boxed;
|
||||
use cell::UnsafeCell;
|
||||
use intrinsics;
|
||||
use ptr;
|
||||
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user