Skip to content

Commit 45c7838

Browse files
committed
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
2 parents 14b1552 + 8a0e88e commit 45c7838

File tree

49 files changed

+185
-119
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+185
-119
lines changed

src/libcore/alloc/layout.rs

+8-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// ignore-tidy-undocumented-unsafe
2-
31
use crate::cmp;
42
use crate::fmt;
53
use crate::mem;
@@ -77,6 +75,8 @@ impl Layout {
7775
return Err(LayoutErr { private: () });
7876
}
7977

78+
// SAFETY: the conditions for `from_size_align_unchecked` have been
79+
// checked above.
8080
unsafe { Ok(Layout::from_size_align_unchecked(size, align)) }
8181
}
8282

@@ -115,7 +115,7 @@ impl Layout {
115115
#[inline]
116116
pub const fn new<T>() -> Self {
117117
let (size, align) = size_align::<T>();
118-
// Note that the align is guaranteed by rustc to be a power of two and
118+
// SAFETY: the align is guaranteed by Rust to be a power of two and
119119
// the size+align combo is guaranteed to fit in our address space. As a
120120
// result use the unchecked constructor here to avoid inserting code
121121
// that panics if it isn't optimized well enough.
@@ -129,8 +129,8 @@ impl Layout {
129129
#[inline]
130130
pub fn for_value<T: ?Sized>(t: &T) -> Self {
131131
let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
132-
// See rationale in `new` for why this is using an unsafe variant below
133132
debug_assert!(Layout::from_size_align(size, align).is_ok());
133+
// SAFETY: see rationale in `new` for why this is using an unsafe variant below
134134
unsafe { Layout::from_size_align_unchecked(size, align) }
135135
}
136136

@@ -143,7 +143,7 @@ impl Layout {
143143
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
144144
#[inline]
145145
pub const fn dangling(&self) -> NonNull<u8> {
146-
// align is non-zero and a power of two
146+
// SAFETY: align is guaranteed to be non-zero
147147
unsafe { NonNull::new_unchecked(self.align() as *mut u8) }
148148
}
149149

@@ -249,11 +249,9 @@ impl Layout {
249249
let padded_size = self.size() + self.padding_needed_for(self.align());
250250
let alloc_size = padded_size.checked_mul(n).ok_or(LayoutErr { private: () })?;
251251

252-
unsafe {
253-
// self.align is already known to be valid and alloc_size has been
254-
// padded already.
255-
Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size))
256-
}
252+
// SAFETY: self.align is already known to be valid and alloc_size has been
253+
// padded already.
254+
unsafe { Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size)) }
257255
}
258256

259257
/// Creates a layout describing the record for `self` followed by

src/libcore/char/mod.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,7 @@ pub use self::convert::ParseCharError;
3434
pub use self::convert::{from_digit, from_u32};
3535
#[stable(feature = "decode_utf16", since = "1.9.0")]
3636
pub use self::decode::{decode_utf16, DecodeUtf16, DecodeUtf16Error};
37-
38-
// unstable re-exports
39-
#[unstable(feature = "unicode_version", issue = "49726")]
37+
#[stable(feature = "unicode_version", since = "1.45.0")]
4038
pub use crate::unicode::UNICODE_VERSION;
4139

4240
use crate::fmt::{self, Write};

src/libcore/hash/mod.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@
7979
//! }
8080
//! ```
8181
82-
// ignore-tidy-undocumented-unsafe
83-
8482
#![stable(feature = "rust1", since = "1.0.0")]
8583

8684
use crate::fmt;
@@ -572,6 +570,10 @@ mod impls {
572570
fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) {
573571
let newlen = data.len() * mem::size_of::<$ty>();
574572
let ptr = data.as_ptr() as *const u8;
573+
// SAFETY: `ptr` is valid and aligned, as this macro is only used
574+
// for numeric primitives which have no padding. The new slice only
575+
// spans across `data` and is never mutated, and its total size is the
576+
// same as the original `data` so it can't be over `isize::MAX`.
575577
state.write(unsafe { slice::from_raw_parts(ptr, newlen) })
576578
}
577579
}
@@ -691,6 +693,11 @@ mod impls {
691693
state.write_usize(*self as *const () as usize);
692694
} else {
693695
// Fat pointer
696+
// SAFETY: we are accessing the memory occupied by `self`
697+
// which is guaranteed to be valid.
698+
// This assumes a fat pointer can be represented by a `(usize, usize)`,
699+
// which is safe to do in `std` because it is shipped and kept in sync
700+
// with the implementation of fat pointers in `rustc`.
694701
let (a, b) = unsafe { *(self as *const Self as *const (usize, usize)) };
695702
state.write_usize(a);
696703
state.write_usize(b);
@@ -706,6 +713,11 @@ mod impls {
706713
state.write_usize(*self as *const () as usize);
707714
} else {
708715
// Fat pointer
716+
// SAFETY: we are accessing the memory occupied by `self`
717+
// which is guaranteed to be valid.
718+
// This assumes a fat pointer can be represented by a `(usize, usize)`,
719+
// which is safe to do in `std` because it is shipped and kept in sync
720+
// with the implementation of fat pointers in `rustc`.
709721
let (a, b) = unsafe { *(self as *const Self as *const (usize, usize)) };
710722
state.write_usize(a);
711723
state.write_usize(b);

src/libcore/hash/sip.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
//! An implementation of SipHash.
22
3-
// ignore-tidy-undocumented-unsafe
4-
53
#![allow(deprecated)] // the types in this module are deprecated
64

75
use crate::cmp;
@@ -265,6 +263,7 @@ impl<S: Sip> super::Hasher for Hasher<S> {
265263

266264
if self.ntail != 0 {
267265
needed = 8 - self.ntail;
266+
// SAFETY: `cmp::min(length, needed)` is guaranteed to not be over `length`
268267
self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << (8 * self.ntail);
269268
if length < needed {
270269
self.ntail += length;
@@ -279,10 +278,13 @@ impl<S: Sip> super::Hasher for Hasher<S> {
279278

280279
// Buffered tail is now flushed, process new input.
281280
let len = length - needed;
282-
let left = len & 0x7;
281+
let left = len & 0x7; // len % 8
283282

284283
let mut i = needed;
285284
while i < len - left {
285+
// SAFETY: because `len - left` is the biggest multiple of 8 under
286+
// `len`, and because `i` starts at `needed` where `len` is `length - needed`,
287+
// `i + 8` is guaranteed to be less than or equal to `length`.
286288
let mi = unsafe { load_int_le!(msg, i, u64) };
287289

288290
self.state.v3 ^= mi;
@@ -292,6 +294,9 @@ impl<S: Sip> super::Hasher for Hasher<S> {
292294
i += 8;
293295
}
294296

297+
// SAFETY: `i` is now `needed + len.div_euclid(8) * 8`,
298+
// so `i + left` = `needed + len` = `length`, which is by
299+
// definition equal to `msg.len()`.
295300
self.tail = unsafe { u8to64_le(msg, i, left) };
296301
self.ntail = left;
297302
}

src/libcore/hint.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
//! Hints to compiler that affects how code should be emitted or optimized.
44
5-
// ignore-tidy-undocumented-unsafe
6-
75
use crate::intrinsics;
86

97
/// Informs the compiler that this point in the code is not reachable, enabling
@@ -68,11 +66,13 @@ pub fn spin_loop() {
6866
{
6967
#[cfg(target_arch = "x86")]
7068
{
69+
// SAFETY: the `cfg` attr ensures that we only execute this on x86 targets.
7170
unsafe { crate::arch::x86::_mm_pause() };
7271
}
7372

7473
#[cfg(target_arch = "x86_64")]
7574
{
75+
// SAFETY: the `cfg` attr ensures that we only execute this on x86_64 targets.
7676
unsafe { crate::arch::x86_64::_mm_pause() };
7777
}
7878
}
@@ -81,10 +81,13 @@ pub fn spin_loop() {
8181
{
8282
#[cfg(target_arch = "aarch64")]
8383
{
84+
// SAFETY: the `cfg` attr ensures that we only execute this on aarch64 targets.
8485
unsafe { crate::arch::aarch64::__yield() };
8586
}
8687
#[cfg(target_arch = "arm")]
8788
{
89+
// SAFETY: the `cfg` attr ensures that we only execute this on arm targets
90+
// with support for the v6 feature.
8891
unsafe { crate::arch::arm::__yield() };
8992
}
9093
}
@@ -112,6 +115,8 @@ pub fn black_box<T>(dummy: T) -> T {
112115
// this. LLVM's interpretation of inline assembly is that it's, well, a black
113116
// box. This isn't the greatest implementation since it probably deoptimizes
114117
// more than we want, but it's so far good enough.
118+
119+
// SAFETY: the inline assembly is a no-op.
115120
unsafe {
116121
llvm_asm!("" : : "r"(&dummy));
117122
dummy

src/libcore/iter/adapters/zip.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// ignore-tidy-undocumented-unsafe
2-
31
use crate::cmp;
42

53
use super::super::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedLen};
@@ -176,9 +174,11 @@ where
176174
if self.index < self.len {
177175
let i = self.index;
178176
self.index += 1;
177+
// SAFETY: `i` is smaller than `self.len`, thus smaller than `self.a.len()` and `self.b.len()`
179178
unsafe { Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) }
180179
} else if A::may_have_side_effect() && self.index < self.a.len() {
181180
// match the base implementation's potential side effects
181+
// SAFETY: we just checked that `self.index` < `self.a.len()`
182182
unsafe {
183183
self.a.get_unchecked(self.index);
184184
}
@@ -203,11 +203,15 @@ where
203203
let i = self.index;
204204
self.index += 1;
205205
if A::may_have_side_effect() {
206+
// SAFETY: the usage of `cmp::min` to calculate `delta`
207+
// ensures that `end` is smaller than or equal to `self.len`,
208+
// so `i` is also smaller than `self.len`.
206209
unsafe {
207210
self.a.get_unchecked(i);
208211
}
209212
}
210213
if B::may_have_side_effect() {
214+
// SAFETY: same as above.
211215
unsafe {
212216
self.b.get_unchecked(i);
213217
}
@@ -243,6 +247,8 @@ where
243247
if self.index < self.len {
244248
self.len -= 1;
245249
let i = self.len;
250+
// SAFETY: `i` is smaller than the previous value of `self.len`,
251+
// which is also smaller than or equal to `self.a.len()` and `self.b.len()`
246252
unsafe { Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) }
247253
} else {
248254
None

src/libcore/option.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,6 @@
133133
//! [`Box<T>`]: ../../std/boxed/struct.Box.html
134134
//! [`i32`]: ../../std/primitive.i32.html
135135
136-
// ignore-tidy-undocumented-unsafe
137-
138136
#![stable(feature = "rust1", since = "1.0.0")]
139137

140138
use crate::iter::{FromIterator, FusedIterator, TrustedLen};
@@ -301,6 +299,8 @@ impl<T> Option<T> {
301299
#[inline]
302300
#[stable(feature = "pin", since = "1.33.0")]
303301
pub fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>> {
302+
// SAFETY: `x` is guaranteed to be pinned because it comes from `self`
303+
// which is pinned.
304304
unsafe { Pin::get_ref(self).as_ref().map(|x| Pin::new_unchecked(x)) }
305305
}
306306

@@ -310,6 +310,8 @@ impl<T> Option<T> {
310310
#[inline]
311311
#[stable(feature = "pin", since = "1.33.0")]
312312
pub fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>> {
313+
// SAFETY: `get_unchecked_mut` is never used to move the `Option` inside `self`.
314+
// `x` is guaranteed to be pinned because it comes from `self` which is pinned.
313315
unsafe { Pin::get_unchecked_mut(self).as_mut().map(|x| Pin::new_unchecked(x)) }
314316
}
315317

@@ -858,6 +860,8 @@ impl<T> Option<T> {
858860

859861
match *self {
860862
Some(ref mut v) => v,
863+
// SAFETY: a `None` variant for `self` would have been replaced by a `Some`
864+
// variant in the code above.
861865
None => unsafe { hint::unreachable_unchecked() },
862866
}
863867
}

src/libcore/panicking.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
//! necessary lang items for the compiler. All panics are funneled through this
2020
//! one function. The actual symbol is declared through the `#[panic_handler]` attribute.
2121
22-
// ignore-tidy-undocumented-unsafe
23-
2422
#![allow(dead_code, missing_docs)]
2523
#![unstable(
2624
feature = "core_panic",
@@ -41,6 +39,7 @@ use crate::panic::{Location, PanicInfo};
4139
#[lang = "panic"] // needed by codegen for panic on overflow and other `Assert` MIR terminators
4240
pub fn panic(expr: &str) -> ! {
4341
if cfg!(feature = "panic_immediate_abort") {
42+
// SAFETY: the `abort` intrinsic has no requirements to be called.
4443
unsafe { super::intrinsics::abort() }
4544
}
4645

@@ -63,6 +62,7 @@ pub fn panic(expr: &str) -> ! {
6362
#[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
6463
fn panic_bounds_check(index: usize, len: usize) -> ! {
6564
if cfg!(feature = "panic_immediate_abort") {
65+
// SAFETY: the `abort` intrinsic has no requirements to be called.
6666
unsafe { super::intrinsics::abort() }
6767
}
6868

@@ -77,6 +77,7 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
7777
#[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
7878
fn panic_bounds_check(location: &Location<'_>, index: usize, len: usize) -> ! {
7979
if cfg!(feature = "panic_immediate_abort") {
80+
// SAFETY: the `abort` intrinsic has no requirements to be called.
8081
unsafe { super::intrinsics::abort() }
8182
}
8283

@@ -93,6 +94,7 @@ fn panic_bounds_check(location: &Location<'_>, index: usize, len: usize) -> ! {
9394
#[cfg_attr(not(bootstrap), track_caller)]
9495
pub fn panic_fmt(fmt: fmt::Arguments<'_>, #[cfg(bootstrap)] location: &Location<'_>) -> ! {
9596
if cfg!(feature = "panic_immediate_abort") {
97+
// SAFETY: the `abort` intrinsic has no requirements to be called.
9698
unsafe { super::intrinsics::abort() }
9799
}
98100

@@ -108,5 +110,6 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>, #[cfg(bootstrap)] location: &Location<
108110
#[cfg(not(bootstrap))]
109111
let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller());
110112

113+
// SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
111114
unsafe { panic_impl(&pi) }
112115
}

src/libcore/unicode/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@ mod unicode_data;
77
/// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of
88
/// `char` and `str` methods are based on.
99
///
10+
/// New versions of Unicode are released regularly and subsequently all methods
11+
/// in the standard library depending on Unicode are updated. Therefore the
12+
/// behavior of some `char` and `str` methods and the value of this constant
13+
/// changes over time. This is *not* considered to be a breaking change.
14+
///
1015
/// The version numbering scheme is explained in
1116
/// [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).
12-
#[unstable(feature = "unicode_version", issue = "49726")]
17+
#[stable(feature = "unicode_version", since = "1.45.0")]
1318
pub const UNICODE_VERSION: (u8, u8, u8) = unicode_data::UNICODE_VERSION;
1419

1520
// For use in liballoc, not re-exported in libstd.

src/librustc_error_codes/error_codes/E0751.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ There are both a positive and negative trait implementation for the same type.
22

33
Erroneous code example:
44

5-
```compile_fail,E0748
5+
```compile_fail,E0751
66
trait MyTrait {}
77
impl MyTrait for i32 { }
88
impl !MyTrait for i32 { }

src/librustc_middle/mir/interpret/pointer.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,13 @@ static_assert_size!(Pointer, 16);
121121

122122
impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for Pointer<Tag, Id> {
123123
default fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124-
write!(f, "{:?}+{:x}[{:?}]", self.alloc_id, self.offset.bytes(), self.tag)
124+
write!(f, "{:?}+0x{:x}[{:?}]", self.alloc_id, self.offset.bytes(), self.tag)
125125
}
126126
}
127127
// Specialization for no tag
128128
impl<Id: fmt::Debug> fmt::Debug for Pointer<(), Id> {
129129
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130-
write!(f, "{:?}+{:x}", self.alloc_id, self.offset.bytes())
130+
write!(f, "{:?}+0x{:x}", self.alloc_id, self.offset.bytes())
131131
}
132132
}
133133

src/librustc_trait_selection/traits/specialize/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ fn report_negative_positive_conflict(
345345
let mut err = struct_span_err!(
346346
tcx.sess,
347347
impl_span,
348-
E0748,
348+
E0751,
349349
"found both positive and negative implementation of trait `{}`{}:",
350350
overlap.trait_desc,
351351
overlap.self_desc.clone().map_or(String::new(), |ty| format!(" for type `{}`", ty))

0 commit comments

Comments
 (0)