Restore T: Sized
on ptr::is_null
The exact semantics of `is_null` on unsized pointers are still debatable, especially for trait objects. It may be legal to call `*mut self` methods on a trait object someday, as with Go interfaces, so `is_null` might need to validate the vtable pointer too. For `as_ref` and `as_mut`, we're assuming that you cannot have a non-null data pointer with a null vtable, so casting the unsized check is fine.
This commit is contained in:
parent
40a678d8db
commit
604f049cd5
3 changed files with 15 additions and 55 deletions
|
@ -28,7 +28,8 @@ macro_rules! impl_zeroable_for_pointer_types {
|
||||||
unsafe impl<T: ?Sized> Zeroable for $Ptr {
|
unsafe impl<T: ?Sized> Zeroable for $Ptr {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_zero(&self) -> bool {
|
fn is_zero(&self) -> bool {
|
||||||
(*self).is_null()
|
// Cast because `is_null` is only available on thin pointers
|
||||||
|
(*self as *mut u8).is_null()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)+
|
)+
|
||||||
|
|
|
@ -476,11 +476,6 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
|
||||||
impl<T: ?Sized> *const T {
|
impl<T: ?Sized> *const T {
|
||||||
/// Returns `true` if the pointer is null.
|
/// Returns `true` if the pointer is null.
|
||||||
///
|
///
|
||||||
/// Note that unsized types have many possible null pointers, as only the
|
|
||||||
/// raw data pointer is considered, not their length, vtable, etc.
|
|
||||||
/// Therefore, two pointers that are null may still not compare equal to
|
|
||||||
/// each other.
|
|
||||||
///
|
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// Basic usage:
|
/// Basic usage:
|
||||||
|
@ -492,10 +487,8 @@ impl<T: ?Sized> *const T {
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_null(self) -> bool {
|
pub fn is_null(self) -> bool where T: Sized {
|
||||||
// Compare via a cast to a thin pointer, so fat pointers are only
|
self == null()
|
||||||
// considering their "data" part for null-ness.
|
|
||||||
(self as *const u8) == null()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `None` if the pointer is null, or else returns a reference to
|
/// Returns `None` if the pointer is null, or else returns a reference to
|
||||||
|
@ -527,7 +520,9 @@ impl<T: ?Sized> *const T {
|
||||||
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
|
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
|
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
|
||||||
if self.is_null() {
|
// Check for null via a cast to a thin pointer, so fat pointers are only
|
||||||
|
// considering their "data" part for null-ness.
|
||||||
|
if (self as *const u8).is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(&*self)
|
Some(&*self)
|
||||||
|
@ -1114,11 +1109,6 @@ impl<T: ?Sized> *const T {
|
||||||
impl<T: ?Sized> *mut T {
|
impl<T: ?Sized> *mut T {
|
||||||
/// Returns `true` if the pointer is null.
|
/// Returns `true` if the pointer is null.
|
||||||
///
|
///
|
||||||
/// Note that unsized types have many possible null pointers, as only the
|
|
||||||
/// raw data pointer is considered, not their length, vtable, etc.
|
|
||||||
/// Therefore, two pointers that are null may still not compare equal to
|
|
||||||
/// each other.
|
|
||||||
///
|
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// Basic usage:
|
/// Basic usage:
|
||||||
|
@ -1130,10 +1120,8 @@ impl<T: ?Sized> *mut T {
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_null(self) -> bool {
|
pub fn is_null(self) -> bool where T: Sized {
|
||||||
// Compare via a cast to a thin pointer, so fat pointers are only
|
self == null_mut()
|
||||||
// considering their "data" part for null-ness.
|
|
||||||
(self as *mut u8) == null_mut()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `None` if the pointer is null, or else returns a reference to
|
/// Returns `None` if the pointer is null, or else returns a reference to
|
||||||
|
@ -1165,7 +1153,9 @@ impl<T: ?Sized> *mut T {
|
||||||
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
|
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
|
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
|
||||||
if self.is_null() {
|
// Check for null via a cast to a thin pointer, so fat pointers are only
|
||||||
|
// considering their "data" part for null-ness.
|
||||||
|
if (self as *const u8).is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(&*self)
|
Some(&*self)
|
||||||
|
@ -1289,7 +1279,9 @@ impl<T: ?Sized> *mut T {
|
||||||
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
|
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> {
|
pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> {
|
||||||
if self.is_null() {
|
// Check for null via a cast to a thin pointer, so fat pointers are only
|
||||||
|
// considering their "data" part for null-ness.
|
||||||
|
if (self as *mut u8).is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(&mut *self)
|
Some(&mut *self)
|
||||||
|
|
|
@ -62,39 +62,6 @@ fn test_is_null() {
|
||||||
|
|
||||||
let mq = unsafe { mp.offset(1) };
|
let mq = unsafe { mp.offset(1) };
|
||||||
assert!(!mq.is_null());
|
assert!(!mq.is_null());
|
||||||
|
|
||||||
// Pointers to unsized types -- slices
|
|
||||||
let s: &mut [u8] = &mut [1, 2, 3];
|
|
||||||
let cs: *const [u8] = s;
|
|
||||||
assert!(!cs.is_null());
|
|
||||||
|
|
||||||
let ms: *mut [u8] = s;
|
|
||||||
assert!(!ms.is_null());
|
|
||||||
|
|
||||||
let cz: *const [u8] = &[];
|
|
||||||
assert!(!cz.is_null());
|
|
||||||
|
|
||||||
let mz: *mut [u8] = &mut [];
|
|
||||||
assert!(!mz.is_null());
|
|
||||||
|
|
||||||
let ncs: *const [u8] = null::<[u8; 3]>();
|
|
||||||
assert!(ncs.is_null());
|
|
||||||
|
|
||||||
let nms: *mut [u8] = null_mut::<[u8; 3]>();
|
|
||||||
assert!(nms.is_null());
|
|
||||||
|
|
||||||
// Pointers to unsized types -- trait objects
|
|
||||||
let ci: *const ToString = &3;
|
|
||||||
assert!(!ci.is_null());
|
|
||||||
|
|
||||||
let mi: *mut ToString = &mut 3;
|
|
||||||
assert!(!mi.is_null());
|
|
||||||
|
|
||||||
let nci: *const ToString = null::<isize>();
|
|
||||||
assert!(nci.is_null());
|
|
||||||
|
|
||||||
let nmi: *mut ToString = null_mut::<isize>();
|
|
||||||
assert!(nmi.is_null());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Reference in a new issue