Skip to content

Commit 193574a

Browse files
committed
auto merge of #14529 : brson/rust/ptr, r=brson
This time we're not promoting anything directly to 'stable', but instead promoting functions we're happy with to 'unstable'. They'll become stable in another pass later. * null and mut_null are unstable. Their names may change if the unsafe pointer types change. * copy_memory and copy_overlapping_memory are unstable. We think they aren't going to change. * set_memory and zero_memory are experimental. Both the names and the semantics are under question. * swap and replace are unstable and probably won't change. * read is unstable, probably won't change * read_and_zero is experimental. It's necessity is in doubt. * mem::overwrite is now called ptr::write to match read and is unstable. mem::overwrite is now deprecated * array_each, array_each_with_len, buf_len, and position are all deprecated because they use old style iteration and their utility is generally under question. Note that `mem::overwrite`, which was just declared stable last week, is deprecated now in favor of `ptr::write`. Woo!
2 parents aa09561 + 9b228f8 commit 193574a

File tree

7 files changed

+80
-48
lines changed

7 files changed

+80
-48
lines changed

src/doc/guide-unsafe.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,14 +213,14 @@ pub struct Unique<T> {
213213
impl<T: Send> Unique<T> {
214214
pub fn new(value: T) -> Unique<T> {
215215
unsafe {
216-
let ptr = malloc(std::mem::size_of::<T>() as size_t) as *mut T;
216+
let ptr = malloc(mem::size_of::<T>() as size_t) as *mut T;
217217
// we *need* valid pointer.
218218
assert!(!ptr.is_null());
219219
// `*ptr` is uninitialized, and `*ptr = value` would
220220
// attempt to destroy it `overwrite` moves a value into
221221
// this memory without attempting to drop the original
222222
// value.
223-
mem::overwrite(&mut *ptr, value);
223+
ptr::write(&mut *ptr, value);
224224
Unique{ptr: ptr}
225225
}
226226
}

src/libarena/lib.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use std::intrinsics::{TyDesc, get_tydesc};
3636
use std::intrinsics;
3737
use std::mem;
3838
use std::num;
39-
use std::ptr::read;
39+
use std::ptr;
4040
use std::rc::Rc;
4141
use std::rt::heap::allocate;
4242

@@ -209,7 +209,7 @@ impl Arena {
209209
let ptr = self.alloc_copy_inner(mem::size_of::<T>(),
210210
mem::min_align_of::<T>());
211211
let ptr = ptr as *mut T;
212-
mem::overwrite(&mut (*ptr), op());
212+
ptr::write(&mut (*ptr), op());
213213
return &*ptr;
214214
}
215215
}
@@ -262,7 +262,7 @@ impl Arena {
262262
// has *not* been initialized yet.
263263
*ty_ptr = mem::transmute(tydesc);
264264
// Actually initialize it
265-
mem::overwrite(&mut(*ptr), op());
265+
ptr::write(&mut(*ptr), op());
266266
// Now that we are done, update the tydesc to indicate that
267267
// the object is there.
268268
*ty_ptr = bitpack_tydesc_ptr(tydesc, true);
@@ -360,7 +360,7 @@ impl<T> TypedArenaChunk<T> {
360360
let mut chunk = unsafe {
361361
let chunk = allocate(size, mem::min_align_of::<TypedArenaChunk<T>>());
362362
let mut chunk: Box<TypedArenaChunk<T>> = mem::transmute(chunk);
363-
mem::overwrite(&mut chunk.next, next);
363+
ptr::write(&mut chunk.next, next);
364364
chunk
365365
};
366366

@@ -376,7 +376,7 @@ impl<T> TypedArenaChunk<T> {
376376
if intrinsics::needs_drop::<T>() {
377377
let mut start = self.start();
378378
for _ in range(0, len) {
379-
read(start as *T); // run the destructor on the pointer
379+
ptr::read(start as *T); // run the destructor on the pointer
380380
start = start.offset(mem::size_of::<T>() as int)
381381
}
382382
}
@@ -442,7 +442,7 @@ impl<T> TypedArena<T> {
442442
}
443443

444444
let ptr: &'a mut T = mem::transmute(this.ptr);
445-
mem::overwrite(ptr, object);
445+
ptr::write(ptr, object);
446446
this.ptr = this.ptr.offset(1);
447447
let ptr: &'a T = ptr;
448448
ptr

src/libcollections/priority_queue.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
#![allow(missing_doc)]
1414

1515
use std::clone::Clone;
16-
use std::mem::{overwrite, zeroed, replace, swap};
16+
use std::mem::{zeroed, replace, swap};
17+
use std::ptr;
1718
use std::slice;
1819

1920
/// A priority queue implemented with a binary heap
@@ -163,13 +164,13 @@ impl<T: Ord> PriorityQueue<T> {
163164
let parent = (pos - 1) >> 1;
164165
if new > *self.data.get(parent) {
165166
let x = replace(self.data.get_mut(parent), zeroed());
166-
overwrite(self.data.get_mut(pos), x);
167+
ptr::write(self.data.get_mut(pos), x);
167168
pos = parent;
168169
continue
169170
}
170171
break
171172
}
172-
overwrite(self.data.get_mut(pos), new);
173+
ptr::write(self.data.get_mut(pos), new);
173174
}
174175
}
175176

@@ -185,12 +186,12 @@ impl<T: Ord> PriorityQueue<T> {
185186
child = right;
186187
}
187188
let x = replace(self.data.get_mut(child), zeroed());
188-
overwrite(self.data.get_mut(pos), x);
189+
ptr::write(self.data.get_mut(pos), x);
189190
pos = child;
190191
child = 2 * pos + 1;
191192
}
192193

193-
overwrite(self.data.get_mut(pos), new);
194+
ptr::write(self.data.get_mut(pos), new);
194195
self.siftup(start, pos);
195196
}
196197
}

src/libcore/mem.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,16 +155,16 @@ pub unsafe fn uninit<T>() -> T {
155155
/// contained at the location `dst`. This could leak allocations or resources,
156156
/// so care must be taken to previously deallocate the value at `dst`.
157157
#[inline]
158-
#[stable]
158+
#[deprecated = "use ptr::write"]
159159
pub unsafe fn overwrite<T>(dst: *mut T, src: T) {
160160
intrinsics::move_val_init(&mut *dst, src)
161161
}
162162

163163
/// Deprecated, use `overwrite` instead
164164
#[inline]
165-
#[deprecated = "this function has been renamed to `overwrite`"]
165+
#[deprecated = "use ptr::write"]
166166
pub unsafe fn move_val_init<T>(dst: &mut T, src: T) {
167-
overwrite(dst, src)
167+
ptr::write(dst, src)
168168
}
169169

170170
/// Convert an u16 to little endian from the target's endianness.

src/libcore/ptr.rs

Lines changed: 60 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -95,36 +95,6 @@ use option::{Some, None, Option};
9595

9696
#[cfg(not(test))] use cmp::{PartialEq, Eq, PartialOrd, Equiv};
9797

98-
/// Return the offset of the first null pointer in `buf`.
99-
#[inline]
100-
pub unsafe fn buf_len<T>(buf: **T) -> uint {
101-
position(buf, |i| *i == null())
102-
}
103-
104-
impl<T> Clone for *T {
105-
#[inline]
106-
fn clone(&self) -> *T {
107-
*self
108-
}
109-
}
110-
111-
impl<T> Clone for *mut T {
112-
#[inline]
113-
fn clone(&self) -> *mut T {
114-
*self
115-
}
116-
}
117-
118-
/// Return the first offset `i` such that `f(buf[i]) == true`.
119-
#[inline]
120-
pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
121-
let mut i = 0;
122-
loop {
123-
if f(&(*buf.offset(i as int))) { return i; }
124-
else { i += 1; }
125-
}
126-
}
127-
12898
/// Create a null pointer.
12999
///
130100
/// # Example
@@ -136,6 +106,7 @@ pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
136106
/// assert!(p.is_null());
137107
/// ```
138108
#[inline]
109+
#[unstable = "may need a different name after pending changes to pointer types"]
139110
pub fn null<T>() -> *T { 0 as *T }
140111

141112
/// Create an unsafe mutable null pointer.
@@ -149,6 +120,7 @@ pub fn null<T>() -> *T { 0 as *T }
149120
/// assert!(p.is_null());
150121
/// ```
151122
#[inline]
123+
#[unstable = "may need a different name after pending changes to pointer types"]
152124
pub fn mut_null<T>() -> *mut T { 0 as *mut T }
153125

154126
/// Copies data from one location to another.
@@ -174,6 +146,7 @@ pub fn mut_null<T>() -> *mut T { 0 as *mut T }
174146
/// ```
175147
///
176148
#[inline]
149+
#[unstable]
177150
pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
178151
intrinsics::copy_memory(dst, src, count)
179152
}
@@ -215,6 +188,7 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
215188
/// If the source and destination overlap then the behavior of this
216189
/// function is undefined.
217190
#[inline]
191+
#[unstable]
218192
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
219193
src: *T,
220194
count: uint) {
@@ -224,19 +198,23 @@ pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
224198
/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
225199
/// bytes of memory starting at `dst` to `c`.
226200
#[inline]
201+
#[experimental = "uncertain about naming and semantics"]
227202
pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
228203
intrinsics::set_memory(dst, c, count)
229204
}
230205

231206
/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
232207
#[inline]
208+
#[experimental = "uncertain about naming and semantics"]
209+
#[allow(experimental)]
233210
pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
234211
set_memory(dst, 0, count);
235212
}
236213

237214
/// Swap the values at two mutable locations of the same type, without
238215
/// deinitialising either. They may overlap.
239216
#[inline]
217+
#[unstable]
240218
pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
241219
// Give ourselves some scratch space to work with
242220
let mut tmp: T = mem::uninitialized();
@@ -255,13 +233,15 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
255233
/// Replace the value at a mutable location with a new one, returning the old
256234
/// value, without deinitialising either.
257235
#[inline]
236+
#[unstable]
258237
pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
259238
mem::swap(mem::transmute(dest), &mut src); // cannot overlap
260239
src
261240
}
262241

263242
/// Reads the value from `*src` and returns it.
264243
#[inline(always)]
244+
#[unstable]
265245
pub unsafe fn read<T>(src: *T) -> T {
266246
let mut tmp: T = mem::uninitialized();
267247
copy_nonoverlapping_memory(&mut tmp, src, 1);
@@ -271,6 +251,8 @@ pub unsafe fn read<T>(src: *T) -> T {
271251
/// Reads the value from `*src` and nulls it out.
272252
/// This currently prevents destructors from executing.
273253
#[inline(always)]
254+
#[experimental]
255+
#[allow(experimental)]
274256
pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
275257
// Copy the data out from `dest`:
276258
let tmp = read(&*dest);
@@ -281,9 +263,22 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
281263
tmp
282264
}
283265

266+
/// Unsafely overwrite a memory location with the given value without destroying
267+
/// the old value.
268+
///
269+
/// This operation is unsafe because it does not destroy the previous value
270+
/// contained at the location `dst`. This could leak allocations or resources,
271+
/// so care must be taken to previously deallocate the value at `dst`.
272+
#[inline]
273+
#[unstable]
274+
pub unsafe fn write<T>(dst: *mut T, src: T) {
275+
intrinsics::move_val_init(&mut *dst, src)
276+
}
277+
284278
/// Given a **T (pointer to an array of pointers),
285279
/// iterate through each *T, up to the provided `len`,
286280
/// passing to the provided callback function
281+
#[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
287282
pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
288283
if arr.is_null() {
289284
fail!("ptr::array_each_with_len failure: arr input is null pointer");
@@ -303,6 +298,8 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
303298
///
304299
/// This will only work with a null-terminated
305300
/// pointer array.
301+
#[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
302+
#[allow(deprecated)]
306303
pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
307304
if arr.is_null() {
308305
fail!("ptr::array_each_with_len failure: arr input is null pointer");
@@ -311,6 +308,25 @@ pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
311308
array_each_with_len(arr, len, cb);
312309
}
313310

311+
/// Return the offset of the first null pointer in `buf`.
312+
#[inline]
313+
#[deprecated = "use a loop and RawPtr::offset"]
314+
#[allow(deprecated)]
315+
pub unsafe fn buf_len<T>(buf: **T) -> uint {
316+
position(buf, |i| *i == null())
317+
}
318+
319+
/// Return the first offset `i` such that `f(buf[i]) == true`.
320+
#[inline]
321+
#[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
322+
pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
323+
let mut i = 0;
324+
loop {
325+
if f(&(*buf.offset(i as int))) { return i; }
326+
else { i += 1; }
327+
}
328+
}
329+
314330
/// Methods on raw pointers
315331
pub trait RawPtr<T> {
316332
/// Returns the null pointer.
@@ -426,6 +442,20 @@ impl<T> Equiv<*T> for *mut T {
426442
}
427443
}
428444

445+
impl<T> Clone for *T {
446+
#[inline]
447+
fn clone(&self) -> *T {
448+
*self
449+
}
450+
}
451+
452+
impl<T> Clone for *mut T {
453+
#[inline]
454+
fn clone(&self) -> *mut T {
455+
*self
456+
}
457+
}
458+
429459
// Equality for extern "C" fn pointers
430460
#[cfg(not(test))]
431461
mod externfnpointers {

src/libcore/should_not_exist.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl<A: Clone> Clone for ~[A] {
7777
try_finally(
7878
&mut i, (),
7979
|i, ()| while *i < len {
80-
mem::overwrite(
80+
ptr::write(
8181
&mut(*p.offset(*i as int)),
8282
self.unsafe_ref(*i).clone());
8383
*i += 1;

src/libcore/slice.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1093,7 +1093,7 @@ impl<'a,T> MutableVector<'a, T> for &'a mut [T] {
10931093

10941094
#[inline]
10951095
unsafe fn init_elem(self, i: uint, val: T) {
1096-
mem::overwrite(&mut (*self.as_mut_ptr().offset(i as int)), val);
1096+
ptr::write(&mut (*self.as_mut_ptr().offset(i as int)), val);
10971097
}
10981098

10991099
#[inline]
@@ -1218,6 +1218,7 @@ pub mod bytes {
12181218

12191219
impl<'a> MutableByteVector for &'a mut [u8] {
12201220
#[inline]
1221+
#[allow(experimental)]
12211222
fn set_memory(self, value: u8) {
12221223
unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) };
12231224
}

0 commit comments

Comments
 (0)