about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeSeulArtichaut <leseulartichaut@gmail.com>2020-04-23 23:21:53 +0200
committerLeSeulArtichaut <leseulartichaut@gmail.com>2020-04-24 01:48:48 +0200
commitd515168f3ba481ee633099753f75e4e62750e6b4 (patch)
treea86c94e3ff0a18d9723831151db3e02ce4decfb8
parent413a12909f3b149af17d75268ed4a136afb82c36 (diff)
downloadrust-d515168f3ba481ee633099753f75e4e62750e6b4.tar.gz
rust-d515168f3ba481ee633099753f75e4e62750e6b4.zip
Document unsafety in `core::{panicking, alloc::layout, hint, iter::adapters::zip}`
-rw-r--r--src/libcore/alloc/layout.rs18
-rw-r--r--src/libcore/hint.rs9
-rw-r--r--src/libcore/iter/adapters/zip.rs10
-rw-r--r--src/libcore/panicking.rs7
4 files changed, 28 insertions, 16 deletions
diff --git a/src/libcore/alloc/layout.rs b/src/libcore/alloc/layout.rs
index 6200cd24266..a09c2387d0d 100644
--- a/src/libcore/alloc/layout.rs
+++ b/src/libcore/alloc/layout.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-undocumented-unsafe
-
 use crate::cmp;
 use crate::fmt;
 use crate::mem;
@@ -77,6 +75,8 @@ impl Layout {
             return Err(LayoutErr { private: () });
         }
 
+        // SAFETY: the conditions for `from_size_align_unchecked` have been
+        // checked above.
         unsafe { Ok(Layout::from_size_align_unchecked(size, align)) }
     }
 
@@ -115,7 +115,7 @@ impl Layout {
     #[inline]
     pub const fn new<T>() -> Self {
         let (size, align) = size_align::<T>();
-        // Note that the align is guaranteed by rustc to be a power of two and
+        // SAFETY: the align is guaranteed by Rust to be a power of two and
         // the size+align combo is guaranteed to fit in our address space. As a
         // result use the unchecked constructor here to avoid inserting code
         // that panics if it isn't optimized well enough.
@@ -129,8 +129,8 @@ impl Layout {
     #[inline]
     pub fn for_value<T: ?Sized>(t: &T) -> Self {
         let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
-        // See rationale in `new` for why this is using an unsafe variant below
         debug_assert!(Layout::from_size_align(size, align).is_ok());
+        // SAFETY: see rationale in `new` for why this is using an unsafe variant below
         unsafe { Layout::from_size_align_unchecked(size, align) }
     }
 
@@ -143,7 +143,7 @@ impl Layout {
     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
     #[inline]
     pub const fn dangling(&self) -> NonNull<u8> {
-        // align is non-zero and a power of two
+        // SAFETY: align is guaranteed to be non-zero
         unsafe { NonNull::new_unchecked(self.align() as *mut u8) }
     }
 
@@ -249,11 +249,9 @@ impl Layout {
         let padded_size = self.size() + self.padding_needed_for(self.align());
         let alloc_size = padded_size.checked_mul(n).ok_or(LayoutErr { private: () })?;
 
-        unsafe {
-            // self.align is already known to be valid and alloc_size has been
-            // padded already.
-            Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size))
-        }
+        // SAFETY: self.align is already known to be valid and alloc_size has been
+        // padded already.
+        unsafe { Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size)) }
     }
 
     /// Creates a layout describing the record for `self` followed by
diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index d406b3ce6ef..0d794de5fe8 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.
 
-// ignore-tidy-undocumented-unsafe
-
 use crate::intrinsics;
 
 /// Informs the compiler that this point in the code is not reachable, enabling
@@ -68,11 +66,13 @@ pub fn spin_loop() {
     {
         #[cfg(target_arch = "x86")]
         {
+            // SAFETY: the `cfg` attr ensures that we only execute this on x86 targets.
             unsafe { crate::arch::x86::_mm_pause() };
         }
 
         #[cfg(target_arch = "x86_64")]
         {
+            // SAFETY: the `cfg` attr ensures that we only execute this on x86_64 targets.
             unsafe { crate::arch::x86_64::_mm_pause() };
         }
     }
@@ -81,10 +81,13 @@ pub fn spin_loop() {
     {
         #[cfg(target_arch = "aarch64")]
         {
+            // SAFETY: the `cfg` attr ensures that we only execute this on aarch64 targets.
             unsafe { crate::arch::aarch64::__yield() };
         }
         #[cfg(target_arch = "arm")]
         {
+            // SAFETY: the `cfg` attr ensures that we only execute this on arm targets
+            // with support for the v6 feature.
             unsafe { crate::arch::arm::__yield() };
         }
     }
@@ -112,6 +115,8 @@ pub fn black_box<T>(dummy: T) -> T {
     // this. LLVM's interpretation of inline assembly is that it's, well, a black
     // box. This isn't the greatest implementation since it probably deoptimizes
     // more than we want, but it's so far good enough.
+
+    // SAFETY: the inline assembly is a no-op.
     unsafe {
         llvm_asm!("" : : "r"(&dummy));
         dummy
diff --git a/src/libcore/iter/adapters/zip.rs b/src/libcore/iter/adapters/zip.rs
index b13e12e2e86..e83d36a580f 100644
--- a/src/libcore/iter/adapters/zip.rs
+++ b/src/libcore/iter/adapters/zip.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-undocumented-unsafe
-
 use crate::cmp;
 
 use super::super::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedLen};
@@ -176,9 +174,11 @@ where
         if self.index < self.len {
             let i = self.index;
             self.index += 1;
+            // SAFETY: `i` is smaller than `self.len`, thus smaller than `self.a.len()` and `self.b.len()`
             unsafe { Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) }
         } else if A::may_have_side_effect() && self.index < self.a.len() {
             // match the base implementation's potential side effects
+            // SAFETY: we just checked that `self.index` < `self.a.len()`
             unsafe {
                 self.a.get_unchecked(self.index);
             }
@@ -203,11 +203,15 @@ where
             let i = self.index;
             self.index += 1;
             if A::may_have_side_effect() {
+                // SAFETY: the usage of `cmp::min` to calculate `delta`
+                // ensures that `end` is smaller than or equal to `self.len`,
+                // so `i` is also smaller than `self.len`.
                 unsafe {
                     self.a.get_unchecked(i);
                 }
             }
             if B::may_have_side_effect() {
+                // SAFETY: same as above.
                 unsafe {
                     self.b.get_unchecked(i);
                 }
@@ -243,6 +247,8 @@ where
         if self.index < self.len {
             self.len -= 1;
             let i = self.len;
+            // SAFETY: `i` is smaller than the previous value of `self.len`,
+            // which is also smaller than or equal to `self.a.len()` and `self.b.len()`
             unsafe { Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) }
         } else {
             None
diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs
index 3587f3f0ebf..1e4209fd26b 100644
--- a/src/libcore/panicking.rs
+++ b/src/libcore/panicking.rs
@@ -19,8 +19,6 @@
 //! necessary lang items for the compiler. All panics are funneled through this
 //! one function. The actual symbol is declared through the `#[panic_handler]` attribute.
 
-// ignore-tidy-undocumented-unsafe
-
 #![allow(dead_code, missing_docs)]
 #![unstable(
     feature = "core_panic",
@@ -41,6 +39,7 @@ use crate::panic::{Location, PanicInfo};
 #[lang = "panic"] // needed by codegen for panic on overflow and other `Assert` MIR terminators
 pub fn panic(expr: &str) -> ! {
     if cfg!(feature = "panic_immediate_abort") {
+        // SAFETY: the `abort` intrinsic has no requirements to be called.
         unsafe { super::intrinsics::abort() }
     }
 
@@ -63,6 +62,7 @@ pub fn panic(expr: &str) -> ! {
 #[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
 fn panic_bounds_check(index: usize, len: usize) -> ! {
     if cfg!(feature = "panic_immediate_abort") {
+        // SAFETY: the `abort` intrinsic has no requirements to be called.
         unsafe { super::intrinsics::abort() }
     }
 
@@ -77,6 +77,7 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
 #[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
 fn panic_bounds_check(location: &Location<'_>, index: usize, len: usize) -> ! {
     if cfg!(feature = "panic_immediate_abort") {
+        // SAFETY: the `abort` intrinsic has no requirements to be called.
         unsafe { super::intrinsics::abort() }
     }
 
@@ -93,6 +94,7 @@ fn panic_bounds_check(location: &Location<'_>, index: usize, len: usize) -> ! {
 #[cfg_attr(not(bootstrap), track_caller)]
 pub fn panic_fmt(fmt: fmt::Arguments<'_>, #[cfg(bootstrap)] location: &Location<'_>) -> ! {
     if cfg!(feature = "panic_immediate_abort") {
+        // SAFETY: the `abort` intrinsic has no requirements to be called.
         unsafe { super::intrinsics::abort() }
     }
 
@@ -108,5 +110,6 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>, #[cfg(bootstrap)] location: &Location<
     #[cfg(not(bootstrap))]
     let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller());
 
+    // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
     unsafe { panic_impl(&pi) }
 }