Skip to content

std: clean up ptr a bit #12282

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/doc/guide-ffi.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ impl<T: Send> Drop for Unique<T> {
let x = mem::uninit(); // dummy value to swap in
// We need to move the object out of the box, so that
// the destructor is called (at the end of this scope.)
ptr::replace_ptr(self.ptr, x);
ptr::replace(self.ptr, x);
free(self.ptr as *mut c_void)
}
}
Expand Down Expand Up @@ -306,7 +306,7 @@ which would call back to `callback()` in Rust.
The former example showed how a global function can be called from C code.
However it is often desired that the callback is targetted to a special
Rust object. This could be the object that represents the wrapper for the
respective C object.
respective C object.

This can be achieved by passing an unsafe pointer to the object down to the
C library. The C library can then include the pointer to the Rust object in
Expand Down Expand Up @@ -335,7 +335,7 @@ extern {
fn main() {
// Create the object that will be referenced in the callback
let rust_object = ~RustObject{a: 5, ...};

unsafe {
// Gets a raw pointer to the object
let target_addr:*RustObject = ptr::to_unsafe_ptr(rust_object);
Expand Down Expand Up @@ -380,8 +380,8 @@ Rust is to use channels (in `std::comm`) to forward data from the C thread
that invoked the callback into a Rust task.

If an asychronous callback targets a special object in the Rust address space
it is also absolutely necessary that no more callbacks are performed by the
C library after the respective Rust object gets destroyed.
it is also absolutely necessary that no more callbacks are performed by the
C library after the respective Rust object gets destroyed.
This can be achieved by unregistering the callback in the object's
destructor and designing the library in a way that guarantees that no
callback will be performed after unregistration.
Expand Down
2 changes: 1 addition & 1 deletion src/libcollections/dlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ impl<T> Rawlink<T> {

/// Like Option::Some for Rawlink
fn some(n: &mut T) -> Rawlink<T> {
Rawlink{p: ptr::to_mut_unsafe_ptr(n)}
Rawlink{p: n}
}

/// Convert the `Rawlink` into an Option value
Expand Down
5 changes: 2 additions & 3 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ use std::cell::{Cell, RefCell};
use std::cmp;
use std::hashmap::{HashMap, HashSet};
use std::ops;
use std::ptr::to_unsafe_ptr;
use std::rc::Rc;
use std::to_bytes;
use std::to_str::ToStr;
Expand Down Expand Up @@ -1137,7 +1136,7 @@ pub fn mk_t(cx: ctxt, st: sty) -> t {
_ => {}
};

let key = intern_key { sty: to_unsafe_ptr(&st) };
let key = intern_key { sty: &st };

{
let mut interner = cx.interner.borrow_mut();
Expand Down Expand Up @@ -1234,7 +1233,7 @@ pub fn mk_t(cx: ctxt, st: sty) -> t {
flags: flags,
};

let sty_ptr = to_unsafe_ptr(&t.sty);
let sty_ptr = &t.sty as *sty;

let key = intern_key {
sty: sty_ptr,
Expand Down
12 changes: 11 additions & 1 deletion src/libstd/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1200,7 +1200,17 @@ impl<T> Pointer for *T {
}
impl<T> Pointer for *mut T {
fn fmt(&self, f: &mut Formatter) -> Result {
secret_pointer(&(*self as *T), f)
secret_pointer::<*T>(&(*self as *T), f)
}
}
impl<'a, T> Pointer for &'a T {
fn fmt(&self, f: &mut Formatter) -> Result {
secret_pointer::<*T>(&(&**self as *T), f)
}
}
impl<'a, T> Pointer for &'a mut T {
fn fmt(&self, f: &mut Formatter) -> Result {
secret_pointer::<*T>(&(&**self as *T), f)
}
}

Expand Down
10 changes: 4 additions & 6 deletions src/libstd/io/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,17 +155,15 @@ mod darwin_fd_limit {
pub unsafe fn raise_fd_limit() {
// The strategy here is to fetch the current resource limits, read the kern.maxfilesperproc
// sysctl value, and bump the soft resource limit for maxfiles up to the sysctl value.
use ptr::{to_unsafe_ptr, to_mut_unsafe_ptr, mut_null};
use ptr::mut_null;
use mem::size_of_val;
use os::last_os_error;

// Fetch the kern.maxfilesperproc value
let mut mib: [libc::c_int, ..2] = [CTL_KERN, KERN_MAXFILESPERPROC];
let mut maxfiles: libc::c_int = 0;
let mut size: libc::size_t = size_of_val(&maxfiles) as libc::size_t;
if sysctl(to_mut_unsafe_ptr(&mut mib[0]), 2,
to_mut_unsafe_ptr(&mut maxfiles) as *mut libc::c_void,
to_mut_unsafe_ptr(&mut size),
if sysctl(&mut mib[0], 2, &mut maxfiles as *mut libc::c_int as *mut libc::c_void, &mut size,
mut_null(), 0) != 0 {
let err = last_os_error();
error!("raise_fd_limit: error calling sysctl: {}", err);
Expand All @@ -174,7 +172,7 @@ mod darwin_fd_limit {

// Fetch the current resource limits
let mut rlim = rlimit{rlim_cur: 0, rlim_max: 0};
if getrlimit(RLIMIT_NOFILE, to_mut_unsafe_ptr(&mut rlim)) != 0 {
if getrlimit(RLIMIT_NOFILE, &mut rlim) != 0 {
let err = last_os_error();
error!("raise_fd_limit: error calling getrlimit: {}", err);
return;
Expand All @@ -184,7 +182,7 @@ mod darwin_fd_limit {
rlim.rlim_cur = ::cmp::min(maxfiles as rlim_t, rlim.rlim_max);

// Set our newly-increased resource limit
if setrlimit(RLIMIT_NOFILE, to_unsafe_ptr(&rlim)) != 0 {
if setrlimit(RLIMIT_NOFILE, &rlim) != 0 {
let err = last_os_error();
error!("raise_fd_limit: error calling setrlimit: {}", err);
return;
Expand Down
5 changes: 1 addition & 4 deletions src/libstd/managed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

//! Operations on managed box types

use ptr::to_unsafe_ptr;

#[cfg(not(test))] use cmp::*;

/// Returns the refcount of a shared box (as just before calling this)
Expand All @@ -24,8 +22,7 @@ pub fn refcount<T>(t: @T) -> uint {
/// Determine if two shared boxes point to the same object
#[inline]
pub fn ptr_eq<T>(a: @T, b: @T) -> bool {
let (a_ptr, b_ptr): (*T, *T) = (to_unsafe_ptr(&*a), to_unsafe_ptr(&*b));
a_ptr == b_ptr
&*a as *T == &*b as *T
}

#[cfg(not(test))]
Expand Down
110 changes: 36 additions & 74 deletions src/libstd/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {

/**
* Swap the values at two mutable locations of the same type, without
* deinitialising or copying either one.
* deinitialising either. They may overlap.
*/
#[inline]
pub unsafe fn swap_ptr<T>(x: *mut T, y: *mut T) {
pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
// Give ourselves some scratch space to work with
let mut tmp: T = mem::uninit();
let t: *mut T = &mut tmp;
Expand All @@ -122,19 +122,19 @@ pub unsafe fn swap_ptr<T>(x: *mut T, y: *mut T) {

/**
* Replace the value at a mutable location with a new one, returning the old
* value, without deinitialising or copying either one.
* value, without deinitialising either.
*/
#[inline]
pub unsafe fn replace_ptr<T>(dest: *mut T, mut src: T) -> T {
pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
mem::swap(cast::transmute(dest), &mut src); // cannot overlap
src
}

/**
* Reads the value from `*src` and returns it. Does not copy `*src`.
* Reads the value from `*src` and returns it.
*/
#[inline(always)]
pub unsafe fn read_ptr<T>(src: *T) -> T {
pub unsafe fn read<T>(src: *T) -> T {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason these can't be methods on RawPtr?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for RawPtr::read()

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Reproduced here)

Changing ptr::read to RawPtr::read is extremely inconvenient because, with ptr::read, &T will be coerced, whereas it will not be when it is a method. This introduces quite unnecessary casts. I do not wish to change it.

let mut tmp: T = mem::uninit();
copy_nonoverlapping_memory(&mut tmp, src, 1);
tmp
Expand All @@ -145,28 +145,16 @@ pub unsafe fn read_ptr<T>(src: *T) -> T {
* This currently prevents destructors from executing.
*/
#[inline(always)]
pub unsafe fn read_and_zero_ptr<T>(dest: *mut T) -> T {
pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
// Copy the data out from `dest`:
let tmp = read_ptr(&*dest);
let tmp = read(&*dest);

// Now zero out `dest`:
zero_memory(dest, 1);

tmp
}

/// Transform a region pointer - &T - to an unsafe pointer - *T.
#[inline]
pub fn to_unsafe_ptr<T>(thing: &T) -> *T {
thing as *T
}

/// Transform a mutable region pointer - &mut T - to a mutable unsafe pointer - *mut T.
#[inline]
pub fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T {
thing as *mut T
}

/**
Given a **T (pointer to an array of pointers),
iterate through each *T, up to the provided `len`,
Expand All @@ -176,7 +164,7 @@ pub fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T {
*/
pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
debug!("array_each_with_len: before iterate");
if arr as uint == 0 {
if arr.is_null() {
fail!("ptr::array_each_with_len failure: arr input is null pointer");
}
//let start_ptr = *arr;
Expand All @@ -197,108 +185,82 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
Dragons be here.
*/
pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
if arr as uint == 0 {
if arr.is_null() {
fail!("ptr::array_each_with_len failure: arr input is null pointer");
}
let len = buf_len(arr);
debug!("array_each inferred len: {}", len);
array_each_with_len(arr, len, cb);
}

#[allow(missing_doc)]
/// Extension methods for raw pointers.
pub trait RawPtr<T> {
/// Returns the null pointer.
fn null() -> Self;
/// Returns true if the pointer is equal to the null pointer.
fn is_null(&self) -> bool;
fn is_not_null(&self) -> bool;
/// Returns true if the pointer is not equal to the null pointer.
fn is_not_null(&self) -> bool { !self.is_null() }
/// Returns the value of this pointer (ie, the address it points to)
fn to_uint(&self) -> uint;
/// Returns `None` if the pointer is null, or else returns the value wrapped
/// in `Some`.
///
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

/// # Safety Notes
///
/// While this method is useful for null-safety, it is important to note
/// that this is still an unsafe operation because the returned value could
/// be pointing to invalid memory.
unsafe fn to_option(&self) -> Option<&T>;
/// Calculates the offset from a pointer. The offset *must* be in-bounds of
/// the object, or one-byte-past-the-end.
unsafe fn offset(self, count: int) -> Self;
}

/// Extension methods for immutable pointers
impl<T> RawPtr<T> for *T {
/// Returns the null pointer.
#[inline]
fn null() -> *T { null() }

/// Returns true if the pointer is equal to the null pointer.
#[inline]
fn is_null(&self) -> bool { *self == RawPtr::null() }

/// Returns true if the pointer is not equal to the null pointer.
#[inline]
fn is_not_null(&self) -> bool { *self != RawPtr::null() }
fn to_uint(&self) -> uint { *self as uint }

/// Returns the address of this pointer.
#[inline]
fn to_uint(&self) -> uint { *self as uint }
unsafe fn offset(self, count: int) -> *T { intrinsics::offset(self, count) }

///
/// Returns `None` if the pointer is null, or else returns the value wrapped
/// in `Some`.
///
/// # Safety Notes
///
/// While this method is useful for null-safety, it is important to note
/// that this is still an unsafe operation because the returned value could
/// be pointing to invalid memory.
///
#[inline]
unsafe fn to_option(&self) -> Option<&T> {
if self.is_null() { None } else {
if self.is_null() {
None
} else {
Some(cast::transmute(*self))
}
}

/// Calculates the offset from a pointer. The offset *must* be in-bounds of
/// the object, or one-byte-past-the-end.
#[inline]
unsafe fn offset(self, count: int) -> *T { intrinsics::offset(self, count) }
}

/// Extension methods for mutable pointers
impl<T> RawPtr<T> for *mut T {
/// Returns the null pointer.
#[inline]
fn null() -> *mut T { mut_null() }

/// Returns true if the pointer is equal to the null pointer.
#[inline]
fn is_null(&self) -> bool { *self == RawPtr::null() }

/// Returns true if the pointer is not equal to the null pointer.
#[inline]
fn is_not_null(&self) -> bool { *self != RawPtr::null() }
fn to_uint(&self) -> uint { *self as uint }

/// Returns the address of this pointer.
#[inline]
fn to_uint(&self) -> uint { *self as uint }
unsafe fn offset(self, count: int) -> *mut T { intrinsics::offset(self as *T, count) as *mut T }

///
/// Returns `None` if the pointer is null, or else returns the value wrapped
/// in `Some`.
///
/// # Safety Notes
///
/// While this method is useful for null-safety, it is important to note
/// that this is still an unsafe operation because the returned value could
/// be pointing to invalid memory.
///
#[inline]
unsafe fn to_option(&self) -> Option<&T> {
if self.is_null() { None } else {
if self.is_null() {
None
} else {
Some(cast::transmute(*self))
}
}

/// Calculates the offset from a pointer. The offset *must* be in-bounds of
/// the object, or one-byte-past-the-end. An arithmetic overflow is also
/// undefined behaviour.
///
/// This method should be preferred over `offset` when the guarantee can be
/// satisfied, to enable better optimization.
#[inline]
unsafe fn offset(self, count: int) -> *mut T { intrinsics::offset(self as *T, count) as *mut T }
}

// Equality for pointers
Expand Down
10 changes: 5 additions & 5 deletions src/libstd/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ pointers, and then storing the parent pointers as `Weak` pointers.
*/

use cast::transmute;
use ops::Drop;
use cmp::{Eq, Ord};
use clone::{Clone, DeepClone};
use cmp::{Eq, Ord};
use kinds::marker;
use rt::global_heap::exchange_free;
use ptr::read_ptr;
use ops::Drop;
use option::{Option, Some, None};
use ptr;
use rt::global_heap::exchange_free;

struct RcBox<T> {
value: T,
Expand Down Expand Up @@ -85,7 +85,7 @@ impl<T> Drop for Rc<T> {
if self.ptr != 0 as *mut RcBox<T> {
(*self.ptr).strong -= 1;
if (*self.ptr).strong == 0 {
read_ptr(self.borrow()); // destroy the contained object
ptr::read(self.borrow()); // destroy the contained object

// remove the implicit "strong weak" pointer now
// that we've destroyed the contents.
Expand Down
Loading