Skip to content

Commit 0a6c636

Browse files
committed
Auto merge of rust-lang#87156 - JohnTitor:rollup-osuhe53, r=JohnTitor
Rollup of 8 pull requests Successful merges: - rust-lang#85579 (Added Arc::try_pin) - rust-lang#86478 (Add -Zfuture-incompat-test to assist with testing future-incompat reports.) - rust-lang#86947 (Move assert_matches to an inner module) - rust-lang#87081 (Add tracking issue number to `wasi_ext`) - rust-lang#87127 (Add safety comments in private core::slice::rotate::ptr_rotate function) - rust-lang#87134 (Make SelfInTyParamDefault wording not be specific to type defaults) - rust-lang#87147 (Update cargo) - rust-lang#87154 (Fix misuse of rev attribute on <a> tag) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents b919797 + 262a4f9 commit 0a6c636

29 files changed

+197
-63
lines changed

compiler/rustc_interface/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,7 @@ fn test_debugging_options_tracking_hash() {
633633
untracked!(dump_mir_graphviz, true);
634634
untracked!(emit_future_incompat_report, true);
635635
untracked!(emit_stack_sizes, true);
636+
untracked!(future_incompat_test, true);
636637
untracked!(hir_stats, true);
637638
untracked!(identify_regions, true);
638639
untracked!(incremental_ignore_spans, true);

compiler/rustc_middle/src/ich/impls_syntax.rs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::ich::StableHashingContext;
66
use rustc_ast as ast;
77
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
88
use rustc_span::{BytePos, NormalizedPos, SourceFile};
9+
use std::assert::assert_matches;
910

1011
use smallvec::SmallVec;
1112

compiler/rustc_middle/src/lint.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_hir::HirId;
88
use rustc_index::vec::IndexVec;
99
use rustc_session::lint::{
1010
builtin::{self, FORBIDDEN_LINT_GROUPS},
11-
FutureIncompatibilityReason, FutureIncompatibleInfo, Level, Lint, LintId,
11+
FutureIncompatibilityReason, Level, Lint, LintId,
1212
};
1313
use rustc_session::{DiagnosticMessageId, Session};
1414
use rustc_span::hygiene::MacroKind;
@@ -223,12 +223,12 @@ pub fn struct_lint_level<'s, 'd>(
223223
let lint_id = LintId::of(lint);
224224
let future_incompatible = lint.future_incompatible;
225225

226-
let has_future_breakage = matches!(
227-
future_incompatible,
228-
Some(FutureIncompatibleInfo {
229-
reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow,
230-
..
231-
})
226+
let has_future_breakage = future_incompatible.map_or(
227+
// Default allow lints trigger too often for testing.
228+
sess.opts.debugging_opts.future_incompat_test && lint.default_level != Level::Allow,
229+
|incompat| {
230+
matches!(incompat.reason, FutureIncompatibilityReason::FutureReleaseErrorReportNow)
231+
},
232232
);
233233

234234
let mut err = match (level, span) {

compiler/rustc_mir/src/interpret/memory.rs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//! integer. It is crucial that these operations call `check_align` *before*
77
//! short-circuiting the empty case!
88
9+
use std::assert::assert_matches;
910
use std::borrow::Cow;
1011
use std::collections::VecDeque;
1112
use std::convert::{TryFrom, TryInto};

compiler/rustc_resolve/src/diagnostics.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -502,14 +502,14 @@ impl<'a> Resolver<'a> {
502502

503503
err
504504
}
505-
ResolutionError::SelfInTyParamDefault => {
505+
ResolutionError::SelfInGenericParamDefault => {
506506
let mut err = struct_span_err!(
507507
self.session,
508508
span,
509509
E0735,
510-
"type parameters cannot use `Self` in their defaults"
510+
"generic parameters cannot use `Self` in their defaults"
511511
);
512-
err.span_label(span, "`Self` in type parameter default".to_string());
512+
err.span_label(span, "`Self` in generic parameter default".to_string());
513513
err
514514
}
515515
ResolutionError::UnreachableLabel { name, definition_span, suggestion } => {

compiler/rustc_resolve/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ enum ResolutionError<'a> {
249249
/// This error is only emitted when using `min_const_generics`.
250250
ParamInNonTrivialAnonConst { name: Symbol, is_type: bool },
251251
/// Error E0735: generic parameters with a default cannot use `Self`
252-
SelfInTyParamDefault,
252+
SelfInGenericParamDefault,
253253
/// Error E0767: use of unreachable label
254254
UnreachableLabel { name: Symbol, definition_span: Span, suggestion: Option<LabelSuggestion> },
255255
}
@@ -2643,7 +2643,7 @@ impl<'a> Resolver<'a> {
26432643
if let ForwardGenericParamBanRibKind = all_ribs[rib_index].kind {
26442644
if record_used {
26452645
let res_error = if rib_ident.name == kw::SelfUpper {
2646-
ResolutionError::SelfInTyParamDefault
2646+
ResolutionError::SelfInGenericParamDefault
26472647
} else {
26482648
ResolutionError::ForwardDeclaredGenericParam
26492649
};

compiler/rustc_session/src/options.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,8 @@ options! {
10841084
"set the optimization fuel quota for a crate"),
10851085
function_sections: Option<bool> = (None, parse_opt_bool, [TRACKED],
10861086
"whether each function should go in its own section"),
1087+
future_incompat_test: bool = (false, parse_bool, [UNTRACKED],
1088+
"forces all lints to be future incompatible, used for internal testing (default: no)"),
10871089
gcc_ld: Option<LdImpl> = (None, parse_gcc_ld, [TRACKED], "implementation of ld used by cc"),
10881090
graphviz_dark_mode: bool = (false, parse_bool, [UNTRACKED],
10891091
"use dark-themed colors in graphviz output (default: no)"),

library/alloc/src/sync.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use core::marker::{PhantomData, Unpin, Unsize};
1919
use core::mem::size_of_val;
2020
use core::mem::{self, align_of_val_raw};
2121
use core::ops::{CoerceUnsized, Deref, DispatchFromDyn, Receiver};
22-
#[cfg(not(no_global_oom_handling))]
2322
use core::pin::Pin;
2423
use core::ptr::{self, NonNull};
2524
#[cfg(not(no_global_oom_handling))]
@@ -494,6 +493,13 @@ impl<T> Arc<T> {
494493
unsafe { Pin::new_unchecked(Arc::new(data)) }
495494
}
496495

496+
/// Constructs a new `Pin<Arc<T>>`, return an error if allocation fails.
497+
#[unstable(feature = "allocator_api", issue = "32838")]
498+
#[inline]
499+
pub fn try_pin(data: T) -> Result<Pin<Arc<T>>, AllocError> {
500+
unsafe { Ok(Pin::new_unchecked(Arc::try_new(data)?)) }
501+
}
502+
497503
/// Constructs a new `Arc<T>`, returning an error if allocation fails.
498504
///
499505
/// # Examples

library/core/src/lib.rs

+10
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,16 @@ use prelude::v1::*;
179179
#[macro_use]
180180
mod macros;
181181

182+
// We don't export this through #[macro_export] for now, to avoid breakage.
183+
// See https://github.com/rust-lang/rust/issues/82913
184+
#[cfg(not(test))]
185+
#[unstable(feature = "assert_matches", issue = "82775")]
186+
/// Unstable module containing the unstable `assert_matches` macro.
187+
pub mod assert {
188+
#[unstable(feature = "assert_matches", issue = "82775")]
189+
pub use crate::macros::{assert_matches, debug_assert_matches};
190+
}
191+
182192
#[macro_use]
183193
mod internal_macros;
184194

library/core/src/macros/mod.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ macro_rules! assert_ne {
127127
/// ```
128128
/// #![feature(assert_matches)]
129129
///
130+
/// use std::assert::assert_matches;
131+
///
130132
/// let a = 1u32.checked_add(2);
131133
/// let b = 1u32.checked_sub(2);
132134
/// assert_matches!(a, Some(_));
@@ -135,10 +137,10 @@ macro_rules! assert_ne {
135137
/// let c = Ok("abc".to_string());
136138
/// assert_matches!(c, Ok(x) | Err(x) if x.len() < 100);
137139
/// ```
138-
#[macro_export]
139140
#[unstable(feature = "assert_matches", issue = "82775")]
140141
#[allow_internal_unstable(core_panic)]
141-
macro_rules! assert_matches {
142+
#[rustc_macro_transparency = "semitransparent"]
143+
pub macro assert_matches {
142144
($left:expr, $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => ({
143145
match $left {
144146
$( $pattern )|+ $( if $guard )? => {}
@@ -150,7 +152,7 @@ macro_rules! assert_matches {
150152
);
151153
}
152154
}
153-
});
155+
}),
154156
($left:expr, $( $pattern:pat_param )|+ $( if $guard: expr )?, $($arg:tt)+) => ({
155157
match $left {
156158
$( $pattern )|+ $( if $guard )? => {}
@@ -162,7 +164,7 @@ macro_rules! assert_matches {
162164
);
163165
}
164166
}
165-
});
167+
}),
166168
}
167169

168170
/// Asserts that a boolean expression is `true` at runtime.
@@ -284,6 +286,8 @@ macro_rules! debug_assert_ne {
284286
/// ```
285287
/// #![feature(assert_matches)]
286288
///
289+
/// use std::assert::debug_assert_matches;
290+
///
287291
/// let a = 1u32.checked_add(2);
288292
/// let b = 1u32.checked_sub(2);
289293
/// debug_assert_matches!(a, Some(_));
@@ -295,8 +299,9 @@ macro_rules! debug_assert_ne {
295299
#[macro_export]
296300
#[unstable(feature = "assert_matches", issue = "82775")]
297301
#[allow_internal_unstable(assert_matches)]
298-
macro_rules! debug_assert_matches {
299-
($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_matches!($($arg)*); })
302+
#[rustc_macro_transparency = "semitransparent"]
303+
pub macro debug_assert_matches($($arg:tt)*) {
304+
if $crate::cfg!(debug_assertions) { $crate::assert::assert_matches!($($arg)*); }
300305
}
301306

302307
/// Returns whether the given expression matches any of the given patterns.

library/core/src/slice/rotate.rs

+54-2
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::mem::{self, MaybeUninit};
53
use crate::ptr;
@@ -79,8 +77,10 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
7977
// the way until about `left + right == 32`, but the worst case performance breaks even
8078
// around 16. 24 was chosen as middle ground. If the size of `T` is larger than 4
8179
// `usize`s, this algorithm also outperforms other algorithms.
80+
// SAFETY: callers must ensure `mid - left` is valid for reading and writing.
8281
let x = unsafe { mid.sub(left) };
8382
// beginning of first round
83+
// SAFETY: see previous comment.
8484
let mut tmp: T = unsafe { x.read() };
8585
let mut i = right;
8686
// `gcd` can be found before hand by calculating `gcd(left + right, right)`,
@@ -92,6 +92,21 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
9292
// the very end. This is possibly due to the fact that swapping or replacing temporaries
9393
// uses only one memory address in the loop instead of needing to manage two.
9494
loop {
95+
// [long-safety-expl]
96+
// SAFETY: callers must ensure `[left, left+mid+right)` are all valid for reading and
97+
// writing.
98+
//
99+
// - `i` start with `right` so `mid-left <= x+i = x+right = mid-left+right < mid+right`
100+
// - `i <= left+right-1` is always true
101+
// - if `i < left`, `right` is added so `i < left+right` and on the next
102+
// iteration `left` is removed from `i` so it doesn't go further
103+
// - if `i >= left`, `left` is removed immediately and so it doesn't go further.
104+
// - overflows cannot happen for `i` since the function's safety contract ask for
105+
// `mid+right-1 = x+left+right` to be valid for writing
106+
// - underflows cannot happen because `i` must be bigger or equal to `left` for
107+
// a substraction of `left` to happen.
108+
//
109+
// So `x+i` is valid for reading and writing if the caller respected the contract
95110
tmp = unsafe { x.add(i).replace(tmp) };
96111
// instead of incrementing `i` and then checking if it is outside the bounds, we
97112
// check if `i` will go outside the bounds on the next increment. This prevents
@@ -100,6 +115,8 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
100115
i -= left;
101116
if i == 0 {
102117
// end of first round
118+
// SAFETY: tmp has been read from a valid source and x is valid for writing
119+
// according to the caller.
103120
unsafe { x.write(tmp) };
104121
break;
105122
}
@@ -113,13 +130,24 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
113130
}
114131
// finish the chunk with more rounds
115132
for start in 1..gcd {
133+
// SAFETY: `gcd` is at most equal to `right` so all values in `1..gcd` are valid for
134+
// reading and writing as per the function's safety contract, see [long-safety-expl]
135+
// above
116136
tmp = unsafe { x.add(start).read() };
137+
// [safety-expl-addition]
138+
//
139+
// Here `start < gcd` so `start < right` so `i < right+right`: `right` being the
140+
// greatest common divisor of `(left+right, right)` means that `left = right` so
141+
// `i < left+right` so `x+i = mid-left+i` is always valid for reading and writing
142+
// according to the function's safety contract.
117143
i = start + right;
118144
loop {
145+
// SAFETY: see [long-safety-expl] and [safety-expl-addition]
119146
tmp = unsafe { x.add(i).replace(tmp) };
120147
if i >= left {
121148
i -= left;
122149
if i == start {
150+
// SAFETY: see [long-safety-expl] and [safety-expl-addition]
123151
unsafe { x.add(start).write(tmp) };
124152
break;
125153
}
@@ -135,14 +163,30 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
135163
// The `[T; 0]` here is to ensure this is appropriately aligned for T
136164
let mut rawarray = MaybeUninit::<(BufType, [T; 0])>::uninit();
137165
let buf = rawarray.as_mut_ptr() as *mut T;
166+
// SAFETY: `mid-left <= mid-left+right < mid+right`
138167
let dim = unsafe { mid.sub(left).add(right) };
139168
if left <= right {
169+
// SAFETY:
170+
//
171+
// 1) The `else if` condition about the sizes ensures `[mid-left; left]` will fit in
172+
// `buf` without overflow and `buf` was created just above and so cannot be
173+
// overlapped with any value of `[mid-left; left]`
174+
// 2) [mid-left, mid+right) are all valid for reading and writing and we don't care
175+
// about overlaps here.
176+
// 3) The `if` condition about `left <= right` ensures writing `left` elements to
177+
// `dim = mid-left+right` is valid because:
178+
// - `buf` is valid and `left` elements were written in it in 1)
179+
// - `dim+left = mid-left+right+left = mid+right` and we write `[dim, dim+left)`
140180
unsafe {
181+
// 1)
141182
ptr::copy_nonoverlapping(mid.sub(left), buf, left);
183+
// 2)
142184
ptr::copy(mid, mid.sub(left), right);
185+
// 3)
143186
ptr::copy_nonoverlapping(buf, dim, left);
144187
}
145188
} else {
189+
// SAFETY: same reasoning as above but with `left` and `right` reversed
146190
unsafe {
147191
ptr::copy_nonoverlapping(mid, buf, right);
148192
ptr::copy(mid.sub(left), dim, left);
@@ -156,6 +200,10 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
156200
// of this algorithm would be, and swapping using that last chunk instead of swapping
157201
// adjacent chunks like this algorithm is doing, but this way is still faster.
158202
loop {
203+
// SAFETY:
204+
// `left >= right` so `[mid-right, mid+right)` is valid for reading and writing
205+
// Substracting `right` from `mid` each turn is counterbalanced by the addition and
206+
// check after it.
159207
unsafe {
160208
ptr::swap_nonoverlapping(mid.sub(right), mid, right);
161209
mid = mid.sub(right);
@@ -168,6 +216,10 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
168216
} else {
169217
// Algorithm 3, `left < right`
170218
loop {
219+
// SAFETY: `[mid-left, mid+left)` is valid for reading and writing because
220+
// `left < right` so `mid+left < mid+right`.
221+
// Adding `left` to `mid` each turn is counterbalanced by the substraction and check
222+
// after it.
171223
unsafe {
172224
ptr::swap_nonoverlapping(mid.sub(left), mid, left);
173225
mid = mid.add(left);

library/std/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -548,8 +548,8 @@ pub use std_detect::{
548548
#[stable(feature = "rust1", since = "1.0.0")]
549549
#[allow(deprecated, deprecated_in_future)]
550550
pub use core::{
551-
assert_eq, assert_matches, assert_ne, debug_assert, debug_assert_eq, debug_assert_matches,
552-
debug_assert_ne, matches, r#try, todo, unimplemented, unreachable, write, writeln,
551+
assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, matches, r#try, todo,
552+
unimplemented, unreachable, write, writeln,
553553
};
554554

555555
// Re-export built-in macros defined through libcore.

library/std/src/os/wasi/fs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! WASI-specific extensions to primitives in the `std::fs` module.
22
33
#![deny(unsafe_op_in_unsafe_fn)]
4-
#![unstable(feature = "wasi_ext", issue = "none")]
4+
#![unstable(feature = "wasi_ext", issue = "71213")]
55

66
use crate::ffi::OsStr;
77
use crate::fs::{self, File, Metadata, OpenOptions};

library/std/src/os/wasi/io.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! WASI-specific extensions to general I/O primitives
22
33
#![deny(unsafe_op_in_unsafe_fn)]
4-
#![unstable(feature = "wasi_ext", issue = "none")]
4+
#![unstable(feature = "wasi_ext", issue = "71213")]
55

66
use crate::fs;
77
use crate::io;

src/librustdoc/html/markdown.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -621,8 +621,7 @@ impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> {
621621
is_paragraph = true;
622622
}
623623
html::push_html(&mut ret, content.into_iter());
624-
write!(ret, "&nbsp;<a href=\"#fnref{}\" rev=\"footnote\">↩</a>", id)
625-
.unwrap();
624+
write!(ret, "&nbsp;<a href=\"#fnref{}\">↩</a>", id).unwrap();
626625
if is_paragraph {
627626
ret.push_str("</p>");
628627
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(const_generics_defaults)]
2+
3+
struct Struct<const N: usize = { Self; 10 }>;
4+
//~^ ERROR generic parameters cannot use `Self` in their defaults [E0735]
5+
6+
enum Enum<const N: usize = { Self; 10 }> { }
7+
//~^ ERROR generic parameters cannot use `Self` in their defaults [E0735]
8+
9+
union Union<const N: usize = { Self; 10 }> { not_empty: () }
10+
//~^ ERROR generic parameters cannot use `Self` in their defaults [E0735]
11+
12+
fn main() {
13+
let _: Struct;
14+
let _: Enum;
15+
let _: Union;
16+
}

0 commit comments

Comments
 (0)