diff options
| author | bors <bors@rust-lang.org> | 2020-04-24 00:49:05 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-04-24 00:49:05 +0000 |
| commit | 45c7838089576552391237bb41cdd3d46582d3e5 (patch) | |
| tree | be8f505326157d0cad29a4ca5c24ad6ce8eafb19 /src/libcore | |
| parent | 14b15521c52549ebbb113173b4abecd124b5a823 (diff) | |
| parent | 8a0e88e653c0382681c81c999dd91ba88ac16568 (diff) | |
| download | rust-45c7838089576552391237bb41cdd3d46582d3e5.tar.gz rust-45c7838089576552391237bb41cdd3d46582d3e5.zip | |
Auto merge of #71496 - Dylan-DPC:rollup-gwxejmk, r=Dylan-DPC
Rollup of 6 pull requests
Successful merges:
- #70845 (Make the `structural_match` error diagnostic for const generics clearer)
- #71063 (Document unsafety in core::{option, hash})
- #71068 (Stabilize UNICODE_VERSION (feature unicode_version))
- #71426 (fix error code in E0751.md)
- #71459 (Add leading 0x to offset in Debug fmt of Pointer)
- #71492 (Document unsafety in core::{panicking, alloc::layout, hint, iter::adapters::zip})
Failed merges:
r? @ghost
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/alloc/layout.rs | 18 | ||||
| -rw-r--r-- | src/libcore/char/mod.rs | 4 | ||||
| -rw-r--r-- | src/libcore/hash/mod.rs | 16 | ||||
| -rw-r--r-- | src/libcore/hash/sip.rs | 11 | ||||
| -rw-r--r-- | src/libcore/hint.rs | 9 | ||||
| -rw-r--r-- | src/libcore/iter/adapters/zip.rs | 10 | ||||
| -rw-r--r-- | src/libcore/option.rs | 8 | ||||
| -rw-r--r-- | src/libcore/panicking.rs | 7 | ||||
| -rw-r--r-- | src/libcore/unicode/mod.rs | 7 |
9 files changed, 63 insertions, 27 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/char/mod.rs b/src/libcore/char/mod.rs index 715ad8992ad..d82a482e0f1 100644 --- a/src/libcore/char/mod.rs +++ b/src/libcore/char/mod.rs @@ -34,9 +34,7 @@ pub use self::convert::ParseCharError; pub use self::convert::{from_digit, from_u32}; #[stable(feature = "decode_utf16", since = "1.9.0")] pub use self::decode::{decode_utf16, DecodeUtf16, DecodeUtf16Error}; - -// unstable re-exports -#[unstable(feature = "unicode_version", issue = "49726")] +#[stable(feature = "unicode_version", since = "1.45.0")] pub use crate::unicode::UNICODE_VERSION; use crate::fmt::{self, Write}; diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index 2a7fa58dd30..d80101753cb 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -79,8 +79,6 @@ //! } //! ``` -// ignore-tidy-undocumented-unsafe - #![stable(feature = "rust1", since = "1.0.0")] use crate::fmt; @@ -572,6 +570,10 @@ mod impls { fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) { let newlen = data.len() * mem::size_of::<$ty>(); let ptr = data.as_ptr() as *const u8; + // SAFETY: `ptr` is valid and aligned, as this macro is only used + // for numeric primitives which have no padding. The new slice only + // spans across `data` and is never mutated, and its total size is the + // same as the original `data` so it can't be over `isize::MAX`. state.write(unsafe { slice::from_raw_parts(ptr, newlen) }) } } @@ -691,6 +693,11 @@ mod impls { state.write_usize(*self as *const () as usize); } else { // Fat pointer + // SAFETY: we are accessing the memory occupied by `self` + // which is guaranteed to be valid. + // This assumes a fat pointer can be represented by a `(usize, usize)`, + // which is safe to do in `std` because it is shipped and kept in sync + // with the implementation of fat pointers in `rustc`. let (a, b) = unsafe { *(self as *const Self as *const (usize, usize)) }; state.write_usize(a); state.write_usize(b); @@ -706,6 +713,11 @@ mod impls { state.write_usize(*self as *const () as usize); } else { // Fat pointer + // SAFETY: we are accessing the memory occupied by `self` + // which is guaranteed to be valid. + // This assumes a fat pointer can be represented by a `(usize, usize)`, + // which is safe to do in `std` because it is shipped and kept in sync + // with the implementation of fat pointers in `rustc`. let (a, b) = unsafe { *(self as *const Self as *const (usize, usize)) }; state.write_usize(a); state.write_usize(b); diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs index adfbe243512..ac058609f45 100644 --- a/src/libcore/hash/sip.rs +++ b/src/libcore/hash/sip.rs @@ -1,7 +1,5 @@ //! An implementation of SipHash. -// ignore-tidy-undocumented-unsafe - #![allow(deprecated)] // the types in this module are deprecated use crate::cmp; @@ -265,6 +263,7 @@ impl<S: Sip> super::Hasher for Hasher<S> { if self.ntail != 0 { needed = 8 - self.ntail; + // SAFETY: `cmp::min(length, needed)` is guaranteed to not be over `length` self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << (8 * self.ntail); if length < needed { self.ntail += length; @@ -279,10 +278,13 @@ impl<S: Sip> super::Hasher for Hasher<S> { // Buffered tail is now flushed, process new input. let len = length - needed; - let left = len & 0x7; + let left = len & 0x7; // len % 8 let mut i = needed; while i < len - left { + // SAFETY: because `len - left` is the biggest multiple of 8 under + // `len`, and because `i` starts at `needed` where `len` is `length - needed`, + // `i + 8` is guaranteed to be less than or equal to `length`. let mi = unsafe { load_int_le!(msg, i, u64) }; self.state.v3 ^= mi; @@ -292,6 +294,9 @@ impl<S: Sip> super::Hasher for Hasher<S> { i += 8; } + // SAFETY: `i` is now `needed + len.div_euclid(8) * 8`, + // so `i + left` = `needed + len` = `length`, which is by + // definition equal to `msg.len()`. self.tail = unsafe { u8to64_le(msg, i, left) }; self.ntail = left; } 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/option.rs b/src/libcore/option.rs index 3aab8b1b333..63a5277100f 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -133,8 +133,6 @@ //! [`Box<T>`]: ../../std/boxed/struct.Box.html //! [`i32`]: ../../std/primitive.i32.html -// ignore-tidy-undocumented-unsafe - #![stable(feature = "rust1", since = "1.0.0")] use crate::iter::{FromIterator, FusedIterator, TrustedLen}; @@ -301,6 +299,8 @@ impl<T> Option<T> { #[inline] #[stable(feature = "pin", since = "1.33.0")] pub fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>> { + // SAFETY: `x` is guaranteed to be pinned because it comes from `self` + // which is pinned. unsafe { Pin::get_ref(self).as_ref().map(|x| Pin::new_unchecked(x)) } } @@ -310,6 +310,8 @@ impl<T> Option<T> { #[inline] #[stable(feature = "pin", since = "1.33.0")] pub fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>> { + // SAFETY: `get_unchecked_mut` is never used to move the `Option` inside `self`. + // `x` is guaranteed to be pinned because it comes from `self` which is pinned. unsafe { Pin::get_unchecked_mut(self).as_mut().map(|x| Pin::new_unchecked(x)) } } @@ -858,6 +860,8 @@ impl<T> Option<T> { match *self { Some(ref mut v) => v, + // SAFETY: a `None` variant for `self` would have been replaced by a `Some` + // variant in the code above. None => unsafe { hint::unreachable_unchecked() }, } } 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) } } diff --git a/src/libcore/unicode/mod.rs b/src/libcore/unicode/mod.rs index 3952ae4482e..28c07f77170 100644 --- a/src/libcore/unicode/mod.rs +++ b/src/libcore/unicode/mod.rs @@ -7,9 +7,14 @@ mod unicode_data; /// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of /// `char` and `str` methods are based on. /// +/// New versions of Unicode are released regularly and subsequently all methods +/// in the standard library depending on Unicode are updated. Therefore the +/// behavior of some `char` and `str` methods and the value of this constant +/// changes over time. This is *not* considered to be a breaking change. +/// /// The version numbering scheme is explained in /// [Unicode 11.0 or later, Section 3.1 Versions of the Unicode Standard](https://www.unicode.org/versions/Unicode11.0.0/ch03.pdf#page=4). -#[unstable(feature = "unicode_version", issue = "49726")] +#[stable(feature = "unicode_version", since = "1.45.0")] pub const UNICODE_VERSION: (u8, u8, u8) = unicode_data::UNICODE_VERSION; // For use in liballoc, not re-exported in libstd. |
