Skip to content

Commit db04229

Browse files
committed
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.)
2 parents b2302a5 + 26d9f0a commit db04229

File tree

15 files changed

+65
-48
lines changed

15 files changed

+65
-48
lines changed

src/liballoc/boxed.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,16 @@ impl<T : ?Sized> Box<T> {
105105
/// After this function call, pointer is owned by resulting box.
106106
/// In particular, it means that `Box` destructor calls destructor
107107
/// of `T` and releases memory. Since the way `Box` allocates and
108-
/// releases memory is unspecified, so the only valid pointer to
109-
/// pass to this function is the one taken from another `Box` with
110-
/// `box::into_raw` function.
108+
/// releases memory is unspecified, the only valid pointer to pass
109+
/// to this function is the one taken from another `Box` with
110+
/// `boxed::into_raw` function.
111111
///
112112
/// Function is unsafe, because improper use of this function may
113113
/// lead to memory problems like double-free, for example if the
114114
/// function is called twice on the same raw pointer.
115115
#[unstable(feature = "alloc",
116116
reason = "may be renamed or moved out of Box scope")]
117+
#[inline]
117118
pub unsafe fn from_raw(raw: *mut T) -> Self {
118119
mem::transmute(raw)
119120
}
@@ -141,6 +142,7 @@ impl<T : ?Sized> Box<T> {
141142
/// ```
142143
#[unstable(feature = "alloc",
143144
reason = "may be renamed")]
145+
#[inline]
144146
pub unsafe fn into_raw<T : ?Sized>(b: Box<T>) -> *mut T {
145147
mem::transmute(b)
146148
}
@@ -248,11 +250,12 @@ impl BoxAny for Box<Any> {
248250
if self.is::<T>() {
249251
unsafe {
250252
// Get the raw representation of the trait object
253+
let raw = into_raw(self);
251254
let to: TraitObject =
252-
mem::transmute::<Box<Any>, TraitObject>(self);
255+
mem::transmute::<*mut Any, TraitObject>(raw);
253256

254257
// Extract the data pointer
255-
Ok(mem::transmute(to.data))
258+
Ok(Box::from_raw(to.data as *mut T))
256259
}
257260
} else {
258261
Err(self)

src/liballoc/rc.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,15 @@
144144
145145
#![stable(feature = "rust1", since = "1.0.0")]
146146

147+
use boxed;
147148
use core::cell::Cell;
148149
use core::clone::Clone;
149150
use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
150151
use core::default::Default;
151152
use core::fmt;
152153
use core::hash::{Hasher, Hash};
153154
use core::marker;
154-
use core::mem::{transmute, min_align_of, size_of, forget};
155+
use core::mem::{min_align_of, size_of, forget};
155156
use core::nonzero::NonZero;
156157
use core::ops::{Deref, Drop};
157158
use core::option::Option;
@@ -201,7 +202,7 @@ impl<T> Rc<T> {
201202
// there is an implicit weak pointer owned by all the strong pointers, which
202203
// ensures that the weak destructor never frees the allocation while the strong
203204
// destructor is running, even if the weak pointer is stored inside the strong one.
204-
_ptr: NonZero::new(transmute(box RcBox {
205+
_ptr: NonZero::new(boxed::into_raw(box RcBox {
205206
value: value,
206207
strong: Cell::new(1),
207208
weak: Cell::new(1)

src/libcollections/vec.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ impl<T> Vec<T> {
388388
pub fn into_boxed_slice(mut self) -> Box<[T]> {
389389
self.shrink_to_fit();
390390
unsafe {
391-
let xs: Box<[T]> = mem::transmute(&mut *self);
391+
let xs: Box<[T]> = Box::from_raw(&mut *self);
392392
mem::forget(self);
393393
xs
394394
}

src/liblog/lib.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@
167167
html_playground_url = "http://play.rust-lang.org/")]
168168
#![deny(missing_docs)]
169169

170+
#![feature(alloc)]
170171
#![feature(staged_api)]
171172
#![feature(box_syntax)]
172173
#![feature(int_uint)]
@@ -175,6 +176,7 @@
175176
#![feature(std_misc)]
176177
#![feature(env)]
177178

179+
use std::boxed;
178180
use std::cell::RefCell;
179181
use std::fmt;
180182
use std::old_io::LineBufferedWriter;
@@ -205,11 +207,11 @@ const DEFAULT_LOG_LEVEL: u32 = 1;
205207
/// logging statement should be run.
206208
static mut LOG_LEVEL: u32 = MAX_LOG_LEVEL;
207209

208-
static mut DIRECTIVES: *const Vec<directive::LogDirective> =
209-
0 as *const Vec<directive::LogDirective>;
210+
static mut DIRECTIVES: *mut Vec<directive::LogDirective> =
211+
0 as *mut Vec<directive::LogDirective>;
210212

211213
/// Optional filter.
212-
static mut FILTER: *const String = 0 as *const _;
214+
static mut FILTER: *mut String = 0 as *mut _;
213215

214216
/// Debug log level
215217
pub const DEBUG: u32 = 4;
@@ -419,23 +421,23 @@ fn init() {
419421

420422
assert!(FILTER.is_null());
421423
match filter {
422-
Some(f) => FILTER = mem::transmute(box f),
424+
Some(f) => FILTER = boxed::into_raw(box f),
423425
None => {}
424426
}
425427

426428
assert!(DIRECTIVES.is_null());
427-
DIRECTIVES = mem::transmute(box directives);
429+
DIRECTIVES = boxed::into_raw(box directives);
428430

429431
// Schedule the cleanup for the globals for when the runtime exits.
430432
rt::at_exit(move || {
431433
assert!(!DIRECTIVES.is_null());
432434
let _directives: Box<Vec<directive::LogDirective>> =
433-
mem::transmute(DIRECTIVES);
434-
DIRECTIVES = ptr::null();
435+
Box::from_raw(DIRECTIVES);
436+
DIRECTIVES = ptr::null_mut();
435437

436438
if !FILTER.is_null() {
437-
let _filter: Box<String> = mem::transmute(FILTER);
438-
FILTER = 0 as *const _;
439+
let _filter: Box<String> = Box::from_raw(FILTER);
440+
FILTER = 0 as *mut _;
439441
}
440442
});
441443
}

src/libstd/old_io/stdio.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
2828
use self::StdSource::*;
2929

30+
use boxed;
3031
use boxed::Box;
3132
use cell::RefCell;
3233
use clone::Clone;
@@ -218,7 +219,7 @@ impl Reader for StdinReader {
218219
/// See `stdout()` for more notes about this function.
219220
pub fn stdin() -> StdinReader {
220221
// We're following the same strategy as kimundi's lazy_static library
221-
static mut STDIN: *const StdinReader = 0 as *const StdinReader;
222+
static mut STDIN: *mut StdinReader = 0 as *mut StdinReader;
222223
static ONCE: Once = ONCE_INIT;
223224

224225
unsafe {
@@ -235,12 +236,12 @@ pub fn stdin() -> StdinReader {
235236
let stdin = StdinReader {
236237
inner: Arc::new(Mutex::new(RaceBox(stdin)))
237238
};
238-
STDIN = mem::transmute(box stdin);
239+
STDIN = boxed::into_raw(box stdin);
239240

240241
// Make sure to free it at exit
241242
rt::at_exit(|| {
242-
mem::transmute::<_, Box<StdinReader>>(STDIN);
243-
STDIN = ptr::null();
243+
Box::from_raw(STDIN);
244+
STDIN = ptr::null_mut();
244245
});
245246
});
246247

src/libstd/rt/at_exit_imp.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
1515
use core::prelude::*;
1616

17+
use boxed;
1718
use boxed::Box;
1819
use vec::Vec;
19-
use mem;
2020
use thunk::Thunk;
2121
use sys_common::mutex::{Mutex, MUTEX_INIT};
2222

@@ -32,7 +32,7 @@ static mut QUEUE: *mut Queue = 0 as *mut Queue;
3232
unsafe fn init() {
3333
if QUEUE.is_null() {
3434
let state: Box<Queue> = box Vec::new();
35-
QUEUE = mem::transmute(state);
35+
QUEUE = boxed::into_raw(state);
3636
} else {
3737
// can't re-init after a cleanup
3838
rtassert!(QUEUE as uint != 1);
@@ -57,7 +57,7 @@ pub fn cleanup() {
5757

5858
// If we never called init, not need to cleanup!
5959
if queue as uint != 0 {
60-
let queue: Box<Queue> = mem::transmute(queue);
60+
let queue: Box<Queue> = Box::from_raw(queue);
6161
for to_run in *queue {
6262
to_run.invoke(());
6363
}

src/libstd/rt/unwind.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
use prelude::v1::*;
6161

6262
use any::Any;
63+
use boxed;
6364
use cell::Cell;
6465
use cmp;
6566
use panicking;
@@ -173,15 +174,16 @@ fn rust_panic(cause: Box<Any + Send + 'static>) -> ! {
173174
},
174175
cause: Some(cause),
175176
};
176-
let error = uw::_Unwind_RaiseException(mem::transmute(exception));
177+
let exception_param = boxed::into_raw(exception) as *mut uw::_Unwind_Exception;
178+
let error = uw::_Unwind_RaiseException(exception_param);
177179
rtabort!("Could not unwind stack, error = {}", error as int)
178180
}
179181

180182
extern fn exception_cleanup(_unwind_code: uw::_Unwind_Reason_Code,
181183
exception: *mut uw::_Unwind_Exception) {
182184
rtdebug!("exception_cleanup()");
183185
unsafe {
184-
let _: Box<Exception> = mem::transmute(exception);
186+
let _: Box<Exception> = Box::from_raw(exception as *mut Exception);
185187
}
186188
}
187189
}

src/libstd/sync/mpsc/mpsc_queue.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ pub use self::PopResult::*;
4444

4545
use core::prelude::*;
4646

47+
use alloc::boxed;
4748
use alloc::boxed::Box;
48-
use core::mem;
4949
use core::ptr;
5050
use core::cell::UnsafeCell;
5151

@@ -82,7 +82,7 @@ unsafe impl<T: Send> Sync for Queue<T> { }
8282

8383
impl<T> Node<T> {
8484
unsafe fn new(v: Option<T>) -> *mut Node<T> {
85-
mem::transmute(box Node {
85+
boxed::into_raw(box Node {
8686
next: AtomicPtr::new(ptr::null_mut()),
8787
value: v,
8888
})
@@ -129,7 +129,7 @@ impl<T: Send> Queue<T> {
129129
assert!((*tail).value.is_none());
130130
assert!((*next).value.is_some());
131131
let ret = (*next).value.take().unwrap();
132-
let _: Box<Node<T>> = mem::transmute(tail);
132+
let _: Box<Node<T>> = Box::from_raw(tail);
133133
return Data(ret);
134134
}
135135

@@ -146,7 +146,7 @@ impl<T: Send> Drop for Queue<T> {
146146
let mut cur = *self.tail.get();
147147
while !cur.is_null() {
148148
let next = (*cur).next.load(Ordering::Relaxed);
149-
let _: Box<Node<T>> = mem::transmute(cur);
149+
let _: Box<Node<T>> = Box::from_raw(cur);
150150
cur = next;
151151
}
152152
}

src/libstd/sync/mpsc/spsc_queue.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737

3838
use core::prelude::*;
3939

40+
use alloc::boxed;
4041
use alloc::boxed::Box;
41-
use core::mem;
4242
use core::ptr;
4343
use core::cell::UnsafeCell;
4444

@@ -81,7 +81,7 @@ unsafe impl<T: Send> Sync for Queue<T> { }
8181
impl<T: Send> Node<T> {
8282
fn new() -> *mut Node<T> {
8383
unsafe {
84-
mem::transmute(box Node {
84+
boxed::into_raw(box Node {
8585
value: None,
8686
next: AtomicPtr::new(ptr::null_mut::<Node<T>>()),
8787
})
@@ -200,7 +200,7 @@ impl<T: Send> Queue<T> {
200200
.next.store(next, Ordering::Relaxed);
201201
// We have successfully erased all references to 'tail', so
202202
// now we can safely drop it.
203-
let _: Box<Node<T>> = mem::transmute(tail);
203+
let _: Box<Node<T>> = Box::from_raw(tail);
204204
}
205205
}
206206
return ret;
@@ -233,7 +233,7 @@ impl<T: Send> Drop for Queue<T> {
233233
let mut cur = *self.first.get();
234234
while !cur.is_null() {
235235
let next = (*cur).next.load(Ordering::Relaxed);
236-
let _n: Box<Node<T>> = mem::transmute(cur);
236+
let _n: Box<Node<T>> = Box::from_raw(cur);
237237
cur = next;
238238
}
239239
}

src/libstd/sys/common/helper_thread.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
2323
use prelude::v1::*;
2424

25+
use boxed;
2526
use cell::UnsafeCell;
26-
use mem;
2727
use ptr;
2828
use rt;
2929
use sync::{StaticMutex, StaticCondvar};
@@ -88,7 +88,7 @@ impl<M: Send> Helper<M> {
8888
let _guard = self.lock.lock().unwrap();
8989
if !*self.initialized.get() {
9090
let (tx, rx) = channel();
91-
*self.chan.get() = mem::transmute(box tx);
91+
*self.chan.get() = boxed::into_raw(box tx);
9292
let (receive, send) = helper_signal::new();
9393
*self.signal.get() = send as uint;
9494

@@ -132,7 +132,7 @@ impl<M: Send> Helper<M> {
132132
let mut guard = self.lock.lock().unwrap();
133133

134134
// Close the channel by destroying it
135-
let chan: Box<Sender<M>> = mem::transmute(*self.chan.get());
135+
let chan: Box<Sender<M>> = Box::from_raw(*self.chan.get());
136136
*self.chan.get() = ptr::null_mut();
137137
drop(chan);
138138
helper_signal::signal(*self.signal.get() as helper_signal::signal);

src/libstd/sys/common/thread.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub fn start_thread(main: *mut libc::c_void) -> thread::rust_thread_return {
2727
unsafe {
2828
stack::record_os_managed_stack_bounds(0, usize::MAX);
2929
let handler = stack_overflow::Handler::new();
30-
let f: Box<Thunk> = mem::transmute(main);
30+
let f: Box<Thunk> = Box::from_raw(main as *mut Thunk);
3131
f.invoke(());
3232
drop(handler);
3333
mem::transmute(0 as thread::rust_thread_return)

src/libstd/sys/unix/thread.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use core::prelude::*;
1212

1313
use io;
14+
use boxed;
1415
use boxed::Box;
1516
use cmp;
1617
use mem;
@@ -241,13 +242,15 @@ pub unsafe fn create(stack: uint, p: Thunk) -> io::Result<rust_thread> {
241242
},
242243
};
243244

244-
let arg: *mut libc::c_void = mem::transmute(box p); // must box since sizeof(p)=2*uint
245+
// must box since sizeof(p)=2*uint
246+
let raw_p = boxed::into_raw(box p);
247+
let arg = raw_p as *mut libc::c_void;
245248
let ret = pthread_create(&mut native, &attr, thread_start, arg);
246249
assert_eq!(pthread_attr_destroy(&mut attr), 0);
247250

248251
if ret != 0 {
249252
// be sure to not leak the closure
250-
let _p: Box<Box<FnOnce()+Send>> = mem::transmute(arg);
253+
let _p: Box<Thunk> = Box::from_raw(raw_p);
251254
Err(io::Error::from_os_error(ret))
252255
} else {
253256
Ok(native)

src/libstd/sys/windows/thread.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
use prelude::v1::*;
1212

13+
use boxed;
14+
use boxed::Box;
1315
use cmp;
1416
use io;
1517
use mem;
@@ -45,7 +47,8 @@ pub mod guard {
4547
}
4648

4749
pub unsafe fn create(stack: uint, p: Thunk) -> io::Result<rust_thread> {
48-
let arg: *mut libc::c_void = mem::transmute(box p);
50+
let raw_p = boxed::into_raw(box p);
51+
let arg = raw_p as *mut libc::c_void;
4952
// FIXME On UNIX, we guard against stack sizes that are too small but
5053
// that's because pthreads enforces that stacks are at least
5154
// 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> {
6164

6265
if ret as uint == 0 {
6366
// be sure to not leak the closure
64-
let _p: Box<Thunk> = mem::transmute(arg);
67+
let _p: Box<Thunk> = Box::from_raw(raw_p);
6568
Err(io::Error::last_os_error())
6669
} else {
6770
Ok(ret)

0 commit comments

Comments
 (0)