Document unsafety in core::{panicking, alloc::layout, hint, iter::adapters::zip}
This commit is contained in:
parent
413a12909f
commit
d515168f3b
@ -1,5 +1,3 @@
|
|||||||
// ignore-tidy-undocumented-unsafe
|
|
||||||
|
|
||||||
use crate::cmp;
|
use crate::cmp;
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::mem;
|
use crate::mem;
|
||||||
@ -77,6 +75,8 @@ impl Layout {
|
|||||||
return Err(LayoutErr { private: () });
|
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)) }
|
unsafe { Ok(Layout::from_size_align_unchecked(size, align)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ impl Layout {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub const fn new<T>() -> Self {
|
pub const fn new<T>() -> Self {
|
||||||
let (size, align) = size_align::<T>();
|
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
|
// the size+align combo is guaranteed to fit in our address space. As a
|
||||||
// result use the unchecked constructor here to avoid inserting code
|
// result use the unchecked constructor here to avoid inserting code
|
||||||
// that panics if it isn't optimized well enough.
|
// that panics if it isn't optimized well enough.
|
||||||
@ -129,8 +129,8 @@ impl Layout {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn for_value<T: ?Sized>(t: &T) -> Self {
|
pub fn for_value<T: ?Sized>(t: &T) -> Self {
|
||||||
let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
|
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());
|
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) }
|
unsafe { Layout::from_size_align_unchecked(size, align) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ impl Layout {
|
|||||||
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
|
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn dangling(&self) -> NonNull<u8> {
|
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) }
|
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 padded_size = self.size() + self.padding_needed_for(self.align());
|
||||||
let alloc_size = padded_size.checked_mul(n).ok_or(LayoutErr { private: () })?;
|
let alloc_size = padded_size.checked_mul(n).ok_or(LayoutErr { private: () })?;
|
||||||
|
|
||||||
unsafe {
|
// SAFETY: self.align is already known to be valid and alloc_size has been
|
||||||
// self.align is already known to be valid and alloc_size has been
|
// padded already.
|
||||||
// padded already.
|
unsafe { Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size)) }
|
||||||
Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a layout describing the record for `self` followed by
|
/// Creates a layout describing the record for `self` followed by
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
//! Hints to compiler that affects how code should be emitted or optimized.
|
//! Hints to compiler that affects how code should be emitted or optimized.
|
||||||
|
|
||||||
// ignore-tidy-undocumented-unsafe
|
|
||||||
|
|
||||||
use crate::intrinsics;
|
use crate::intrinsics;
|
||||||
|
|
||||||
/// Informs the compiler that this point in the code is not reachable, enabling
|
/// 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")]
|
#[cfg(target_arch = "x86")]
|
||||||
{
|
{
|
||||||
|
// SAFETY: the `cfg` attr ensures that we only execute this on x86 targets.
|
||||||
unsafe { crate::arch::x86::_mm_pause() };
|
unsafe { crate::arch::x86::_mm_pause() };
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[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() };
|
unsafe { crate::arch::x86_64::_mm_pause() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,10 +81,13 @@ pub fn spin_loop() {
|
|||||||
{
|
{
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
{
|
{
|
||||||
|
// SAFETY: the `cfg` attr ensures that we only execute this on aarch64 targets.
|
||||||
unsafe { crate::arch::aarch64::__yield() };
|
unsafe { crate::arch::aarch64::__yield() };
|
||||||
}
|
}
|
||||||
#[cfg(target_arch = "arm")]
|
#[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() };
|
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
|
// 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
|
// box. This isn't the greatest implementation since it probably deoptimizes
|
||||||
// more than we want, but it's so far good enough.
|
// more than we want, but it's so far good enough.
|
||||||
|
|
||||||
|
// SAFETY: the inline assembly is a no-op.
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm_asm!("" : : "r"(&dummy));
|
llvm_asm!("" : : "r"(&dummy));
|
||||||
dummy
|
dummy
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
// ignore-tidy-undocumented-unsafe
|
|
||||||
|
|
||||||
use crate::cmp;
|
use crate::cmp;
|
||||||
|
|
||||||
use super::super::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedLen};
|
use super::super::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedLen};
|
||||||
@ -176,9 +174,11 @@ where
|
|||||||
if self.index < self.len {
|
if self.index < self.len {
|
||||||
let i = self.index;
|
let i = self.index;
|
||||||
self.index += 1;
|
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))) }
|
unsafe { Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) }
|
||||||
} else if A::may_have_side_effect() && self.index < self.a.len() {
|
} else if A::may_have_side_effect() && self.index < self.a.len() {
|
||||||
// match the base implementation's potential side effects
|
// match the base implementation's potential side effects
|
||||||
|
// SAFETY: we just checked that `self.index` < `self.a.len()`
|
||||||
unsafe {
|
unsafe {
|
||||||
self.a.get_unchecked(self.index);
|
self.a.get_unchecked(self.index);
|
||||||
}
|
}
|
||||||
@ -203,11 +203,15 @@ where
|
|||||||
let i = self.index;
|
let i = self.index;
|
||||||
self.index += 1;
|
self.index += 1;
|
||||||
if A::may_have_side_effect() {
|
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 {
|
unsafe {
|
||||||
self.a.get_unchecked(i);
|
self.a.get_unchecked(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if B::may_have_side_effect() {
|
if B::may_have_side_effect() {
|
||||||
|
// SAFETY: same as above.
|
||||||
unsafe {
|
unsafe {
|
||||||
self.b.get_unchecked(i);
|
self.b.get_unchecked(i);
|
||||||
}
|
}
|
||||||
@ -243,6 +247,8 @@ where
|
|||||||
if self.index < self.len {
|
if self.index < self.len {
|
||||||
self.len -= 1;
|
self.len -= 1;
|
||||||
let i = self.len;
|
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))) }
|
unsafe { Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) }
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -19,8 +19,6 @@
|
|||||||
//! necessary lang items for the compiler. All panics are funneled through this
|
//! necessary lang items for the compiler. All panics are funneled through this
|
||||||
//! one function. The actual symbol is declared through the `#[panic_handler]` attribute.
|
//! one function. The actual symbol is declared through the `#[panic_handler]` attribute.
|
||||||
|
|
||||||
// ignore-tidy-undocumented-unsafe
|
|
||||||
|
|
||||||
#![allow(dead_code, missing_docs)]
|
#![allow(dead_code, missing_docs)]
|
||||||
#![unstable(
|
#![unstable(
|
||||||
feature = "core_panic",
|
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
|
#[lang = "panic"] // needed by codegen for panic on overflow and other `Assert` MIR terminators
|
||||||
pub fn panic(expr: &str) -> ! {
|
pub fn panic(expr: &str) -> ! {
|
||||||
if cfg!(feature = "panic_immediate_abort") {
|
if cfg!(feature = "panic_immediate_abort") {
|
||||||
|
// SAFETY: the `abort` intrinsic has no requirements to be called.
|
||||||
unsafe { super::intrinsics::abort() }
|
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
|
#[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
|
||||||
fn panic_bounds_check(index: usize, len: usize) -> ! {
|
fn panic_bounds_check(index: usize, len: usize) -> ! {
|
||||||
if cfg!(feature = "panic_immediate_abort") {
|
if cfg!(feature = "panic_immediate_abort") {
|
||||||
|
// SAFETY: the `abort` intrinsic has no requirements to be called.
|
||||||
unsafe { super::intrinsics::abort() }
|
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
|
#[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
|
||||||
fn panic_bounds_check(location: &Location<'_>, index: usize, len: usize) -> ! {
|
fn panic_bounds_check(location: &Location<'_>, index: usize, len: usize) -> ! {
|
||||||
if cfg!(feature = "panic_immediate_abort") {
|
if cfg!(feature = "panic_immediate_abort") {
|
||||||
|
// SAFETY: the `abort` intrinsic has no requirements to be called.
|
||||||
unsafe { super::intrinsics::abort() }
|
unsafe { super::intrinsics::abort() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +94,7 @@ fn panic_bounds_check(location: &Location<'_>, index: usize, len: usize) -> ! {
|
|||||||
#[cfg_attr(not(bootstrap), track_caller)]
|
#[cfg_attr(not(bootstrap), track_caller)]
|
||||||
pub fn panic_fmt(fmt: fmt::Arguments<'_>, #[cfg(bootstrap)] location: &Location<'_>) -> ! {
|
pub fn panic_fmt(fmt: fmt::Arguments<'_>, #[cfg(bootstrap)] location: &Location<'_>) -> ! {
|
||||||
if cfg!(feature = "panic_immediate_abort") {
|
if cfg!(feature = "panic_immediate_abort") {
|
||||||
|
// SAFETY: the `abort` intrinsic has no requirements to be called.
|
||||||
unsafe { super::intrinsics::abort() }
|
unsafe { super::intrinsics::abort() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,5 +110,6 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>, #[cfg(bootstrap)] location: &Location<
|
|||||||
#[cfg(not(bootstrap))]
|
#[cfg(not(bootstrap))]
|
||||||
let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller());
|
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) }
|
unsafe { panic_impl(&pi) }
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user