Skip to content

Commit eef03c3

Browse files
committed
Update to stop unsolicited copying and mark methods as unsafe
1 parent d1e091a commit eef03c3

File tree

1 file changed

+29
-11
lines changed

1 file changed

+29
-11
lines changed

src/libcore/ptr.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ pub unsafe fn array_each<T>(arr: **T, cb: &fn(*T)) {
210210
pub trait Ptr<T> {
211211
fn is_null(&const self) -> bool;
212212
fn is_not_null(&const self) -> bool;
213-
fn to_option(&const self) -> Option<T>;
213+
unsafe fn to_option(&const self) -> Option<&T>;
214214
fn offset(&self, count: uint) -> Self;
215215
}
216216

@@ -224,11 +224,20 @@ impl<T> Ptr<T> for *T {
224224
#[inline(always)]
225225
fn is_not_null(&const self) -> bool { is_not_null(*self) }
226226

227-
/// Returns `None` if the pointer is null, or else returns the value wrapped in `Some`.
227+
///
228+
/// Returns `None` if the pointer is null, or else returns the value wrapped
229+
/// in `Some`.
230+
///
231+
/// # Safety Notes
232+
///
233+
/// While this method is useful for null-safety, it is important to note
234+
/// that this is still an unsafe operation because the returned value could
235+
/// be pointing to invalid memory.
236+
///
228237
#[inline(always)]
229-
fn to_option(&const self) -> Option<T> {
238+
unsafe fn to_option(&const self) -> Option<&T> {
230239
if self.is_null() { None } else {
231-
Some(unsafe { **self })
240+
Some(cast::transmute(*self))
232241
}
233242
}
234243

@@ -247,11 +256,20 @@ impl<T> Ptr<T> for *mut T {
247256
#[inline(always)]
248257
fn is_not_null(&const self) -> bool { is_not_null(*self) }
249258

250-
/// Returns `None` if the pointer is null, or else returns the value wrapped in `Some`.
259+
///
260+
/// Returns `None` if the pointer is null, or else returns the value wrapped
261+
/// in `Some`.
262+
///
263+
/// # Safety Notes
264+
///
265+
/// While this method is useful for null-safety, it is important to note
266+
/// that this is still an unsafe operation because the returned value could
267+
/// be pointing to invalid memory.
268+
///
251269
#[inline(always)]
252-
fn to_option(&const self) -> Option<T> {
270+
unsafe fn to_option(&const self) -> Option<&T> {
253271
if self.is_null() { None } else {
254-
Some(unsafe { **self })
272+
Some(cast::transmute(*self))
255273
}
256274
}
257275

@@ -442,19 +460,19 @@ pub mod ptr_tests {
442460
}
443461

444462
#[test]
445-
#[allow(unused_mut)]
446463
fn test_to_option() {
447464
let p: *int = null();
465+
// FIXME (#6641): Usage of unsafe methods in safe code doesn't cause an error.
448466
assert_eq!(p.to_option(), None);
449467

450468
let q: *int = &2;
451-
assert_eq!(q.to_option(), Some(2));
469+
assert_eq!(q.to_option().unwrap(), &2); // FIXME (#6641)
452470

453471
let p: *mut int = mut_null();
454-
assert_eq!(p.to_option(), None);
472+
assert_eq!(p.to_option(), None); // FIXME (#6641)
455473

456474
let q: *mut int = &mut 2;
457-
assert_eq!(q.to_option(), Some(2));
475+
assert_eq!(q.to_option().unwrap(), &2); // FIXME (#6641)
458476
}
459477

460478
#[test]

0 commit comments

Comments
 (0)