Skip to content

Rollup of 6 pull requests #71496

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Apr 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
37514de
Document unsafety in `core::option`
LeSeulArtichaut Apr 11, 2020
d1ce7ff
Document unsafety in `src/libcore/hash/mod.rs`
LeSeulArtichaut Apr 11, 2020
b84f981
Document unsafety in `src/libcore/hash/sip.rs`
LeSeulArtichaut Apr 12, 2020
3eea7b3
Make the `structural_match` error diagnostic for const generics clearer
varkor Apr 6, 2020
f8b796b
Add error message for using type parameter as the type of a const par…
varkor Apr 20, 2020
c16b6e0
Add leading 0x to offset in Debug fmt of Pointer
divergentdave Apr 23, 2020
baac961
fix error code for E0751
contrun Apr 22, 2020
aa0175c
Stabilize UNICODE_VERSION (feature unicode_version)
pyfisch Apr 12, 2020
3029e9e
Add note about padding
LeSeulArtichaut Apr 23, 2020
a694315
Add a note about fat pointers
LeSeulArtichaut Apr 23, 2020
d515168
Document unsafety in `core::{panicking, alloc::layout, hint, iter::ad…
LeSeulArtichaut Apr 23, 2020
45e04fe
Rollup merge of #70845 - varkor:const-generics-derive-eq-diagnostic, …
Dylan-DPC Apr 24, 2020
9ff020e
Rollup merge of #71063 - LeSeulArtichaut:document-unsafe, r=Mark-Simu…
Dylan-DPC Apr 24, 2020
c33deb9
Rollup merge of #71068 - pyfisch:unicode-version-stable, r=SimonSapin
Dylan-DPC Apr 24, 2020
fa7fb93
Rollup merge of #71426 - contrun:fix-e0751-explanation, r=estebank
Dylan-DPC Apr 24, 2020
ed25ca0
Rollup merge of #71459 - divergentdave:pointer-offset-0x, r=RalfJung
Dylan-DPC Apr 24, 2020
8a0e88e
Rollup merge of #71492 - LeSeulArtichaut:document-unsafe-2, r=Mark-Si…
Dylan-DPC Apr 24, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions src/libcore/alloc/layout.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// ignore-tidy-undocumented-unsafe

use crate::cmp;
use crate::fmt;
use crate::mem;
Expand Down Expand Up @@ -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)) }
}

Expand Down Expand Up @@ -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.
Expand All @@ -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) }
}

Expand All @@ -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) }
}

Expand Down Expand Up @@ -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
Expand Down
4 changes: 1 addition & 3 deletions src/libcore/char/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
16 changes: 14 additions & 2 deletions src/libcore/hash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@
//! }
//! ```

// ignore-tidy-undocumented-unsafe

#![stable(feature = "rust1", since = "1.0.0")]

use crate::fmt;
Expand Down Expand Up @@ -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) })
}
}
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
11 changes: 8 additions & 3 deletions src/libcore/hash/sip.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! An implementation of SipHash.

// ignore-tidy-undocumented-unsafe

#![allow(deprecated)] // the types in this module are deprecated

use crate::cmp;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down
9 changes: 7 additions & 2 deletions src/libcore/hint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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() };
}
}
Expand All @@ -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() };
}
}
Expand Down Expand Up @@ -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
Expand Down
10 changes: 8 additions & 2 deletions src/libcore/iter/adapters/zip.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// ignore-tidy-undocumented-unsafe

use crate::cmp;

use super::super::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedLen};
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand Down Expand Up @@ -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
Expand Down
8 changes: 6 additions & 2 deletions src/libcore/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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)) }
}

Expand All @@ -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)) }
}

Expand Down Expand Up @@ -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() },
}
}
Expand Down
7 changes: 5 additions & 2 deletions src/libcore/panicking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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() }
}

Expand All @@ -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() }
}

Expand All @@ -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() }
}

Expand All @@ -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() }
}

Expand All @@ -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) }
}
7 changes: 6 additions & 1 deletion src/libcore/unicode/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_error_codes/error_codes/E0751.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ There are both a positive and negative trait implementation for the same type.

Erroneous code example:

```compile_fail,E0748
```compile_fail,E0751
trait MyTrait {}
impl MyTrait for i32 { }
impl !MyTrait for i32 { }
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_middle/mir/interpret/pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,13 @@ static_assert_size!(Pointer, 16);

impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for Pointer<Tag, Id> {
default fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}+{:x}[{:?}]", self.alloc_id, self.offset.bytes(), self.tag)
write!(f, "{:?}+0x{:x}[{:?}]", self.alloc_id, self.offset.bytes(), self.tag)
}
}
// Specialization for no tag
impl<Id: fmt::Debug> fmt::Debug for Pointer<(), Id> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}+{:x}", self.alloc_id, self.offset.bytes())
write!(f, "{:?}+0x{:x}", self.alloc_id, self.offset.bytes())
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trait_selection/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ fn report_negative_positive_conflict(
let mut err = struct_span_err!(
tcx.sess,
impl_span,
E0748,
E0751,
"found both positive and negative implementation of trait `{}`{}:",
overlap.trait_desc,
overlap.self_desc.clone().map_or(String::new(), |ty| format!(" for type `{}`", ty))
Expand Down
Loading