about summary refs log tree commit diff
diff options
context:
space:
mode:
authorjoboet <jonasboettiger@icloud.com>2025-01-10 18:48:48 +0100
committerjoboet <jonasboettiger@icloud.com>2025-01-10 18:48:48 +0100
commit4426e9a3c260e329f51c94e2b231f72574271f0b (patch)
tree5e951ec52413e97fde47b94bc51089ae20378dcc
parent336209eef13882bd1e211b24779584cb7ef911eb (diff)
downloadrust-4426e9a3c260e329f51c94e2b231f72574271f0b.tar.gz
rust-4426e9a3c260e329f51c94e2b231f72574271f0b.zip
alloc: remove unsound `IsZero` for raw pointers
Fixes #135338
-rw-r--r--library/alloc/src/vec/is_zero.rs15
-rw-r--r--library/alloc/tests/vec.rs10
2 files changed, 12 insertions, 13 deletions
diff --git a/library/alloc/src/vec/is_zero.rs b/library/alloc/src/vec/is_zero.rs
index ba57d940d8c..a3ddd6f6e23 100644
--- a/library/alloc/src/vec/is_zero.rs
+++ b/library/alloc/src/vec/is_zero.rs
@@ -40,19 +40,8 @@ impl_is_zero!(char, |x| x == '\0');
 impl_is_zero!(f32, |x: f32| x.to_bits() == 0);
 impl_is_zero!(f64, |x: f64| x.to_bits() == 0);
 
-unsafe impl<T> IsZero for *const T {
-    #[inline]
-    fn is_zero(&self) -> bool {
-        (*self).is_null()
-    }
-}
-
-unsafe impl<T> IsZero for *mut T {
-    #[inline]
-    fn is_zero(&self) -> bool {
-        (*self).is_null()
-    }
-}
+// `IsZero` cannot be soundly implemented for pointers because of provenance
+// (see #135338).
 
 unsafe impl<T: IsZero, const N: usize> IsZero for [T; N] {
     #[inline]
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index 2e654d3d1ff..b24daec2968 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -2742,3 +2742,13 @@ fn max_swap_remove() {
     let mut v = vec![0];
     v.swap_remove(usize::MAX);
 }
+
+// Regression test for #135338
+#[test]
+fn vec_null_ptr_roundtrip() {
+    let ptr = std::ptr::from_ref(&42);
+    let zero = ptr.with_addr(0);
+    let roundtripped = vec![zero; 1].pop().unwrap();
+    let new = roundtripped.with_addr(ptr.addr());
+    unsafe { new.read() };
+}