Skip to content

Commit 3580c4c

Browse files
committed
Remove T: Sized on ptr::is_null(), as_ref(), as_mut()
`NonZero::is_zero()` was already casting all pointers to thin `*mut u8` to check for null. It seems reasonable to apply that for `is_null()` in general, and then unsized fat pointers can also be used with `as_ref()` and `as_mut()` to get fat references.
1 parent 688a858 commit 3580c4c

File tree

3 files changed

+66
-9
lines changed

3 files changed

+66
-9
lines changed

src/libcore/nonzero.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ macro_rules! impl_zeroable_for_pointer_types {
2828
unsafe impl<T: ?Sized> Zeroable for $Ptr {
2929
#[inline]
3030
fn is_zero(&self) -> bool {
31-
// Cast because `is_null` is only available on thin pointers
32-
(*self as *mut u8).is_null()
31+
(*self).is_null()
3332
}
3433
}
3534
)+

src/libcore/ptr.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,10 @@ impl<T: ?Sized> *const T {
487487
/// ```
488488
#[stable(feature = "rust1", since = "1.0.0")]
489489
#[inline]
490-
pub fn is_null(self) -> bool where T: Sized {
491-
self == null()
490+
pub fn is_null(self) -> bool {
491+
// Compare via a cast to a thin pointer, so fat pointers are only
492+
// considering their "data" part for null-ness.
493+
(self as *const u8) == null()
492494
}
493495

494496
/// Returns `None` if the pointer is null, or else returns a reference to
@@ -519,7 +521,7 @@ impl<T: ?Sized> *const T {
519521
/// ```
520522
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
521523
#[inline]
522-
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> where T: Sized {
524+
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
523525
if self.is_null() {
524526
None
525527
} else {
@@ -1118,8 +1120,10 @@ impl<T: ?Sized> *mut T {
11181120
/// ```
11191121
#[stable(feature = "rust1", since = "1.0.0")]
11201122
#[inline]
1121-
pub fn is_null(self) -> bool where T: Sized {
1122-
self == null_mut()
1123+
pub fn is_null(self) -> bool {
1124+
// Compare via a cast to a thin pointer, so fat pointers are only
1125+
// considering their "data" part for null-ness.
1126+
(self as *mut u8) == null_mut()
11231127
}
11241128

11251129
/// Returns `None` if the pointer is null, or else returns a reference to
@@ -1150,7 +1154,7 @@ impl<T: ?Sized> *mut T {
11501154
/// ```
11511155
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
11521156
#[inline]
1153-
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> where T: Sized {
1157+
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
11541158
if self.is_null() {
11551159
None
11561160
} else {
@@ -1274,7 +1278,7 @@ impl<T: ?Sized> *mut T {
12741278
/// ```
12751279
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
12761280
#[inline]
1277-
pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> where T: Sized {
1281+
pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> {
12781282
if self.is_null() {
12791283
None
12801284
} else {

src/libcore/tests/ptr.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
use core::ptr::*;
12+
use core::slice;
1213
use core::cell::RefCell;
1314

1415
#[test]
@@ -62,6 +63,28 @@ fn test_is_null() {
6263

6364
let mq = unsafe { mp.offset(1) };
6465
assert!(!mq.is_null());
66+
67+
// Pointers to unsized types
68+
let s: &mut [u8] = &mut [1, 2, 3];
69+
let cs: *const [u8] = s;
70+
assert!(!cs.is_null());
71+
72+
let ms: *mut [u8] = s;
73+
assert!(!ms.is_null());
74+
75+
let cz: *const [u8] = &[];
76+
assert!(!cz.is_null());
77+
78+
let mz: *mut [u8] = &mut [];
79+
assert!(!mz.is_null());
80+
81+
unsafe {
82+
let ncs: *const [u8] = slice::from_raw_parts(null(), 0);
83+
assert!(ncs.is_null());
84+
85+
let nms: *mut [u8] = slice::from_raw_parts_mut(null_mut(), 0);
86+
assert!(nms.is_null());
87+
}
6588
}
6689

6790
#[test]
@@ -85,6 +108,26 @@ fn test_as_ref() {
85108
let p = &u as *const isize;
86109
assert_eq!(p.as_ref().unwrap(), &2);
87110
}
111+
112+
// Pointers to unsized types
113+
let s: &mut [u8] = &mut [1, 2, 3];
114+
let cs: *const [u8] = s;
115+
assert_eq!(cs.as_ref(), Some(&*s));
116+
117+
let ms: *mut [u8] = s;
118+
assert_eq!(ms.as_ref(), Some(&*s));
119+
120+
let cz: *const [u8] = &[];
121+
assert_eq!(cz.as_ref(), Some(&[][..]));
122+
123+
let mz: *mut [u8] = &mut [];
124+
assert_eq!(mz.as_ref(), Some(&[][..]));
125+
126+
let ncs: *const [u8] = slice::from_raw_parts(null(), 0);
127+
assert_eq!(ncs.as_ref(), None);
128+
129+
let nms: *mut [u8] = slice::from_raw_parts_mut(null_mut(), 0);
130+
assert_eq!(nms.as_ref(), None);
88131
}
89132
}
90133

@@ -103,6 +146,17 @@ fn test_as_mut() {
103146
let p = &mut u as *mut isize;
104147
assert!(p.as_mut().unwrap() == &mut 2);
105148
}
149+
150+
// Pointers to unsized types
151+
let s: &mut [u8] = &mut [1, 2, 3];
152+
let ms: *mut [u8] = s;
153+
assert_eq!(ms.as_mut(), Some(s));
154+
155+
let mz: *mut [u8] = &mut [];
156+
assert_eq!(mz.as_mut(), Some(&mut [][..]));
157+
158+
let nms: *mut [u8] = slice::from_raw_parts_mut(null_mut(), 0);
159+
assert_eq!(nms.as_mut(), None);
106160
}
107161
}
108162

0 commit comments

Comments
 (0)