From 1b7733109d7b692c2ddd404f1bb6c751c3194750 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 31 Jan 2014 14:01:59 -0800 Subject: [PATCH 1/2] std: Stop parameterizing some memcpy functions over RawPtr It unsafe assumptions that any impl of RawPtr is for actual pointers, that they can be copied by memcpy. Removing it is easy, so I don't think it's solving a real problem. --- src/libstd/cast.rs | 5 ++--- src/libstd/ptr.rs | 18 +++++++++--------- src/libstd/util.rs | 6 +++--- src/libstd/vec.rs | 16 ++++++++-------- 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/libstd/cast.rs b/src/libstd/cast.rs index 258c0e23094..ffdd70a6c14 100644 --- a/src/libstd/cast.rs +++ b/src/libstd/cast.rs @@ -10,7 +10,6 @@ //! Unsafe casting functions -use ptr::RawPtr; use mem; use unstable::intrinsics; use ptr::copy_nonoverlapping_memory; @@ -72,13 +71,13 @@ pub unsafe fn transmute_region<'a,'b,T>(ptr: &'a T) -> &'b T { /// Coerce an immutable reference to be mutable. #[inline] -pub unsafe fn transmute_mut_unsafe>(ptr: P) -> *mut T { +pub unsafe fn transmute_mut_unsafe(ptr: *T) -> *mut T { transmute(ptr) } /// Coerce an immutable reference to be mutable. #[inline] -pub unsafe fn transmute_immut_unsafe>(ptr: P) -> *T { +pub unsafe fn transmute_immut_unsafe(ptr: *mut T) -> *T { transmute(ptr) } diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index d22e91fb83e..484f81f277f 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -92,8 +92,8 @@ pub fn is_not_null>(ptr: P) -> bool { ptr.is_not_null() } * and destination may overlap. */ #[inline] -pub unsafe fn copy_memory>(dst: *mut T, src: P, count: uint) { - intrinsics::copy_memory(dst, cast::transmute_immut_unsafe(src), count) +pub unsafe fn copy_memory(dst: *mut T, src: *T, count: uint) { + intrinsics::copy_memory(dst, src, count) } /** @@ -103,10 +103,10 @@ pub unsafe fn copy_memory>(dst: *mut T, src: P, count: uint) { * and destination may *not* overlap. */ #[inline] -pub unsafe fn copy_nonoverlapping_memory>(dst: *mut T, - src: P, - count: uint) { - intrinsics::copy_nonoverlapping_memory(dst, cast::transmute_immut_unsafe(src), count) +pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, + src: *T, + count: uint) { + intrinsics::copy_nonoverlapping_memory(dst, src, count) } /** @@ -137,9 +137,9 @@ pub unsafe fn swap_ptr(x: *mut T, y: *mut T) { let t: *mut T = &mut tmp; // Perform the swap - copy_nonoverlapping_memory(t, x, 1); - copy_memory(x, y, 1); // `x` and `y` may overlap - copy_nonoverlapping_memory(y, t, 1); + copy_nonoverlapping_memory(t, &*x, 1); + copy_memory(x, &*y, 1); // `x` and `y` may overlap + copy_nonoverlapping_memory(y, &*t, 1); // y and t now point to the same thing, but we need to completely forget `tmp` // because it's no longer relevant. diff --git a/src/libstd/util.rs b/src/libstd/util.rs index 05c5d7e1588..4f7fbbc2bbc 100644 --- a/src/libstd/util.rs +++ b/src/libstd/util.rs @@ -32,9 +32,9 @@ pub fn swap(x: &mut T, y: &mut T) { // Perform the swap, `&mut` pointers never alias let x_raw: *mut T = x; let y_raw: *mut T = y; - ptr::copy_nonoverlapping_memory(t, x_raw, 1); - ptr::copy_nonoverlapping_memory(x, y_raw, 1); - ptr::copy_nonoverlapping_memory(y, t, 1); + ptr::copy_nonoverlapping_memory(t, &*x_raw, 1); + ptr::copy_nonoverlapping_memory(x, &*y_raw, 1); + ptr::copy_nonoverlapping_memory(y, &*t, 1); // y and t now point to the same thing, but we need to completely forget `tmp` // because it's no longer relevant. diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 85413cb5bd6..de865434a3e 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -1548,7 +1548,7 @@ impl OwnedVector for ~[T] { let p = self.as_mut_ptr().offset(i as int); // Shift everything over to make space. (Duplicating the // `i`th element into two consecutive places.) - ptr::copy_memory(p.offset(1), p, len - i); + ptr::copy_memory(p.offset(1), &*p, len - i); // Write it in, overwriting the first copy of the `i`th // element. mem::move_val_init(&mut *p, x); @@ -1567,7 +1567,7 @@ impl OwnedVector for ~[T] { let ret = Some(ptr::read_ptr(ptr as *T)); // Shift everything down to fill in that spot. - ptr::copy_memory(ptr, ptr.offset(1), len - i - 1); + ptr::copy_memory(ptr, &*ptr.offset(1), len - i - 1); self.set_len(len - 1); ret @@ -1842,7 +1842,7 @@ fn insertion_sort(v: &mut [T], compare: |&T, &T| -> Ordering) { if i != j { let tmp = ptr::read_ptr(read_ptr); ptr::copy_memory(buf_v.offset(j + 1), - buf_v.offset(j), + &*buf_v.offset(j), (i - j) as uint); ptr::copy_nonoverlapping_memory(buf_v.offset(j), &tmp as *T, @@ -1920,7 +1920,7 @@ fn merge_sort(v: &mut [T], compare: |&T, &T| -> Ordering) { // that case, `i == j` so we don't copy. The // `.offset(j)` is always in bounds. ptr::copy_memory(buf_dat.offset(j + 1), - buf_dat.offset(j), + &*buf_dat.offset(j), i - j as uint); ptr::copy_nonoverlapping_memory(buf_dat.offset(j), read_ptr, 1); } @@ -1970,11 +1970,11 @@ fn merge_sort(v: &mut [T], compare: |&T, &T| -> Ordering) { if left == right_start { // the number remaining in this run. let elems = (right_end as uint - right as uint) / mem::size_of::(); - ptr::copy_nonoverlapping_memory(out, right, elems); + ptr::copy_nonoverlapping_memory(out, &*right, elems); break; } else if right == right_end { let elems = (right_start as uint - left as uint) / mem::size_of::(); - ptr::copy_nonoverlapping_memory(out, left, elems); + ptr::copy_nonoverlapping_memory(out, &*left, elems); break; } @@ -1988,7 +1988,7 @@ fn merge_sort(v: &mut [T], compare: |&T, &T| -> Ordering) { } else { step(&mut left) }; - ptr::copy_nonoverlapping_memory(out, to_copy, 1); + ptr::copy_nonoverlapping_memory(out, &*to_copy, 1); step(&mut out); } } @@ -2002,7 +2002,7 @@ fn merge_sort(v: &mut [T], compare: |&T, &T| -> Ordering) { // write the result to `v` in one go, so that there are never two copies // of the same object in `v`. unsafe { - ptr::copy_nonoverlapping_memory(v.as_mut_ptr(), buf_dat, len); + ptr::copy_nonoverlapping_memory(v.as_mut_ptr(), &*buf_dat, len); } // increment the pointer, returning the old pointer. From 07c5e5d81363b6cdbca64637832620ab4870d258 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 9 Feb 2014 14:05:31 -0800 Subject: [PATCH 2/2] std: Clean up the swap function a little --- src/libstd/util.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/libstd/util.rs b/src/libstd/util.rs index 4f7fbbc2bbc..644b5cefdc8 100644 --- a/src/libstd/util.rs +++ b/src/libstd/util.rs @@ -26,19 +26,16 @@ pub fn id(x: T) -> T { x } pub fn swap(x: &mut T, y: &mut T) { unsafe { // Give ourselves some scratch space to work with - let mut tmp: T = mem::uninit(); - let t: *mut T = &mut tmp; + let mut t: T = mem::uninit(); // Perform the swap, `&mut` pointers never alias - let x_raw: *mut T = x; - let y_raw: *mut T = y; - ptr::copy_nonoverlapping_memory(t, &*x_raw, 1); - ptr::copy_nonoverlapping_memory(x, &*y_raw, 1); - ptr::copy_nonoverlapping_memory(y, &*t, 1); + ptr::copy_nonoverlapping_memory(&mut t, &*x, 1); + ptr::copy_nonoverlapping_memory(x, &*y, 1); + ptr::copy_nonoverlapping_memory(y, &t, 1); // y and t now point to the same thing, but we need to completely forget `tmp` // because it's no longer relevant. - cast::forget(tmp); + cast::forget(t); } }