Skip to content

Commit f3a87a7

Browse files
committed
auto merge of #12143 : brson/rust/swap, r=alexcrichton
Thinking about swap as an example of unsafe programming. This cleans it up a bit. It also removes type parametrization over `RawPtr` from the memcpy functions to make this compile.
2 parents 5bad63c + 07c5e5d commit f3a87a7

File tree

4 files changed

+24
-28
lines changed

4 files changed

+24
-28
lines changed

src/libstd/cast.rs

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

1111
//! Unsafe casting functions
1212
13-
use ptr::RawPtr;
1413
use mem;
1514
use unstable::intrinsics;
1615
use ptr::copy_nonoverlapping_memory;
@@ -72,13 +71,13 @@ pub unsafe fn transmute_region<'a,'b,T>(ptr: &'a T) -> &'b T {
7271

7372
/// Coerce an immutable reference to be mutable.
7473
#[inline]
75-
pub unsafe fn transmute_mut_unsafe<T,P:RawPtr<T>>(ptr: P) -> *mut T {
74+
pub unsafe fn transmute_mut_unsafe<T>(ptr: *T) -> *mut T {
7675
transmute(ptr)
7776
}
7877

7978
/// Coerce an immutable reference to be mutable.
8079
#[inline]
81-
pub unsafe fn transmute_immut_unsafe<T,P:RawPtr<T>>(ptr: P) -> *T {
80+
pub unsafe fn transmute_immut_unsafe<T>(ptr: *mut T) -> *T {
8281
transmute(ptr)
8382
}
8483

src/libstd/ptr.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ pub fn is_not_null<T,P:RawPtr<T>>(ptr: P) -> bool { ptr.is_not_null() }
9292
* and destination may overlap.
9393
*/
9494
#[inline]
95-
pub unsafe fn copy_memory<T,P:RawPtr<T>>(dst: *mut T, src: P, count: uint) {
96-
intrinsics::copy_memory(dst, cast::transmute_immut_unsafe(src), count)
95+
pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
96+
intrinsics::copy_memory(dst, src, count)
9797
}
9898

9999
/**
@@ -103,10 +103,10 @@ pub unsafe fn copy_memory<T,P:RawPtr<T>>(dst: *mut T, src: P, count: uint) {
103103
* and destination may *not* overlap.
104104
*/
105105
#[inline]
106-
pub unsafe fn copy_nonoverlapping_memory<T,P:RawPtr<T>>(dst: *mut T,
107-
src: P,
108-
count: uint) {
109-
intrinsics::copy_nonoverlapping_memory(dst, cast::transmute_immut_unsafe(src), count)
106+
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
107+
src: *T,
108+
count: uint) {
109+
intrinsics::copy_nonoverlapping_memory(dst, src, count)
110110
}
111111

112112
/**
@@ -137,9 +137,9 @@ pub unsafe fn swap_ptr<T>(x: *mut T, y: *mut T) {
137137
let t: *mut T = &mut tmp;
138138

139139
// Perform the swap
140-
copy_nonoverlapping_memory(t, x, 1);
141-
copy_memory(x, y, 1); // `x` and `y` may overlap
142-
copy_nonoverlapping_memory(y, t, 1);
140+
copy_nonoverlapping_memory(t, &*x, 1);
141+
copy_memory(x, &*y, 1); // `x` and `y` may overlap
142+
copy_nonoverlapping_memory(y, &*t, 1);
143143

144144
// y and t now point to the same thing, but we need to completely forget `tmp`
145145
// because it's no longer relevant.

src/libstd/util.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,16 @@ pub fn id<T>(x: T) -> T { x }
2626
pub fn swap<T>(x: &mut T, y: &mut T) {
2727
unsafe {
2828
// Give ourselves some scratch space to work with
29-
let mut tmp: T = mem::uninit();
30-
let t: *mut T = &mut tmp;
29+
let mut t: T = mem::uninit();
3130

3231
// Perform the swap, `&mut` pointers never alias
33-
let x_raw: *mut T = x;
34-
let y_raw: *mut T = y;
35-
ptr::copy_nonoverlapping_memory(t, x_raw, 1);
36-
ptr::copy_nonoverlapping_memory(x, y_raw, 1);
37-
ptr::copy_nonoverlapping_memory(y, t, 1);
32+
ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
33+
ptr::copy_nonoverlapping_memory(x, &*y, 1);
34+
ptr::copy_nonoverlapping_memory(y, &t, 1);
3835

3936
// y and t now point to the same thing, but we need to completely forget `tmp`
4037
// because it's no longer relevant.
41-
cast::forget(tmp);
38+
cast::forget(t);
4239
}
4340
}
4441

src/libstd/vec.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,7 +1548,7 @@ impl<T> OwnedVector<T> for ~[T] {
15481548
let p = self.as_mut_ptr().offset(i as int);
15491549
// Shift everything over to make space. (Duplicating the
15501550
// `i`th element into two consecutive places.)
1551-
ptr::copy_memory(p.offset(1), p, len - i);
1551+
ptr::copy_memory(p.offset(1), &*p, len - i);
15521552
// Write it in, overwriting the first copy of the `i`th
15531553
// element.
15541554
mem::move_val_init(&mut *p, x);
@@ -1567,7 +1567,7 @@ impl<T> OwnedVector<T> for ~[T] {
15671567
let ret = Some(ptr::read_ptr(ptr as *T));
15681568

15691569
// Shift everything down to fill in that spot.
1570-
ptr::copy_memory(ptr, ptr.offset(1), len - i - 1);
1570+
ptr::copy_memory(ptr, &*ptr.offset(1), len - i - 1);
15711571
self.set_len(len - 1);
15721572

15731573
ret
@@ -1842,7 +1842,7 @@ fn insertion_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
18421842
if i != j {
18431843
let tmp = ptr::read_ptr(read_ptr);
18441844
ptr::copy_memory(buf_v.offset(j + 1),
1845-
buf_v.offset(j),
1845+
&*buf_v.offset(j),
18461846
(i - j) as uint);
18471847
ptr::copy_nonoverlapping_memory(buf_v.offset(j),
18481848
&tmp as *T,
@@ -1920,7 +1920,7 @@ fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
19201920
// that case, `i == j` so we don't copy. The
19211921
// `.offset(j)` is always in bounds.
19221922
ptr::copy_memory(buf_dat.offset(j + 1),
1923-
buf_dat.offset(j),
1923+
&*buf_dat.offset(j),
19241924
i - j as uint);
19251925
ptr::copy_nonoverlapping_memory(buf_dat.offset(j), read_ptr, 1);
19261926
}
@@ -1970,11 +1970,11 @@ fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
19701970
if left == right_start {
19711971
// the number remaining in this run.
19721972
let elems = (right_end as uint - right as uint) / mem::size_of::<T>();
1973-
ptr::copy_nonoverlapping_memory(out, right, elems);
1973+
ptr::copy_nonoverlapping_memory(out, &*right, elems);
19741974
break;
19751975
} else if right == right_end {
19761976
let elems = (right_start as uint - left as uint) / mem::size_of::<T>();
1977-
ptr::copy_nonoverlapping_memory(out, left, elems);
1977+
ptr::copy_nonoverlapping_memory(out, &*left, elems);
19781978
break;
19791979
}
19801980

@@ -1988,7 +1988,7 @@ fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
19881988
} else {
19891989
step(&mut left)
19901990
};
1991-
ptr::copy_nonoverlapping_memory(out, to_copy, 1);
1991+
ptr::copy_nonoverlapping_memory(out, &*to_copy, 1);
19921992
step(&mut out);
19931993
}
19941994
}
@@ -2002,7 +2002,7 @@ fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
20022002
// write the result to `v` in one go, so that there are never two copies
20032003
// of the same object in `v`.
20042004
unsafe {
2005-
ptr::copy_nonoverlapping_memory(v.as_mut_ptr(), buf_dat, len);
2005+
ptr::copy_nonoverlapping_memory(v.as_mut_ptr(), &*buf_dat, len);
20062006
}
20072007

20082008
// increment the pointer, returning the old pointer.

0 commit comments

Comments
 (0)