From a1623ff3b6a48e7ac29e1c25900989851278743b Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Tue, 30 Jun 2020 19:10:22 +0200 Subject: [PATCH] Deny unsafe ops in unsafe fns, part 6 And final part!!! --- src/libcore/alloc/mod.rs | 1 - src/libcore/cell.rs | 1 - src/libcore/char/convert.rs | 2 - src/libcore/char/methods.rs | 2 - src/libcore/convert/num.rs | 2 - src/libcore/ffi.rs | 1 - src/libcore/future/mod.rs | 4 +- src/libcore/hash/sip.rs | 1 - src/libcore/hint.rs | 2 - src/libcore/intrinsics.rs | 1 - src/libcore/iter/mod.rs | 1 - src/libcore/lib.rs | 9 ++- src/libcore/mem/mod.rs | 1 - src/libcore/num/f32.rs | 1 - src/libcore/num/f64.rs | 1 - src/libcore/num/mod.rs | 1 - src/libcore/pin.rs | 1 - src/libcore/ptr/const_ptr.rs | 31 ++++++--- src/libcore/ptr/mod.rs | 126 ++++++++++++++++++++++++++--------- src/libcore/ptr/mut_ptr.rs | 64 ++++++++++++------ src/libcore/ptr/non_null.rs | 11 ++- src/libcore/ptr/unique.rs | 11 ++- src/libcore/slice/mod.rs | 1 - src/libcore/str/mod.rs | 1 - src/libcore/sync/atomic.rs | 1 - 25 files changed, 185 insertions(+), 93 deletions(-) diff --git a/src/libcore/alloc/mod.rs b/src/libcore/alloc/mod.rs index d00dbd2c34d56..be4e051b1ca42 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 caaf940b62cb2..51d9695687f4a 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 001362ba1c375..c329eec76ac3d 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 5a62c92694fad..72555d781ed38 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 094618acc5885..336c0b26bc7d7 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 dda1d3467b66f..ca4632006509f 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 9dbc23f5c04c5..2555d91ae8d9a 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 84148058d03f7..f2bbf646f3272 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 fd2d443dde8d8..9ebcde79b633d 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 237c6e0545f8f..3c0d5f8bfe7be 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 4a1f6418bb5b3..080b70c6368b2 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 1459a6b2f16f7..81c2344e205c5 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 20ea83fd063c6..272088815ece9 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 028beb86e68ba..061d1ea6b1c46 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 74e38c128b377..b0df4d64f6ee1 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 918eea7acb3ad..2ded2e9c086c8 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 b042bed681e38..da299f026f8f1 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 64a506a6377f2..d1d7a71523822 100644 --- a/src/libcore/ptr/const_ptr.rs +++ b/src/libcore/ptr/const_ptr.rs @@ -95,7 +95,9 @@ impl *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 *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 *const T { { let pointee_size = mem::size_of::(); 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 *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 *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 *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 *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 *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` bytes from `self` to `dest`. The source @@ -716,7 +725,8 @@ impl *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` bytes from `self` to `dest`. The source @@ -733,7 +743,8 @@ impl *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 ca2b0c85ec121..5f028f9ea76ca 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(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(x: *mut T, y: *mut T) { let mut tmp = MaybeUninit::::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::()` bytes between the two regions of memory @@ -432,7 +440,9 @@ pub unsafe fn swap_nonoverlapping(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::() * 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(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::() < 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::::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(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(dst: *mut T, mut src: T) -> T { pub unsafe fn read(src: *const T) -> T { // `copy_nonoverlapping` takes care of debug_assert. let mut tmp = MaybeUninit::::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(src: *const T) -> T { pub unsafe fn read_unaligned(src: *const T) -> T { // `copy_nonoverlapping` takes care of debug_assert. let mut tmp = MaybeUninit::::uninit(); - copy_nonoverlapping(src as *const u8, tmp.as_mut_ptr() as *mut u8, mem::size_of::()); - 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::()); + tmp.assume_init() + } } /// Overwrites a memory location with the given value without reading or @@ -847,7 +897,8 @@ pub unsafe fn write(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(dst: *mut T, src: T) { #[inline] #[stable(feature = "ptr_unaligned", since = "1.17.0")] pub unsafe fn write_unaligned(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::()); + // 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::()); + } mem::forget(src); } @@ -1015,7 +1071,8 @@ pub unsafe fn read_volatile(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(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(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 6b5cd9fdb854d..7d4b6339b511f 100644 --- a/src/libcore/ptr/mut_ptr.rs +++ b/src/libcore/ptr/mut_ptr.rs @@ -89,7 +89,9 @@ impl *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 *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 *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 *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 *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 *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 *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 *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 *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` bytes from `self` to `dest`. The source @@ -763,7 +776,8 @@ impl *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` bytes from `self` to `dest`. The source @@ -780,7 +794,8 @@ impl *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` bytes from `src` to `self`. The source @@ -797,7 +812,8 @@ impl *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` bytes from `src` to `self`. The source @@ -814,7 +830,8 @@ impl *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 *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 *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::()` @@ -855,7 +874,8 @@ impl *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 *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 *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 *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 *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 870364a61dd47..c2d31bfb6a4ee 100644 --- a/src/libcore/ptr/non_null.rs +++ b/src/libcore/ptr/non_null.rs @@ -87,7 +87,8 @@ impl NonNull { #[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 NonNull { #[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 NonNull { #[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 f58d35f06137d..78647eee3389a 100644 --- a/src/libcore/ptr/unique.rs +++ b/src/libcore/ptr/unique.rs @@ -87,7 +87,8 @@ impl Unique { /// `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 Unique { /// (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 Unique { /// (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 ad9c43eccc12e..71d63a7115dbe 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 cbbeaa81d4572..0014501d2c4d0 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 359c39a065f51..fcae6c86774f2 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::*;