about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeSeulArtichaut <leseulartichaut@gmail.com>2020-06-30 19:10:22 +0200
committerLeSeulArtichaut <leseulartichaut@gmail.com>2020-06-30 19:28:51 +0200
commita1623ff3b6a48e7ac29e1c25900989851278743b (patch)
tree55caa59b00e3e3a180b88c616ad2335623f82f77
parentb3652337a9539e703682a6babbf816192760bd3d (diff)
downloadrust-a1623ff3b6a48e7ac29e1c25900989851278743b.tar.gz
rust-a1623ff3b6a48e7ac29e1c25900989851278743b.zip
Deny unsafe ops in unsafe fns, part 6
And final part!!!
-rw-r--r--src/libcore/alloc/mod.rs1
-rw-r--r--src/libcore/cell.rs1
-rw-r--r--src/libcore/char/convert.rs2
-rw-r--r--src/libcore/char/methods.rs2
-rw-r--r--src/libcore/convert/num.rs2
-rw-r--r--src/libcore/ffi.rs1
-rw-r--r--src/libcore/future/mod.rs4
-rw-r--r--src/libcore/hash/sip.rs1
-rw-r--r--src/libcore/hint.rs2
-rw-r--r--src/libcore/intrinsics.rs1
-rw-r--r--src/libcore/iter/mod.rs1
-rw-r--r--src/libcore/lib.rs9
-rw-r--r--src/libcore/mem/mod.rs1
-rw-r--r--src/libcore/num/f32.rs1
-rw-r--r--src/libcore/num/f64.rs1
-rw-r--r--src/libcore/num/mod.rs1
-rw-r--r--src/libcore/pin.rs1
-rw-r--r--src/libcore/ptr/const_ptr.rs31
-rw-r--r--src/libcore/ptr/mod.rs126
-rw-r--r--src/libcore/ptr/mut_ptr.rs64
-rw-r--r--src/libcore/ptr/non_null.rs11
-rw-r--r--src/libcore/ptr/unique.rs11
-rw-r--r--src/libcore/slice/mod.rs1
-rw-r--r--src/libcore/str/mod.rs1
-rw-r--r--src/libcore/sync/atomic.rs1
25 files changed, 185 insertions, 93 deletions
diff --git a/src/libcore/alloc/mod.rs b/src/libcore/alloc/mod.rs
index d00dbd2c34d..be4e051b1ca 100644
--- a/src/libcore/alloc/mod.rs
+++ b/src/libcore/alloc/mod.rs
@@ -1,7 +1,6 @@
 //! Memory allocation APIs
 
 #![stable(feature = "alloc_module", since = "1.28.0")]
-#![deny(unsafe_op_in_unsafe_fn)]
 
 mod global;
 mod layout;
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index caaf940b62c..51d9695687f 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -187,7 +187,6 @@
 //!
 
 #![stable(feature = "rust1", since = "1.0.0")]
-#![deny(unsafe_op_in_unsafe_fn)]
 
 use crate::cmp::Ordering;
 use crate::fmt::{self, Debug, Display};
diff --git a/src/libcore/char/convert.rs b/src/libcore/char/convert.rs
index 001362ba1c3..c329eec76ac 100644
--- a/src/libcore/char/convert.rs
+++ b/src/libcore/char/convert.rs
@@ -1,7 +1,5 @@
 //! Character conversions.
 
-#![deny(unsafe_op_in_unsafe_fn)]
-
 use crate::convert::TryFrom;
 use crate::fmt;
 use crate::mem::transmute;
diff --git a/src/libcore/char/methods.rs b/src/libcore/char/methods.rs
index 5a62c92694f..72555d781ed 100644
--- a/src/libcore/char/methods.rs
+++ b/src/libcore/char/methods.rs
@@ -1,7 +1,5 @@
 //! impl char {}
 
-#![deny(unsafe_op_in_unsafe_fn)]
-
 use crate::slice;
 use crate::str::from_utf8_unchecked_mut;
 use crate::unicode::printable::is_printable;
diff --git a/src/libcore/convert/num.rs b/src/libcore/convert/num.rs
index 094618acc58..336c0b26bc7 100644
--- a/src/libcore/convert/num.rs
+++ b/src/libcore/convert/num.rs
@@ -1,5 +1,3 @@
-#![deny(unsafe_op_in_unsafe_fn)]
-
 use super::{From, TryFrom};
 use crate::num::TryFromIntError;
 
diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs
index dda1d3467b6..ca463200650 100644
--- a/src/libcore/ffi.rs
+++ b/src/libcore/ffi.rs
@@ -1,6 +1,5 @@
 #![stable(feature = "", since = "1.30.0")]
 #![allow(non_camel_case_types)]
-#![deny(unsafe_op_in_unsafe_fn)]
 
 //! Utilities related to FFI bindings.
 
diff --git a/src/libcore/future/mod.rs b/src/libcore/future/mod.rs
index 9dbc23f5c04..2555d91ae8d 100644
--- a/src/libcore/future/mod.rs
+++ b/src/libcore/future/mod.rs
@@ -85,5 +85,7 @@ where
 #[unstable(feature = "gen_future", issue = "50547")]
 #[inline]
 pub unsafe fn get_context<'a, 'b>(cx: ResumeTy) -> &'a mut Context<'b> {
-    &mut *cx.0.as_ptr().cast()
+    // SAFETY: the caller must guarantee that `cx.0` is a valid pointer
+    // that fulfills all the requirements for a mutable reference.
+    unsafe { &mut *cx.0.as_ptr().cast() }
 }
diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs
index 84148058d03..f2bbf646f32 100644
--- a/src/libcore/hash/sip.rs
+++ b/src/libcore/hash/sip.rs
@@ -1,7 +1,6 @@
 //! An implementation of SipHash.
 
 #![allow(deprecated)] // the types in this module are deprecated
-#![deny(unsafe_op_in_unsafe_fn)]
 
 use crate::cmp;
 use crate::marker::PhantomData;
diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index fd2d443dde8..9ebcde79b63 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -2,8 +2,6 @@
 
 //! Hints to compiler that affects how code should be emitted or optimized.
 
-#![deny(unsafe_op_in_unsafe_fn)]
-
 use crate::intrinsics;
 
 /// Informs the compiler that this point in the code is not reachable, enabling
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 237c6e0545f..3c0d5f8bfe7 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -53,7 +53,6 @@
     issue = "none"
 )]
 #![allow(missing_docs)]
-#![deny(unsafe_op_in_unsafe_fn)]
 
 use crate::marker::DiscriminantKind;
 use crate::mem;
diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs
index 4a1f6418bb5..080b70c6368 100644
--- a/src/libcore/iter/mod.rs
+++ b/src/libcore/iter/mod.rs
@@ -309,7 +309,6 @@
 //! [`min`]: trait.Iterator.html#method.min
 
 #![stable(feature = "rust1", since = "1.0.0")]
-#![deny(unsafe_op_in_unsafe_fn)]
 
 use crate::ops::Try;
 
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 1459a6b2f16..81c2344e205 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -149,6 +149,7 @@
 #![feature(const_caller_location)]
 #![feature(no_niche)] // rust-lang/rust#68303
 #![feature(unsafe_block_in_unsafe_fn)]
+#![deny(unsafe_op_in_unsafe_fn)]
 
 #[prelude_import]
 #[allow(unused)]
@@ -279,7 +280,13 @@ pub mod primitive;
 // set up in such a way that directly pulling it here works such that the
 // crate uses the this crate as its libcore.
 #[path = "../stdarch/crates/core_arch/src/mod.rs"]
-#[allow(missing_docs, missing_debug_implementations, dead_code, unused_imports)]
+#[allow(
+    missing_docs,
+    missing_debug_implementations,
+    dead_code,
+    unused_imports,
+    unsafe_op_in_unsafe_fn
+)]
 // FIXME: This annotation should be moved into rust-lang/stdarch after clashing_extern_declarations is
 // merged. It currently cannot because bootstrap fails as the lint hasn't been defined yet.
 #[cfg_attr(not(bootstrap), allow(clashing_extern_declarations))]
diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs
index 20ea83fd063..272088815ec 100644
--- a/src/libcore/mem/mod.rs
+++ b/src/libcore/mem/mod.rs
@@ -4,7 +4,6 @@
 //! types, initializing and manipulating memory.
 
 #![stable(feature = "rust1", since = "1.0.0")]
-#![deny(unsafe_op_in_unsafe_fn)]
 
 use crate::clone;
 use crate::cmp;
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 028beb86e68..061d1ea6b1c 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -9,7 +9,6 @@
 //! new code should use the associated constants directly on the primitive type.
 
 #![stable(feature = "rust1", since = "1.0.0")]
-#![deny(unsafe_op_in_unsafe_fn)]
 
 use crate::convert::FloatToInt;
 #[cfg(not(test))]
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 74e38c128b3..b0df4d64f6e 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -9,7 +9,6 @@
 //! new code should use the associated constants directly on the primitive type.
 
 #![stable(feature = "rust1", since = "1.0.0")]
-#![deny(unsafe_op_in_unsafe_fn)]
 
 use crate::convert::FloatToInt;
 #[cfg(not(test))]
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 918eea7acb3..2ded2e9c086 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -3,7 +3,6 @@
 //! Numeric traits and functions for the built-in numeric types.
 
 #![stable(feature = "rust1", since = "1.0.0")]
-#![deny(unsafe_op_in_unsafe_fn)]
 
 use crate::convert::Infallible;
 use crate::fmt;
diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index b042bed681e..da299f026f8 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -375,7 +375,6 @@
 //! [`i32`]: ../../std/primitive.i32.html
 
 #![stable(feature = "pin", since = "1.33.0")]
-#![deny(unsafe_op_in_unsafe_fn)]
 
 use crate::cmp::{self, PartialEq, PartialOrd};
 use crate::fmt;
diff --git a/src/libcore/ptr/const_ptr.rs b/src/libcore/ptr/const_ptr.rs
index 64a506a6377..d1d7a715238 100644
--- a/src/libcore/ptr/const_ptr.rs
+++ b/src/libcore/ptr/const_ptr.rs
@@ -95,7 +95,9 @@ impl<T: ?Sized> *const T {
     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
     #[inline]
     pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
-        if self.is_null() { None } else { Some(&*self) }
+        // SAFETY: the caller must guarantee that `self` is valid
+        // for a reference if it isn't null.
+        if self.is_null() { None } else { unsafe { Some(&*self) } }
     }
 
     /// Calculates the offset from a pointer.
@@ -157,7 +159,8 @@ impl<T: ?Sized> *const T {
     where
         T: Sized,
     {
-        intrinsics::offset(self, count)
+        // SAFETY: the caller must uphold the safety contract for `offset`.
+        unsafe { intrinsics::offset(self, count) }
     }
 
     /// Calculates the offset from a pointer using wrapping arithmetic.
@@ -292,7 +295,8 @@ impl<T: ?Sized> *const T {
     {
         let pointee_size = mem::size_of::<T>();
         assert!(0 < pointee_size && pointee_size <= isize::MAX as usize);
-        intrinsics::ptr_offset_from(self, origin)
+        // SAFETY: the caller must uphold the safety contract for `ptr_offset_from`.
+        unsafe { intrinsics::ptr_offset_from(self, origin) }
     }
 
     /// Returns whether two pointers are guaranteed to be equal.
@@ -471,7 +475,8 @@ impl<T: ?Sized> *const T {
     where
         T: Sized,
     {
-        self.offset(count as isize)
+        // SAFETY: the caller must uphold the safety contract for `offset`.
+        unsafe { self.offset(count as isize) }
     }
 
     /// Calculates the offset from a pointer (convenience for
@@ -534,7 +539,8 @@ impl<T: ?Sized> *const T {
     where
         T: Sized,
     {
-        self.offset((count as isize).wrapping_neg())
+        // SAFETY: the caller must uphold the safety contract for `offset`.
+        unsafe { self.offset((count as isize).wrapping_neg()) }
     }
 
     /// Calculates the offset from a pointer using wrapping arithmetic.
@@ -663,7 +669,8 @@ impl<T: ?Sized> *const T {
     where
         T: Sized,
     {
-        read(self)
+        // SAFETY: the caller must uphold the safety contract for `read`.
+        unsafe { read(self) }
     }
 
     /// Performs a volatile read of the value from `self` without moving it. This
@@ -682,7 +689,8 @@ impl<T: ?Sized> *const T {
     where
         T: Sized,
     {
-        read_volatile(self)
+        // SAFETY: the caller must uphold the safety contract for `read_volatile`.
+        unsafe { read_volatile(self) }
     }
 
     /// Reads the value from `self` without moving it. This leaves the
@@ -699,7 +707,8 @@ impl<T: ?Sized> *const T {
     where
         T: Sized,
     {
-        read_unaligned(self)
+        // SAFETY: the caller must uphold the safety contract for `read_unaligned`.
+        unsafe { read_unaligned(self) }
     }
 
     /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
@@ -716,7 +725,8 @@ impl<T: ?Sized> *const T {
     where
         T: Sized,
     {
-        copy(self, dest, count)
+        // SAFETY: the caller must uphold the safety contract for `copy`.
+        unsafe { copy(self, dest, count) }
     }
 
     /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
@@ -733,7 +743,8 @@ impl<T: ?Sized> *const T {
     where
         T: Sized,
     {
-        copy_nonoverlapping(self, dest, count)
+        // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
+        unsafe { copy_nonoverlapping(self, dest, count) }
     }
 
     /// Computes the offset that needs to be applied to the pointer in order to make it aligned to
diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs
index ca2b0c85ec1..5f028f9ea76 100644
--- a/src/libcore/ptr/mod.rs
+++ b/src/libcore/ptr/mod.rs
@@ -184,7 +184,9 @@ mod mut_ptr;
 pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     // Code here does not matter - this is replaced by the
     // real drop glue by the compiler.
-    drop_in_place(to_drop)
+
+    // SAFETY: see comment above
+    unsafe { drop_in_place(to_drop) }
 }
 
 /// Creates a null raw pointer.
@@ -374,9 +376,15 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
     let mut tmp = MaybeUninit::<T>::uninit();
 
     // Perform the swap
-    copy_nonoverlapping(x, tmp.as_mut_ptr(), 1);
-    copy(y, x, 1); // `x` and `y` may overlap
-    copy_nonoverlapping(tmp.as_ptr(), y, 1);
+    // SAFETY: the caller must guarantee that `x` and `y` are
+    // valid for writes and properly aligned. `tmp` cannot be
+    // overlapping either `x` or `y` because `tmp` was just allocated
+    // on the stack as a separate allocated object.
+    unsafe {
+        copy_nonoverlapping(x, tmp.as_mut_ptr(), 1);
+        copy(y, x, 1); // `x` and `y` may overlap
+        copy_nonoverlapping(tmp.as_ptr(), y, 1);
+    }
 }
 
 /// Swaps `count * size_of::<T>()` bytes between the two regions of memory
@@ -432,7 +440,9 @@ pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
     let x = x as *mut u8;
     let y = y as *mut u8;
     let len = mem::size_of::<T>() * count;
-    swap_nonoverlapping_bytes(x, y, len)
+    // SAFETY: the caller must guarantee that `x` and `y` are
+    // valid for writes and properly aligned.
+    unsafe { swap_nonoverlapping_bytes(x, y, len) }
 }
 
 #[inline]
@@ -440,11 +450,16 @@ pub(crate) unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
     // For types smaller than the block optimization below,
     // just swap directly to avoid pessimizing codegen.
     if mem::size_of::<T>() < 32 {
-        let z = read(x);
-        copy_nonoverlapping(y, x, 1);
-        write(y, z);
+        // SAFETY: the caller must guarantee that `x` and `y` are valid
+        // for writes, properly aligned, and non-overlapping.
+        unsafe {
+            let z = read(x);
+            copy_nonoverlapping(y, x, 1);
+            write(y, z);
+        }
     } else {
-        swap_nonoverlapping(x, y, 1);
+        // SAFETY: the caller must uphold the safety contract for `swap_nonoverlapping`.
+        unsafe { swap_nonoverlapping(x, y, 1) };
     }
 }
 
@@ -471,14 +486,23 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) {
         // Declaring `t` here avoids aligning the stack when this loop is unused
         let mut t = mem::MaybeUninit::<Block>::uninit();
         let t = t.as_mut_ptr() as *mut u8;
-        let x = x.add(i);
-        let y = y.add(i);
 
-        // Swap a block of bytes of x & y, using t as a temporary buffer
-        // This should be optimized into efficient SIMD operations where available
-        copy_nonoverlapping(x, t, block_size);
-        copy_nonoverlapping(y, x, block_size);
-        copy_nonoverlapping(t, y, block_size);
+        // SAFETY: As `i < len`, and as the caller must guarantee that `x` and `y` are valid
+        // for `len` bytes, `x + i` and `y + i` must be valid adresses, which fulfills the
+        // safety contract for `add`.
+        //
+        // Also, the caller must guarantee that `x` and `y` are valid for writes, properly aligned,
+        // and non-overlapping, which fulfills the safety contract for `copy_nonoverlapping`.
+        unsafe {
+            let x = x.add(i);
+            let y = y.add(i);
+
+            // Swap a block of bytes of x & y, using t as a temporary buffer
+            // This should be optimized into efficient SIMD operations where available
+            copy_nonoverlapping(x, t, block_size);
+            copy_nonoverlapping(y, x, block_size);
+            copy_nonoverlapping(t, y, block_size);
+        }
         i += block_size;
     }
 
@@ -488,12 +512,16 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) {
         let rem = len - i;
 
         let t = t.as_mut_ptr() as *mut u8;
-        let x = x.add(i);
-        let y = y.add(i);
 
-        copy_nonoverlapping(x, t, rem);
-        copy_nonoverlapping(y, x, rem);
-        copy_nonoverlapping(t, y, rem);
+        // SAFETY: see previous safety comment.
+        unsafe {
+            let x = x.add(i);
+            let y = y.add(i);
+
+            copy_nonoverlapping(x, t, rem);
+            copy_nonoverlapping(y, x, rem);
+            copy_nonoverlapping(t, y, rem);
+        }
     }
 }
 
@@ -540,7 +568,13 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) {
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
-    mem::swap(&mut *dst, &mut src); // cannot overlap
+    // SAFETY: the caller must guarantee that `dst` is valid to be
+    // cast to a mutable reference (valid for writes, aligned, initialized),
+    // and cannot overlap `src` since `dst` must point to a distinct
+    // allocated object.
+    unsafe {
+        mem::swap(&mut *dst, &mut src); // cannot overlap
+    }
     src
 }
 
@@ -658,8 +692,16 @@ pub unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
 pub unsafe fn read<T>(src: *const T) -> T {
     // `copy_nonoverlapping` takes care of debug_assert.
     let mut tmp = MaybeUninit::<T>::uninit();
-    copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
-    tmp.assume_init()
+    // SAFETY: the caller must guarantee that `src` is valid for reads.
+    // `src` cannot overlap `tmp` because `tmp` was just allocated on
+    // the stack as a separate allocated object.
+    //
+    // Also, since we just wrote a valid value into `tmp`, it is guaranteed
+    // to be properly initialized.
+    unsafe {
+        copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
+        tmp.assume_init()
+    }
 }
 
 /// Reads the value from `src` without moving it. This leaves the
@@ -752,8 +794,16 @@ pub unsafe fn read<T>(src: *const T) -> T {
 pub unsafe fn read_unaligned<T>(src: *const T) -> T {
     // `copy_nonoverlapping` takes care of debug_assert.
     let mut tmp = MaybeUninit::<T>::uninit();
-    copy_nonoverlapping(src as *const u8, tmp.as_mut_ptr() as *mut u8, mem::size_of::<T>());
-    tmp.assume_init()
+    // SAFETY: the caller must guarantee that `src` is valid for reads.
+    // `src` cannot overlap `tmp` because `tmp` was just allocated on
+    // the stack as a separate allocated object.
+    //
+    // Also, since we just wrote a valid value into `tmp`, it is guaranteed
+    // to be properly initialized.
+    unsafe {
+        copy_nonoverlapping(src as *const u8, tmp.as_mut_ptr() as *mut u8, mem::size_of::<T>());
+        tmp.assume_init()
+    }
 }
 
 /// Overwrites a memory location with the given value without reading or
@@ -847,7 +897,8 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
         // Not panicking to keep codegen impact smaller.
         abort();
     }
-    intrinsics::move_val_init(&mut *dst, src)
+    // SAFETY: the caller must uphold the safety contract for `move_val_init`.
+    unsafe { intrinsics::move_val_init(&mut *dst, src) }
 }
 
 /// Overwrites a memory location with the given value without reading or
@@ -939,8 +990,13 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
 #[inline]
 #[stable(feature = "ptr_unaligned", since = "1.17.0")]
 pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
-    // `copy_nonoverlapping` takes care of debug_assert.
-    copy_nonoverlapping(&src as *const T as *const u8, dst as *mut u8, mem::size_of::<T>());
+    // SAFETY: the caller must guarantee that `dst` is valid for writes.
+    // `dst` cannot overlap `src` because the caller has mutable access
+    // to `dst` while `src` is owned by this function.
+    unsafe {
+        // `copy_nonoverlapping` takes care of debug_assert.
+        copy_nonoverlapping(&src as *const T as *const u8, dst as *mut u8, mem::size_of::<T>());
+    }
     mem::forget(src);
 }
 
@@ -1015,7 +1071,8 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
         // Not panicking to keep codegen impact smaller.
         abort();
     }
-    intrinsics::volatile_load(src)
+    // SAFETY: the caller must uphold the safety contract for `volatile_load`.
+    unsafe { intrinsics::volatile_load(src) }
 }
 
 /// Performs a volatile write of a memory location with the given value without
@@ -1087,7 +1144,10 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
         // Not panicking to keep codegen impact smaller.
         abort();
     }
-    intrinsics::volatile_store(dst, src);
+    // SAFETY: the caller must uphold the safety contract for `volatile_store`.
+    unsafe {
+        intrinsics::volatile_store(dst, src);
+    }
 }
 
 /// Align pointer `p`.
@@ -1173,8 +1233,8 @@ pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
     }
 
     let smoda = stride & a_minus_one;
-    // a is power-of-two so cannot be 0. stride = 0 is handled above.
-    let gcdpow = intrinsics::cttz_nonzero(stride).min(intrinsics::cttz_nonzero(a));
+    // SAFETY: a is power-of-two so cannot be 0. stride = 0 is handled above.
+    let gcdpow = unsafe { intrinsics::cttz_nonzero(stride).min(intrinsics::cttz_nonzero(a)) };
     let gcd = 1usize << gcdpow;
 
     if p as usize & (gcd.wrapping_sub(1)) == 0 {
diff --git a/src/libcore/ptr/mut_ptr.rs b/src/libcore/ptr/mut_ptr.rs
index 6b5cd9fdb85..7d4b6339b51 100644
--- a/src/libcore/ptr/mut_ptr.rs
+++ b/src/libcore/ptr/mut_ptr.rs
@@ -89,7 +89,9 @@ impl<T: ?Sized> *mut T {
     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
     #[inline]
     pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
-        if self.is_null() { None } else { Some(&*self) }
+        // SAFETY: the caller must guarantee that `self` is valid for a
+        // reference if it isn't null.
+        if self.is_null() { None } else { unsafe { Some(&*self) } }
     }
 
     /// Calculates the offset from a pointer.
@@ -151,7 +153,10 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        intrinsics::offset(self, count) as *mut T
+        // SAFETY: the caller must uphold the safety contract for `offset`.
+        // The obtained pointer is valid for writes since the caller must
+        // guarantee that it points to the same allocated object as `self`.
+        unsafe { intrinsics::offset(self, count) as *mut T }
     }
 
     /// Calculates the offset from a pointer using wrapping arithmetic.
@@ -270,7 +275,9 @@ impl<T: ?Sized> *mut T {
     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
     #[inline]
     pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> {
-        if self.is_null() { None } else { Some(&mut *self) }
+        // SAFETY: the caller must guarantee that `self` is be valid for
+        // a mutable reference if it isn't null.
+        if self.is_null() { None } else { unsafe { Some(&mut *self) } }
     }
 
     /// Returns whether two pointers are guaranteed to be equal.
@@ -406,7 +413,8 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        (self as *const T).offset_from(origin)
+        // SAFETY: the caller must uphold the safety contract for `offset_from`.
+        unsafe { (self as *const T).offset_from(origin) }
     }
 
     /// Calculates the distance between two pointers. The returned value is in
@@ -518,7 +526,8 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        self.offset(count as isize)
+        // SAFETY: the caller must uphold the safety contract for `offset`.
+        unsafe { self.offset(count as isize) }
     }
 
     /// Calculates the offset from a pointer (convenience for
@@ -581,7 +590,8 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        self.offset((count as isize).wrapping_neg())
+        // SAFETY: the caller must uphold the safety contract for `offset`.
+        unsafe { self.offset((count as isize).wrapping_neg()) }
     }
 
     /// Calculates the offset from a pointer using wrapping arithmetic.
@@ -710,7 +720,8 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        read(self)
+        // SAFETY: the caller must uphold the safety contract for ``.
+        unsafe { read(self) }
     }
 
     /// Performs a volatile read of the value from `self` without moving it. This
@@ -729,7 +740,8 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        read_volatile(self)
+        // SAFETY: the caller must uphold the safety contract for `read_volatile`.
+        unsafe { read_volatile(self) }
     }
 
     /// Reads the value from `self` without moving it. This leaves the
@@ -746,7 +758,8 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        read_unaligned(self)
+        // SAFETY: the caller must uphold the safety contract for `read_unaligned`.
+        unsafe { read_unaligned(self) }
     }
 
     /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
@@ -763,7 +776,8 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        copy(self, dest, count)
+        // SAFETY: the caller must uphold the safety contract for `copy`.
+        unsafe { copy(self, dest, count) }
     }
 
     /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
@@ -780,7 +794,8 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        copy_nonoverlapping(self, dest, count)
+        // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
+        unsafe { copy_nonoverlapping(self, dest, count) }
     }
 
     /// Copies `count * size_of<T>` bytes from `src` to `self`. The source
@@ -797,7 +812,8 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        copy(src, self, count)
+        // SAFETY: the caller must uphold the safety contract for `copy`.
+        unsafe { copy(src, self, count) }
     }
 
     /// Copies `count * size_of<T>` bytes from `src` to `self`. The source
@@ -814,7 +830,8 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        copy_nonoverlapping(src, self, count)
+        // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
+        unsafe { copy_nonoverlapping(src, self, count) }
     }
 
     /// Executes the destructor (if any) of the pointed-to value.
@@ -825,7 +842,8 @@ impl<T: ?Sized> *mut T {
     #[stable(feature = "pointer_methods", since = "1.26.0")]
     #[inline]
     pub unsafe fn drop_in_place(self) {
-        drop_in_place(self)
+        // SAFETY: the caller must uphold the safety contract for `drop_in_place`.
+        unsafe { drop_in_place(self) }
     }
 
     /// Overwrites a memory location with the given value without reading or
@@ -840,7 +858,8 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        write(self, val)
+        // SAFETY: the caller must uphold the safety contract for `write`.
+        unsafe { write(self, val) }
     }
 
     /// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
@@ -855,7 +874,8 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        write_bytes(self, val, count)
+        // SAFETY: the caller must uphold the safety contract for `write_bytes`.
+        unsafe { write_bytes(self, val, count) }
     }
 
     /// Performs a volatile write of a memory location with the given value without
@@ -874,7 +894,8 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        write_volatile(self, val)
+        // SAFETY: the caller must uphold the safety contract for `write_volatile`.
+        unsafe { write_volatile(self, val) }
     }
 
     /// Overwrites a memory location with the given value without reading or
@@ -891,7 +912,8 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        write_unaligned(self, val)
+        // SAFETY: the caller must uphold the safety contract for `write_unaligned`.
+        unsafe { write_unaligned(self, val) }
     }
 
     /// Replaces the value at `self` with `src`, returning the old
@@ -906,7 +928,8 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        replace(self, src)
+        // SAFETY: the caller must uphold the safety contract for `replace`.
+        unsafe { replace(self, src) }
     }
 
     /// Swaps the values at two mutable locations of the same type, without
@@ -922,7 +945,8 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        swap(self, with)
+        // SAFETY: the caller must uphold the safety contract for `swap`.
+        unsafe { swap(self, with) }
     }
 
     /// Computes the offset that needs to be applied to the pointer in order to make it aligned to
diff --git a/src/libcore/ptr/non_null.rs b/src/libcore/ptr/non_null.rs
index 870364a61dd..c2d31bfb6a4 100644
--- a/src/libcore/ptr/non_null.rs
+++ b/src/libcore/ptr/non_null.rs
@@ -87,7 +87,8 @@ impl<T: ?Sized> NonNull<T> {
     #[rustc_const_stable(feature = "const_nonnull_new_unchecked", since = "1.32.0")]
     #[inline]
     pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
-        NonNull { pointer: ptr as _ }
+        // SAFETY: the caller must guarantee that `ptr` is non-null.
+        unsafe { NonNull { pointer: ptr as _ } }
     }
 
     /// Creates a new `NonNull` if `ptr` is non-null.
@@ -118,7 +119,9 @@ impl<T: ?Sized> NonNull<T> {
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[inline]
     pub unsafe fn as_ref(&self) -> &T {
-        &*self.as_ptr()
+        // SAFETY: the caller must guarantee that `self` meets all the
+        // requirements for a reference.
+        unsafe { &*self.as_ptr() }
     }
 
     /// Mutably dereferences the content.
@@ -129,7 +132,9 @@ impl<T: ?Sized> NonNull<T> {
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[inline]
     pub unsafe fn as_mut(&mut self) -> &mut T {
-        &mut *self.as_ptr()
+        // SAFETY: the caller must guarantee that `self` meets all the
+        // requirements for a mutable reference.
+        unsafe { &mut *self.as_ptr() }
     }
 
     /// Casts to a pointer of another type.
diff --git a/src/libcore/ptr/unique.rs b/src/libcore/ptr/unique.rs
index f58d35f0613..78647eee338 100644
--- a/src/libcore/ptr/unique.rs
+++ b/src/libcore/ptr/unique.rs
@@ -87,7 +87,8 @@ impl<T: ?Sized> Unique<T> {
     /// `ptr` must be non-null.
     #[inline]
     pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
-        Unique { pointer: ptr as _, _marker: PhantomData }
+        // SAFETY: the caller must guarantee that `ptr` is non-null.
+        unsafe { Unique { pointer: ptr as _, _marker: PhantomData } }
     }
 
     /// Creates a new `Unique` if `ptr` is non-null.
@@ -114,7 +115,9 @@ impl<T: ?Sized> Unique<T> {
     /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
     #[inline]
     pub unsafe fn as_ref(&self) -> &T {
-        &*self.as_ptr()
+        // SAFETY: the caller must guarantee that `self` meets all the
+        // requirements for a reference.
+        unsafe { &*self.as_ptr() }
     }
 
     /// Mutably dereferences the content.
@@ -124,7 +127,9 @@ impl<T: ?Sized> Unique<T> {
     /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
     #[inline]
     pub unsafe fn as_mut(&mut self) -> &mut T {
-        &mut *self.as_ptr()
+        // SAFETY: the caller must guarantee that `self` meets all the
+        // requirements for a mutable reference.
+        unsafe { &mut *self.as_ptr() }
     }
 
     /// Casts to a pointer of another type.
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index ad9c43eccc1..71d63a7115d 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -8,7 +8,6 @@
 //! [`std::slice`]: ../../std/slice/index.html
 
 #![stable(feature = "rust1", since = "1.0.0")]
-#![deny(unsafe_op_in_unsafe_fn)]
 
 // How this module is organized.
 //
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index cbbeaa81d45..0014501d2c4 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -7,7 +7,6 @@
 //! [`std::str`]: ../../std/str/index.html
 
 #![stable(feature = "rust1", since = "1.0.0")]
-#![deny(unsafe_op_in_unsafe_fn)]
 
 use self::pattern::Pattern;
 use self::pattern::{DoubleEndedSearcher, ReverseSearcher, Searcher};
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 359c39a065f..fcae6c86774 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -115,7 +115,6 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))]
 #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))]
-#![deny(unsafe_op_in_unsafe_fn)]
 
 use self::Ordering::*;