Skip to content

Commit 00ff5aa

Browse files
committed
Rename RawPtr::to_option() to RawPtr::as_ref()
As outlined in https://aturon.github.io/style/naming/conversions.html `to_` functions names should only be used for expensive operations. Thus `to_option` is better named `as_option`. Also, putting type names into method names is considered bad style; what the user is really trying to get is a reference. This `as_ref` is even better. Also, we are missing a mutable version of this method. So add a new trait `RawMutPtr` with a corresponding `as_mut` methode. Finally, there is a bug in the signature of `to_option` which has been around since lifetime elision: originally the returned reference had 'static lifetime, but since the elision changes this become the lifetime of the raw pointer (which does not make sense, since the pointer lifetime and referent lifetime are unrelated). Fix the bug to return a reference with a fresh lifetime (which will be inferred from the calling context). [breaking-change]
1 parent 27e8d5b commit 00ff5aa

File tree

4 files changed

+70
-15
lines changed

4 files changed

+70
-15
lines changed

src/libcollections/dlist.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ impl<T> Rawlink<T> {
9090
/// Convert the `Rawlink` into an Option value
9191
fn resolve_immut<'a>(&self) -> Option<&'a T> {
9292
unsafe {
93-
mem::transmute(self.p.to_option())
93+
self.p.as_ref()
9494
}
9595
}
9696

src/libcore/ptr.rs

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -256,27 +256,46 @@ pub unsafe fn position<T>(buf: *const T, f: |&T| -> bool) -> uint {
256256
pub trait RawPtr<T> {
257257
/// Returns the null pointer.
258258
fn null() -> Self;
259+
259260
/// Returns true if the pointer is equal to the null pointer.
260261
fn is_null(&self) -> bool;
262+
261263
/// Returns true if the pointer is not equal to the null pointer.
262264
fn is_not_null(&self) -> bool { !self.is_null() }
265+
263266
/// Returns the value of this pointer (ie, the address it points to)
264267
fn to_uint(&self) -> uint;
265-
/// Returns `None` if the pointer is null, or else returns the value wrapped
266-
/// in `Some`.
268+
269+
/// Returns `None` if the pointer is null, or else returns a reference to the
270+
/// value wrapped in `Some`.
267271
///
268272
/// # Safety Notes
269273
///
270-
/// While this method is useful for null-safety, it is important to note
271-
/// that this is still an unsafe operation because the returned value could
272-
/// be pointing to invalid memory.
273-
unsafe fn to_option(&self) -> Option<&T>;
274+
/// While this method and its mutable counterpart are useful for null-safety,
275+
/// it is important to note that this is still an unsafe operation because
276+
/// the returned value could be pointing to invalid memory.
277+
unsafe fn as_ref<'a>(&self) -> Option<&'a T>;
278+
279+
/// A synonym for `as_ref`, except with incorrect lifetime semantics
280+
#[deprecated="Use `as_ref` instead"]
281+
unsafe fn to_option<'a>(&'a self) -> Option<&'a T> {
282+
mem::transmute(self.as_ref())
283+
}
284+
274285
/// Calculates the offset from a pointer. The offset *must* be in-bounds of
275286
/// the object, or one-byte-past-the-end. `count` is in units of T; e.g. a
276287
/// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
277288
unsafe fn offset(self, count: int) -> Self;
278289
}
279290

291+
/// Methods on mutable raw pointers
292+
pub trait RawMutPtr<T>{
293+
/// Returns `None` if the pointer is null, or else returns a mutable reference
294+
/// to the value wrapped in `Some`. As with `as_ref`, this is unsafe because
295+
/// it cannot verify the validity of the returned pointer.
296+
unsafe fn as_mut<'a>(&self) -> Option<&'a mut T>;
297+
}
298+
280299
impl<T> RawPtr<T> for *const T {
281300
#[inline]
282301
fn null() -> *const T { null() }
@@ -293,7 +312,7 @@ impl<T> RawPtr<T> for *const T {
293312
}
294313

295314
#[inline]
296-
unsafe fn to_option(&self) -> Option<&T> {
315+
unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
297316
if self.is_null() {
298317
None
299318
} else {
@@ -318,7 +337,7 @@ impl<T> RawPtr<T> for *mut T {
318337
}
319338

320339
#[inline]
321-
unsafe fn to_option(&self) -> Option<&T> {
340+
unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
322341
if self.is_null() {
323342
None
324343
} else {
@@ -327,6 +346,17 @@ impl<T> RawPtr<T> for *mut T {
327346
}
328347
}
329348

349+
impl<T> RawMutPtr<T> for *mut T {
350+
#[inline]
351+
unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> {
352+
if self.is_null() {
353+
None
354+
} else {
355+
Some(&mut **self)
356+
}
357+
}
358+
}
359+
330360
// Equality for pointers
331361
impl<T> PartialEq for *const T {
332362
#[inline]

src/libcoretest/ptr.rs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,19 +102,44 @@ fn test_is_null() {
102102
}
103103

104104
#[test]
105-
fn test_to_option() {
105+
fn test_as_ref() {
106106
unsafe {
107107
let p: *const int = null();
108-
assert_eq!(p.to_option(), None);
108+
assert_eq!(p.as_ref(), None);
109109

110110
let q: *const int = &2;
111-
assert_eq!(q.to_option().unwrap(), &2);
111+
assert_eq!(q.as_ref().unwrap(), &2);
112112

113113
let p: *mut int = mut_null();
114-
assert_eq!(p.to_option(), None);
114+
assert_eq!(p.as_ref(), None);
115115

116116
let q: *mut int = &mut 2;
117-
assert_eq!(q.to_option().unwrap(), &2);
117+
assert_eq!(q.as_ref().unwrap(), &2);
118+
119+
// Lifetime inference
120+
let u = 2i;
121+
{
122+
let p: *const int = &u as *const _;
123+
assert_eq!(p.as_ref().unwrap(), &2);
124+
}
125+
}
126+
}
127+
128+
#[test]
129+
fn test_as_mut() {
130+
unsafe {
131+
let p: *mut int = mut_null();
132+
assert!(p.as_mut() == None);
133+
134+
let q: *mut int = &mut 2;
135+
assert!(q.as_mut().unwrap() == &mut 2);
136+
137+
// Lifetime inference
138+
let mut u = 2i;
139+
{
140+
let p: *mut int = &mut u as *mut _;
141+
assert!(p.as_mut().unwrap() == &mut 2);
142+
}
118143
}
119144
}
120145

src/liblog/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ impl Drop for DefaultLogger {
282282
pub fn log(level: u32, loc: &'static LogLocation, args: &fmt::Arguments) {
283283
// Test the literal string from args against the current filter, if there
284284
// is one.
285-
match unsafe { FILTER.to_option() } {
285+
match unsafe { FILTER.as_ref() } {
286286
Some(filter) if filter.is_match(args.to_string().as_slice()) => return,
287287
_ => {}
288288
}

0 commit comments

Comments
 (0)