Skip to content

Commit d3d145e

Browse files
committedFeb 29, 2024·
Auto merge of rust-lang#121770 - matthiaskrgr:rollup-wdher8r, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - rust-lang#110543 (Make `ReentrantLock` public) - rust-lang#121689 ([rustdoc] Prevent inclusion of whitespace character after macro_rules ident) - rust-lang#121724 (Use `LitKind::Err` for malformed floats) - rust-lang#121735 (pattern analysis: Don't panic when encountering unexpected constructor) - rust-lang#121743 (Opportunistically resolve regions when processing region outlives obligations) Failed merges: - rust-lang#121326 (Detect empty leading where clauses on type aliases) - rust-lang#121416 (Improve error messages for generics with default parameters) - rust-lang#121669 (Count stashed errors again) - rust-lang#121723 (Two diagnostic things) r? `@ghost` `@rustbot` modify labels: rollup
2 parents c475e23 + 9f9daed commit d3d145e

File tree

19 files changed

+600
-396
lines changed

19 files changed

+600
-396
lines changed
 

‎compiler/rustc_infer/src/infer/outlives/obligations.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,17 @@
6262
use crate::infer::outlives::components::{push_outlives_components, Component};
6363
use crate::infer::outlives::env::RegionBoundPairs;
6464
use crate::infer::outlives::verify::VerifyBoundCx;
65+
use crate::infer::resolve::OpportunisticRegionResolver;
6566
use crate::infer::{
6667
self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, UndoLog, VerifyBound,
6768
};
6869
use crate::traits::{ObligationCause, ObligationCauseCode};
6970
use rustc_data_structures::undo_log::UndoLogs;
7071
use rustc_middle::mir::ConstraintCategory;
7172
use rustc_middle::traits::query::NoSolution;
72-
use rustc_middle::ty::{self, GenericArgsRef, Region, Ty, TyCtxt, TypeVisitableExt};
73+
use rustc_middle::ty::{
74+
self, GenericArgsRef, Region, Ty, TyCtxt, TypeFoldable as _, TypeVisitableExt,
75+
};
7376
use rustc_middle::ty::{GenericArgKind, PolyTypeOutlivesPredicate};
7477
use rustc_span::DUMMY_SP;
7578
use smallvec::smallvec;
@@ -176,6 +179,11 @@ impl<'tcx> InferCtxt<'tcx> {
176179
.map_err(|NoSolution| (outlives, origin.clone()))?
177180
.no_bound_vars()
178181
.expect("started with no bound vars, should end with no bound vars");
182+
// `TypeOutlives` is structural, so we should try to opportunistically resolve all
183+
// region vids before processing regions, so we have a better chance to match clauses
184+
// in our param-env.
185+
let (sup_type, sub_region) =
186+
(sup_type, sub_region).fold_with(&mut OpportunisticRegionResolver::new(self));
179187

180188
debug!(?sup_type, ?sub_region, ?origin);
181189

‎compiler/rustc_parse/src/lexer/mod.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -501,9 +501,11 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
501501
(kind, self.symbol_from_to(start, end))
502502
}
503503
rustc_lexer::LiteralKind::Float { base, empty_exponent } => {
504+
let mut kind = token::Float;
504505
if empty_exponent {
505506
let span = self.mk_sp(start, self.pos);
506-
self.dcx().emit_err(errors::EmptyExponentFloat { span });
507+
let guar = self.dcx().emit_err(errors::EmptyExponentFloat { span });
508+
kind = token::Err(guar);
507509
}
508510
let base = match base {
509511
Base::Hexadecimal => Some("hexadecimal"),
@@ -513,9 +515,11 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
513515
};
514516
if let Some(base) = base {
515517
let span = self.mk_sp(start, end);
516-
self.dcx().emit_err(errors::FloatLiteralUnsupportedBase { span, base });
518+
let guar =
519+
self.dcx().emit_err(errors::FloatLiteralUnsupportedBase { span, base });
520+
kind = token::Err(guar)
517521
}
518-
(token::Float, self.symbol_from_to(start, end))
522+
(kind, self.symbol_from_to(start, end))
519523
}
520524
}
521525
}

‎compiler/rustc_pattern_analysis/src/constructor.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,7 @@ impl<Cx: TypeCx> ConstructorSet<Cx> {
940940
}
941941
ConstructorSet::Variants { variants, non_exhaustive } => {
942942
let mut seen_set = index::IdxSet::new_empty(variants.len());
943-
for idx in seen.iter().map(|c| c.as_variant().unwrap()) {
943+
for idx in seen.iter().filter_map(|c| c.as_variant()) {
944944
seen_set.insert(idx);
945945
}
946946
let mut skipped_a_hidden_variant = false;
@@ -969,7 +969,7 @@ impl<Cx: TypeCx> ConstructorSet<Cx> {
969969
ConstructorSet::Bool => {
970970
let mut seen_false = false;
971971
let mut seen_true = false;
972-
for b in seen.iter().map(|ctor| ctor.as_bool().unwrap()) {
972+
for b in seen.iter().filter_map(|ctor| ctor.as_bool()) {
973973
if b {
974974
seen_true = true;
975975
} else {
@@ -989,7 +989,7 @@ impl<Cx: TypeCx> ConstructorSet<Cx> {
989989
}
990990
ConstructorSet::Integers { range_1, range_2 } => {
991991
let seen_ranges: Vec<_> =
992-
seen.iter().map(|ctor| *ctor.as_int_range().unwrap()).collect();
992+
seen.iter().filter_map(|ctor| ctor.as_int_range()).copied().collect();
993993
for (seen, splitted_range) in range_1.split(seen_ranges.iter().cloned()) {
994994
match seen {
995995
Presence::Unseen => missing.push(IntRange(splitted_range)),
@@ -1006,7 +1006,7 @@ impl<Cx: TypeCx> ConstructorSet<Cx> {
10061006
}
10071007
}
10081008
ConstructorSet::Slice { array_len, subtype_is_empty } => {
1009-
let seen_slices = seen.iter().map(|c| c.as_slice().unwrap());
1009+
let seen_slices = seen.iter().filter_map(|c| c.as_slice());
10101010
let base_slice = Slice::new(*array_len, VarLen(0, 0));
10111011
for (seen, splitted_slice) in base_slice.split(seen_slices) {
10121012
let ctor = Slice(splitted_slice);

‎library/std/src/io/stdio.rs

+35-10
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ use crate::fs::File;
1111
use crate::io::{
1212
self, BorrowedCursor, BufReader, IoSlice, IoSliceMut, LineWriter, Lines, SpecReadByte,
1313
};
14+
use crate::panic::{RefUnwindSafe, UnwindSafe};
1415
use crate::sync::atomic::{AtomicBool, Ordering};
15-
use crate::sync::{Arc, Mutex, MutexGuard, OnceLock, ReentrantMutex, ReentrantMutexGuard};
16+
use crate::sync::{Arc, Mutex, MutexGuard, OnceLock, ReentrantLock, ReentrantLockGuard};
1617
use crate::sys::stdio;
1718

1819
type LocalStream = Arc<Mutex<Vec<u8>>>;
@@ -545,7 +546,7 @@ pub struct Stdout {
545546
// FIXME: this should be LineWriter or BufWriter depending on the state of
546547
// stdout (tty or not). Note that if this is not line buffered it
547548
// should also flush-on-panic or some form of flush-on-abort.
548-
inner: &'static ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>,
549+
inner: &'static ReentrantLock<RefCell<LineWriter<StdoutRaw>>>,
549550
}
550551

551552
/// A locked reference to the [`Stdout`] handle.
@@ -567,10 +568,10 @@ pub struct Stdout {
567568
#[must_use = "if unused stdout will immediately unlock"]
568569
#[stable(feature = "rust1", since = "1.0.0")]
569570
pub struct StdoutLock<'a> {
570-
inner: ReentrantMutexGuard<'a, RefCell<LineWriter<StdoutRaw>>>,
571+
inner: ReentrantLockGuard<'a, RefCell<LineWriter<StdoutRaw>>>,
571572
}
572573

573-
static STDOUT: OnceLock<ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>> = OnceLock::new();
574+
static STDOUT: OnceLock<ReentrantLock<RefCell<LineWriter<StdoutRaw>>>> = OnceLock::new();
574575

575576
/// Constructs a new handle to the standard output of the current process.
576577
///
@@ -624,7 +625,7 @@ static STDOUT: OnceLock<ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>> = OnceLo
624625
pub fn stdout() -> Stdout {
625626
Stdout {
626627
inner: STDOUT
627-
.get_or_init(|| ReentrantMutex::new(RefCell::new(LineWriter::new(stdout_raw())))),
628+
.get_or_init(|| ReentrantLock::new(RefCell::new(LineWriter::new(stdout_raw())))),
628629
}
629630
}
630631

@@ -635,7 +636,7 @@ pub fn cleanup() {
635636
let mut initialized = false;
636637
let stdout = STDOUT.get_or_init(|| {
637638
initialized = true;
638-
ReentrantMutex::new(RefCell::new(LineWriter::with_capacity(0, stdout_raw())))
639+
ReentrantLock::new(RefCell::new(LineWriter::with_capacity(0, stdout_raw())))
639640
});
640641

641642
if !initialized {
@@ -678,6 +679,12 @@ impl Stdout {
678679
}
679680
}
680681

682+
#[stable(feature = "catch_unwind", since = "1.9.0")]
683+
impl UnwindSafe for Stdout {}
684+
685+
#[stable(feature = "catch_unwind", since = "1.9.0")]
686+
impl RefUnwindSafe for Stdout {}
687+
681688
#[stable(feature = "std_debug", since = "1.16.0")]
682689
impl fmt::Debug for Stdout {
683690
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -737,6 +744,12 @@ impl Write for &Stdout {
737744
}
738745
}
739746

747+
#[stable(feature = "catch_unwind", since = "1.9.0")]
748+
impl UnwindSafe for StdoutLock<'_> {}
749+
750+
#[stable(feature = "catch_unwind", since = "1.9.0")]
751+
impl RefUnwindSafe for StdoutLock<'_> {}
752+
740753
#[stable(feature = "rust1", since = "1.0.0")]
741754
impl Write for StdoutLock<'_> {
742755
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
@@ -786,7 +799,7 @@ impl fmt::Debug for StdoutLock<'_> {
786799
/// standard library or via raw Windows API calls, will fail.
787800
#[stable(feature = "rust1", since = "1.0.0")]
788801
pub struct Stderr {
789-
inner: &'static ReentrantMutex<RefCell<StderrRaw>>,
802+
inner: &'static ReentrantLock<RefCell<StderrRaw>>,
790803
}
791804

792805
/// A locked reference to the [`Stderr`] handle.
@@ -808,7 +821,7 @@ pub struct Stderr {
808821
#[must_use = "if unused stderr will immediately unlock"]
809822
#[stable(feature = "rust1", since = "1.0.0")]
810823
pub struct StderrLock<'a> {
811-
inner: ReentrantMutexGuard<'a, RefCell<StderrRaw>>,
824+
inner: ReentrantLockGuard<'a, RefCell<StderrRaw>>,
812825
}
813826

814827
/// Constructs a new handle to the standard error of the current process.
@@ -862,8 +875,8 @@ pub fn stderr() -> Stderr {
862875
// Note that unlike `stdout()` we don't use `at_exit` here to register a
863876
// destructor. Stderr is not buffered, so there's no need to run a
864877
// destructor for flushing the buffer
865-
static INSTANCE: ReentrantMutex<RefCell<StderrRaw>> =
866-
ReentrantMutex::new(RefCell::new(stderr_raw()));
878+
static INSTANCE: ReentrantLock<RefCell<StderrRaw>> =
879+
ReentrantLock::new(RefCell::new(stderr_raw()));
867880

868881
Stderr { inner: &INSTANCE }
869882
}
@@ -898,6 +911,12 @@ impl Stderr {
898911
}
899912
}
900913

914+
#[stable(feature = "catch_unwind", since = "1.9.0")]
915+
impl UnwindSafe for Stderr {}
916+
917+
#[stable(feature = "catch_unwind", since = "1.9.0")]
918+
impl RefUnwindSafe for Stderr {}
919+
901920
#[stable(feature = "std_debug", since = "1.16.0")]
902921
impl fmt::Debug for Stderr {
903922
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -957,6 +976,12 @@ impl Write for &Stderr {
957976
}
958977
}
959978

979+
#[stable(feature = "catch_unwind", since = "1.9.0")]
980+
impl UnwindSafe for StderrLock<'_> {}
981+
982+
#[stable(feature = "catch_unwind", since = "1.9.0")]
983+
impl RefUnwindSafe for StderrLock<'_> {}
984+
960985
#[stable(feature = "rust1", since = "1.0.0")]
961986
impl Write for StderrLock<'_> {
962987
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {

‎library/std/src/sync/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ pub use self::lazy_lock::LazyLock;
184184
#[stable(feature = "once_cell", since = "1.70.0")]
185185
pub use self::once_lock::OnceLock;
186186

187-
pub(crate) use self::remutex::{ReentrantMutex, ReentrantMutexGuard};
187+
#[unstable(feature = "reentrant_lock", issue = "121440")]
188+
pub use self::reentrant_lock::{ReentrantLock, ReentrantLockGuard};
188189

189190
pub mod mpsc;
190191

@@ -196,5 +197,5 @@ mod mutex;
196197
pub(crate) mod once;
197198
mod once_lock;
198199
mod poison;
199-
mod remutex;
200+
mod reentrant_lock;
200201
mod rwlock;
+320
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
#[cfg(all(test, not(target_os = "emscripten")))]
2+
mod tests;
3+
4+
use crate::cell::UnsafeCell;
5+
use crate::fmt;
6+
use crate::ops::Deref;
7+
use crate::panic::{RefUnwindSafe, UnwindSafe};
8+
use crate::sync::atomic::{AtomicUsize, Ordering::Relaxed};
9+
use crate::sys::locks as sys;
10+
11+
/// A re-entrant mutual exclusion lock
12+
///
13+
/// This lock will block *other* threads waiting for the lock to become
14+
/// available. The thread which has already locked the mutex can lock it
15+
/// multiple times without blocking, preventing a common source of deadlocks.
16+
///
17+
/// # Examples
18+
///
19+
/// Allow recursively calling a function needing synchronization from within
20+
/// a callback (this is how [`StdoutLock`](crate::io::StdoutLock) is currently
21+
/// implemented):
22+
///
23+
/// ```
24+
/// #![feature(reentrant_lock)]
25+
///
26+
/// use std::cell::RefCell;
27+
/// use std::sync::ReentrantLock;
28+
///
29+
/// pub struct Log {
30+
/// data: RefCell<String>,
31+
/// }
32+
///
33+
/// impl Log {
34+
/// pub fn append(&self, msg: &str) {
35+
/// self.data.borrow_mut().push_str(msg);
36+
/// }
37+
/// }
38+
///
39+
/// static LOG: ReentrantLock<Log> = ReentrantLock::new(Log { data: RefCell::new(String::new()) });
40+
///
41+
/// pub fn with_log<R>(f: impl FnOnce(&Log) -> R) -> R {
42+
/// let log = LOG.lock();
43+
/// f(&*log)
44+
/// }
45+
///
46+
/// with_log(|log| {
47+
/// log.append("Hello");
48+
/// with_log(|log| log.append(" there!"));
49+
/// });
50+
/// ```
51+
///
52+
// # Implementation details
53+
//
54+
// The 'owner' field tracks which thread has locked the mutex.
55+
//
56+
// We use current_thread_unique_ptr() as the thread identifier,
57+
// which is just the address of a thread local variable.
58+
//
59+
// If `owner` is set to the identifier of the current thread,
60+
// we assume the mutex is already locked and instead of locking it again,
61+
// we increment `lock_count`.
62+
//
63+
// When unlocking, we decrement `lock_count`, and only unlock the mutex when
64+
// it reaches zero.
65+
//
66+
// `lock_count` is protected by the mutex and only accessed by the thread that has
67+
// locked the mutex, so needs no synchronization.
68+
//
69+
// `owner` can be checked by other threads that want to see if they already
70+
// hold the lock, so needs to be atomic. If it compares equal, we're on the
71+
// same thread that holds the mutex and memory access can use relaxed ordering
72+
// since we're not dealing with multiple threads. If it's not equal,
73+
// synchronization is left to the mutex, making relaxed memory ordering for
74+
// the `owner` field fine in all cases.
75+
#[unstable(feature = "reentrant_lock", issue = "121440")]
76+
pub struct ReentrantLock<T: ?Sized> {
77+
mutex: sys::Mutex,
78+
owner: AtomicUsize,
79+
lock_count: UnsafeCell<u32>,
80+
data: T,
81+
}
82+
83+
#[unstable(feature = "reentrant_lock", issue = "121440")]
84+
unsafe impl<T: Send + ?Sized> Send for ReentrantLock<T> {}
85+
#[unstable(feature = "reentrant_lock", issue = "121440")]
86+
unsafe impl<T: Send + ?Sized> Sync for ReentrantLock<T> {}
87+
88+
// Because of the `UnsafeCell`, these traits are not implemented automatically
89+
#[unstable(feature = "reentrant_lock", issue = "121440")]
90+
impl<T: UnwindSafe + ?Sized> UnwindSafe for ReentrantLock<T> {}
91+
#[unstable(feature = "reentrant_lock", issue = "121440")]
92+
impl<T: RefUnwindSafe + ?Sized> RefUnwindSafe for ReentrantLock<T> {}
93+
94+
/// An RAII implementation of a "scoped lock" of a re-entrant lock. When this
95+
/// structure is dropped (falls out of scope), the lock will be unlocked.
96+
///
97+
/// The data protected by the mutex can be accessed through this guard via its
98+
/// [`Deref`] implementation.
99+
///
100+
/// This structure is created by the [`lock`](ReentrantLock::lock) method on
101+
/// [`ReentrantLock`].
102+
///
103+
/// # Mutability
104+
///
105+
/// Unlike [`MutexGuard`](super::MutexGuard), `ReentrantLockGuard` does not
106+
/// implement [`DerefMut`](crate::ops::DerefMut), because implementation of
107+
/// the trait would violate Rust’s reference aliasing rules. Use interior
108+
/// mutability (usually [`RefCell`](crate::cell::RefCell)) in order to mutate
109+
/// the guarded data.
110+
#[must_use = "if unused the ReentrantLock will immediately unlock"]
111+
#[unstable(feature = "reentrant_lock", issue = "121440")]
112+
pub struct ReentrantLockGuard<'a, T: ?Sized + 'a> {
113+
lock: &'a ReentrantLock<T>,
114+
}
115+
116+
#[unstable(feature = "reentrant_lock", issue = "121440")]
117+
impl<T: ?Sized> !Send for ReentrantLockGuard<'_, T> {}
118+
119+
#[unstable(feature = "reentrant_lock", issue = "121440")]
120+
impl<T> ReentrantLock<T> {
121+
/// Creates a new re-entrant lock in an unlocked state ready for use.
122+
///
123+
/// # Examples
124+
///
125+
/// ```
126+
/// #![feature(reentrant_lock)]
127+
/// use std::sync::ReentrantLock;
128+
///
129+
/// let lock = ReentrantLock::new(0);
130+
/// ```
131+
pub const fn new(t: T) -> ReentrantLock<T> {
132+
ReentrantLock {
133+
mutex: sys::Mutex::new(),
134+
owner: AtomicUsize::new(0),
135+
lock_count: UnsafeCell::new(0),
136+
data: t,
137+
}
138+
}
139+
140+
/// Consumes this lock, returning the underlying data.
141+
///
142+
/// # Examples
143+
///
144+
/// ```
145+
/// #![feature(reentrant_lock)]
146+
///
147+
/// use std::sync::ReentrantLock;
148+
///
149+
/// let lock = ReentrantLock::new(0);
150+
/// assert_eq!(lock.into_inner(), 0);
151+
/// ```
152+
pub fn into_inner(self) -> T {
153+
self.data
154+
}
155+
}
156+
157+
#[unstable(feature = "reentrant_lock", issue = "121440")]
158+
impl<T: ?Sized> ReentrantLock<T> {
159+
/// Acquires the lock, blocking the current thread until it is able to do
160+
/// so.
161+
///
162+
/// This function will block the caller until it is available to acquire
163+
/// the lock. Upon returning, the thread is the only thread with the lock
164+
/// held. When the thread calling this method already holds the lock, the
165+
/// call succeeds without blocking.
166+
///
167+
/// # Examples
168+
///
169+
/// ```
170+
/// #![feature(reentrant_lock)]
171+
/// use std::cell::Cell;
172+
/// use std::sync::{Arc, ReentrantLock};
173+
/// use std::thread;
174+
///
175+
/// let lock = Arc::new(ReentrantLock::new(Cell::new(0)));
176+
/// let c_lock = Arc::clone(&lock);
177+
///
178+
/// thread::spawn(move || {
179+
/// c_lock.lock().set(10);
180+
/// }).join().expect("thread::spawn failed");
181+
/// assert_eq!(lock.lock().get(), 10);
182+
/// ```
183+
pub fn lock(&self) -> ReentrantLockGuard<'_, T> {
184+
let this_thread = current_thread_unique_ptr();
185+
// Safety: We only touch lock_count when we own the lock.
186+
unsafe {
187+
if self.owner.load(Relaxed) == this_thread {
188+
self.increment_lock_count().expect("lock count overflow in reentrant mutex");
189+
} else {
190+
self.mutex.lock();
191+
self.owner.store(this_thread, Relaxed);
192+
debug_assert_eq!(*self.lock_count.get(), 0);
193+
*self.lock_count.get() = 1;
194+
}
195+
}
196+
ReentrantLockGuard { lock: self }
197+
}
198+
199+
/// Returns a mutable reference to the underlying data.
200+
///
201+
/// Since this call borrows the `ReentrantLock` mutably, no actual locking
202+
/// needs to take place -- the mutable borrow statically guarantees no locks
203+
/// exist.
204+
///
205+
/// # Examples
206+
///
207+
/// ```
208+
/// #![feature(reentrant_lock)]
209+
/// use std::sync::ReentrantLock;
210+
///
211+
/// let mut lock = ReentrantLock::new(0);
212+
/// *lock.get_mut() = 10;
213+
/// assert_eq!(*lock.lock(), 10);
214+
/// ```
215+
pub fn get_mut(&mut self) -> &mut T {
216+
&mut self.data
217+
}
218+
219+
/// Attempts to acquire this lock.
220+
///
221+
/// If the lock could not be acquired at this time, then `None` is returned.
222+
/// Otherwise, an RAII guard is returned.
223+
///
224+
/// This function does not block.
225+
pub(crate) fn try_lock(&self) -> Option<ReentrantLockGuard<'_, T>> {
226+
let this_thread = current_thread_unique_ptr();
227+
// Safety: We only touch lock_count when we own the lock.
228+
unsafe {
229+
if self.owner.load(Relaxed) == this_thread {
230+
self.increment_lock_count()?;
231+
Some(ReentrantLockGuard { lock: self })
232+
} else if self.mutex.try_lock() {
233+
self.owner.store(this_thread, Relaxed);
234+
debug_assert_eq!(*self.lock_count.get(), 0);
235+
*self.lock_count.get() = 1;
236+
Some(ReentrantLockGuard { lock: self })
237+
} else {
238+
None
239+
}
240+
}
241+
}
242+
243+
unsafe fn increment_lock_count(&self) -> Option<()> {
244+
*self.lock_count.get() = (*self.lock_count.get()).checked_add(1)?;
245+
Some(())
246+
}
247+
}
248+
249+
#[unstable(feature = "reentrant_lock", issue = "121440")]
250+
impl<T: fmt::Debug + ?Sized> fmt::Debug for ReentrantLock<T> {
251+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
252+
let mut d = f.debug_struct("ReentrantLock");
253+
match self.try_lock() {
254+
Some(v) => d.field("data", &&*v),
255+
None => d.field("data", &format_args!("<locked>")),
256+
};
257+
d.finish_non_exhaustive()
258+
}
259+
}
260+
261+
#[unstable(feature = "reentrant_lock", issue = "121440")]
262+
impl<T: Default> Default for ReentrantLock<T> {
263+
fn default() -> Self {
264+
Self::new(T::default())
265+
}
266+
}
267+
268+
#[unstable(feature = "reentrant_lock", issue = "121440")]
269+
impl<T> From<T> for ReentrantLock<T> {
270+
fn from(t: T) -> Self {
271+
Self::new(t)
272+
}
273+
}
274+
275+
#[unstable(feature = "reentrant_lock", issue = "121440")]
276+
impl<T: ?Sized> Deref for ReentrantLockGuard<'_, T> {
277+
type Target = T;
278+
279+
fn deref(&self) -> &T {
280+
&self.lock.data
281+
}
282+
}
283+
284+
#[unstable(feature = "reentrant_lock", issue = "121440")]
285+
impl<T: fmt::Debug + ?Sized> fmt::Debug for ReentrantLockGuard<'_, T> {
286+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
287+
(**self).fmt(f)
288+
}
289+
}
290+
291+
#[unstable(feature = "reentrant_lock", issue = "121440")]
292+
impl<T: fmt::Display + ?Sized> fmt::Display for ReentrantLockGuard<'_, T> {
293+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
294+
(**self).fmt(f)
295+
}
296+
}
297+
298+
#[unstable(feature = "reentrant_lock", issue = "121440")]
299+
impl<T: ?Sized> Drop for ReentrantLockGuard<'_, T> {
300+
#[inline]
301+
fn drop(&mut self) {
302+
// Safety: We own the lock.
303+
unsafe {
304+
*self.lock.lock_count.get() -= 1;
305+
if *self.lock.lock_count.get() == 0 {
306+
self.lock.owner.store(0, Relaxed);
307+
self.lock.mutex.unlock();
308+
}
309+
}
310+
}
311+
}
312+
313+
/// Get an address that is unique per running thread.
314+
///
315+
/// This can be used as a non-null usize-sized ID.
316+
pub(crate) fn current_thread_unique_ptr() -> usize {
317+
// Use a non-drop type to make sure it's still available during thread destruction.
318+
thread_local! { static X: u8 = const { 0 } }
319+
X.with(|x| <*const _>::addr(x))
320+
}

‎library/std/src/sync/remutex/tests.rs ‎library/std/src/sync/reentrant_lock/tests.rs

+17-17
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
use super::{ReentrantMutex, ReentrantMutexGuard};
1+
use super::{ReentrantLock, ReentrantLockGuard};
22
use crate::cell::RefCell;
33
use crate::sync::Arc;
44
use crate::thread;
55

66
#[test]
77
fn smoke() {
8-
let m = ReentrantMutex::new(());
8+
let l = ReentrantLock::new(());
99
{
10-
let a = m.lock();
10+
let a = l.lock();
1111
{
12-
let b = m.lock();
12+
let b = l.lock();
1313
{
14-
let c = m.lock();
14+
let c = l.lock();
1515
assert_eq!(*c, ());
1616
}
1717
assert_eq!(*b, ());
@@ -22,15 +22,15 @@ fn smoke() {
2222

2323
#[test]
2424
fn is_mutex() {
25-
let m = Arc::new(ReentrantMutex::new(RefCell::new(0)));
26-
let m2 = m.clone();
27-
let lock = m.lock();
25+
let l = Arc::new(ReentrantLock::new(RefCell::new(0)));
26+
let l2 = l.clone();
27+
let lock = l.lock();
2828
let child = thread::spawn(move || {
29-
let lock = m2.lock();
29+
let lock = l2.lock();
3030
assert_eq!(*lock.borrow(), 4950);
3131
});
3232
for i in 0..100 {
33-
let lock = m.lock();
33+
let lock = l.lock();
3434
*lock.borrow_mut() += i;
3535
}
3636
drop(lock);
@@ -39,20 +39,20 @@ fn is_mutex() {
3939

4040
#[test]
4141
fn trylock_works() {
42-
let m = Arc::new(ReentrantMutex::new(()));
43-
let m2 = m.clone();
44-
let _lock = m.try_lock();
45-
let _lock2 = m.try_lock();
42+
let l = Arc::new(ReentrantLock::new(()));
43+
let l2 = l.clone();
44+
let _lock = l.try_lock();
45+
let _lock2 = l.try_lock();
4646
thread::spawn(move || {
47-
let lock = m2.try_lock();
47+
let lock = l2.try_lock();
4848
assert!(lock.is_none());
4949
})
5050
.join()
5151
.unwrap();
52-
let _lock3 = m.try_lock();
52+
let _lock3 = l.try_lock();
5353
}
5454

55-
pub struct Answer<'a>(pub ReentrantMutexGuard<'a, RefCell<u32>>);
55+
pub struct Answer<'a>(pub ReentrantLockGuard<'a, RefCell<u32>>);
5656
impl Drop for Answer<'_> {
5757
fn drop(&mut self) {
5858
*self.0.borrow_mut() = 42;

‎library/std/src/sync/remutex.rs

-178
This file was deleted.

‎src/librustdoc/html/highlight.rs

+1
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ fn can_merge(class1: Option<Class>, class2: Option<Class>, text: &str) -> bool {
136136
match (class1, class2) {
137137
(Some(c1), Some(c2)) => c1.is_equal_to(c2),
138138
(Some(Class::Ident(_)), None) | (None, Some(Class::Ident(_))) => true,
139+
(Some(Class::Macro(_)), _) => false,
139140
(Some(_), None) | (None, Some(_)) => text.trim().is_empty(),
140141
(None, None) => true,
141142
}

‎src/librustdoc/html/highlight/fixtures/sample.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
}
3333
}
3434

35-
<span class="macro">macro_rules! </span>bar {
35+
<span class="macro">macro_rules!</span> bar {
3636
(<span class="macro-nonterminal">$foo</span>:tt) =&gt; {};
3737
}
3838
</code></pre>

‎src/tools/clippy/tests/ui/crashes/ice-10912.rs

-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,5 @@
22
//@no-rustfix
33
fn f2() -> impl Sized { && 3.14159265358979323846E }
44
//~^ ERROR: expected at least one digit in exponent
5-
//~| ERROR: long literal lacking separators
6-
//~| NOTE: `-D clippy::unreadable-literal` implied by `-D warnings`
75

86
fn main() {}

‎src/tools/clippy/tests/ui/crashes/ice-10912.stderr

+1-10
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,5 @@ error: expected at least one digit in exponent
44
LL | fn f2() -> impl Sized { && 3.14159265358979323846E }
55
| ^^^^^^^^^^^^^^^^^^^^^^^
66

7-
error: long literal lacking separators
8-
--> tests/ui/crashes/ice-10912.rs:3:28
9-
|
10-
LL | fn f2() -> impl Sized { && 3.14159265358979323846E }
11-
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider: `3.141_592_653_589_793_238_46`
12-
|
13-
= note: `-D clippy::unreadable-literal` implied by `-D warnings`
14-
= help: to override `-D warnings` add `#[allow(clippy::unreadable_literal)]`
15-
16-
error: aborting due to 2 previous errors
7+
error: aborting due to 1 previous error
178

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// We need this option to be enabled for the `foo` macro declaration to ensure
2+
// that the link on the ident is not including whitespace characters.
3+
4+
//@ compile-flags: -Zunstable-options --generate-link-to-definition
5+
#![crate_name = "foo"]
6+
7+
// @has 'src/foo/source-code-highlight.rs.html'
8+
9+
// @hasraw - '<a href="../../foo/macro.foo.html">foo</a>'
10+
#[macro_export]
11+
macro_rules! foo {
12+
() => {}
13+
}
14+
15+
// @hasraw - '<span class="macro">foo!</span>'
16+
foo! {}
17+
18+
// @hasraw - '<a href="../../foo/fn.f.html">f</a>'
19+
#[rustfmt::skip]
20+
pub fn f () {}
21+
// @hasraw - '<a href="../../foo/struct.Bar.html">Bar</a>'
22+
// @hasraw - '<a href="../../foo/struct.Bar.html">Bar</a>'
23+
// @hasraw - '<a href="{{channel}}/std/primitive.u32.html">u32</a>'
24+
#[rustfmt::skip]
25+
pub struct Bar ( u32 );
26+
// @hasraw - '<a href="../../foo/enum.Foo.html">Foo</a>'
27+
pub enum Foo {
28+
A,
29+
}
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻²
22
//~^ ERROR expected at least one digit in exponent
33
//~| ERROR unknown start of token: \u{2212}
4-
//~| ERROR cannot subtract `{integer}` from `{float}`
54

65
fn main() {}

‎tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr

+1-20
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,5 @@ help: Unicode character '−' (Minus Sign) looks like '-' (Minus/Hyphen), but it
1515
LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e-11; // m³⋅kg⁻¹⋅s⁻²
1616
| ~
1717

18-
error[E0277]: cannot subtract `{integer}` from `{float}`
19-
--> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:53
20-
|
21-
LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻²
22-
| ^ no implementation for `{float} - {integer}`
23-
|
24-
= help: the trait `Sub<{integer}>` is not implemented for `{float}`
25-
= help: the following other types implement trait `Sub<Rhs>`:
26-
<isize as Sub>
27-
<isize as Sub<&isize>>
28-
<i8 as Sub>
29-
<i8 as Sub<&i8>>
30-
<i16 as Sub>
31-
<i16 as Sub<&i16>>
32-
<i32 as Sub>
33-
<i32 as Sub<&i32>>
34-
and 48 others
35-
36-
error: aborting due to 3 previous errors
18+
error: aborting due to 2 previous errors
3719

38-
For more information about this error, try `rustc --explain E0277`.

‎tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub trait MessageListenersInterface {
1010

1111
impl<'a> MessageListenersInterface for MessageListeners<'a> {
1212
fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
13-
//~^ ERROR cannot infer an appropriate lifetime for lifetime parameter 'b in generic type due to conflicting requirements
13+
//~^ ERROR in type `&'a MessageListeners<'_>`, reference has a longer lifetime than the data it references
1414
self
1515
}
1616
}
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,20 @@
1-
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'b in generic type due to conflicting requirements
1+
error[E0491]: in type `&'a MessageListeners<'_>`, reference has a longer lifetime than the data it references
22
--> $DIR/impl-implied-bounds-compatibility.rs:12:5
33
|
44
LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
7-
note: first, the lifetime cannot outlive the lifetime `'c` as defined here...
8-
--> $DIR/impl-implied-bounds-compatibility.rs:12:5
9-
|
10-
LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12-
note: ...so that the method type is compatible with trait
13-
--> $DIR/impl-implied-bounds-compatibility.rs:12:5
14-
|
15-
LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
16-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17-
= note: expected `fn(&'c MessageListeners<'_>) -> &'c MessageListeners<'c>`
18-
found `fn(&MessageListeners<'_>) -> &'a MessageListeners<'_>`
19-
note: but, the lifetime must be valid for the lifetime `'a` as defined here...
7+
note: the pointer is valid for the lifetime `'a` as defined here
208
--> $DIR/impl-implied-bounds-compatibility.rs:11:6
219
|
2210
LL | impl<'a> MessageListenersInterface for MessageListeners<'a> {
2311
| ^^
24-
note: ...so that the reference type `&'a MessageListeners<'_>` does not outlive the data it points at
12+
note: but the referenced data is only valid for the lifetime `'c` as defined here
2513
--> $DIR/impl-implied-bounds-compatibility.rs:12:5
2614
|
2715
LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
2816
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2917

3018
error: aborting due to 1 previous error
3119

32-
For more information about this error, try `rustc --explain E0495`.
20+
For more information about this error, try `rustc --explain E0491`.

‎tests/ui/parser/float-field.rs

+51-20
Original file line numberDiff line numberDiff line change
@@ -3,60 +3,91 @@ struct S(u8, (u8, u8));
33
fn main() {
44
let s = S(0, (0, 0));
55

6-
s.1e1; //~ ERROR no field `1e1` on type `S`
7-
s.1.; //~ ERROR unexpected token: `;`
8-
s.1.1;
9-
s.1.1e1; //~ ERROR no field `1e1` on type `(u8, u8)`
6+
{ s.1e1; } //~ ERROR no field `1e1` on type `S`
7+
8+
{ s.1.; } //~ ERROR unexpected token: `;`
9+
10+
{ s.1.1; }
11+
12+
{ s.1.1e1; } //~ ERROR no field `1e1` on type `(u8, u8)`
13+
1014
{ s.1e+; } //~ ERROR unexpected token: `1e+`
1115
//~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+`
1216
//~| ERROR expected at least one digit in exponent
17+
1318
{ s.1e-; } //~ ERROR unexpected token: `1e-`
1419
//~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-`
1520
//~| ERROR expected at least one digit in exponent
21+
1622
{ s.1e+1; } //~ ERROR unexpected token: `1e+1`
1723
//~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+1`
24+
1825
{ s.1e-1; } //~ ERROR unexpected token: `1e-1`
1926
//~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-1`
27+
2028
{ s.1.1e+1; } //~ ERROR unexpected token: `1.1e+1`
2129
//~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e+1`
30+
2231
{ s.1.1e-1; } //~ ERROR unexpected token: `1.1e-1`
2332
//~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e-1`
24-
s.0x1e1; //~ ERROR no field `0x1e1` on type `S`
25-
s.0x1.; //~ ERROR no field `0x1` on type `S`
26-
//~| ERROR hexadecimal float literal is not supported
27-
//~| ERROR unexpected token: `;`
28-
s.0x1.1; //~ ERROR no field `0x1` on type `S`
29-
//~| ERROR hexadecimal float literal is not supported
30-
s.0x1.1e1; //~ ERROR no field `0x1` on type `S`
31-
//~| ERROR hexadecimal float literal is not supported
33+
34+
{ s.0x1e1; } //~ ERROR no field `0x1e1` on type `S`
35+
36+
{ s.0x1.; } //~ ERROR hexadecimal float literal is not supported
37+
//~| ERROR unexpected token: `0x1.`
38+
//~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.`
39+
40+
{ s.0x1.1; } //~ ERROR hexadecimal float literal is not supported
41+
//~| ERROR unexpected token: `0x1.1`
42+
//~| expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1`
43+
44+
{ s.0x1.1e1; } //~ ERROR hexadecimal float literal is not supported
45+
//~| ERROR unexpected token: `0x1.1e1`
46+
//~| expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e1`
47+
3248
{ s.0x1e+; } //~ ERROR expected expression, found `;`
49+
3350
{ s.0x1e-; } //~ ERROR expected expression, found `;`
34-
s.0x1e+1; //~ ERROR no field `0x1e` on type `S`
35-
s.0x1e-1; //~ ERROR no field `0x1e` on type `S`
51+
52+
{ s.0x1e+1; } //~ ERROR no field `0x1e` on type `S`
53+
54+
{ s.0x1e-1; } //~ ERROR no field `0x1e` on type `S`
55+
3656
{ s.0x1.1e+1; } //~ ERROR unexpected token: `0x1.1e+1`
3757
//~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e+1`
3858
//~| ERROR hexadecimal float literal is not supported
59+
3960
{ s.0x1.1e-1; } //~ ERROR unexpected token: `0x1.1e-1`
4061
//~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e-1`
4162
//~| ERROR hexadecimal float literal is not supported
42-
s.1e1f32; //~ ERROR no field `1e1` on type `S`
43-
//~| ERROR suffixes on a tuple index are invalid
44-
s.1.f32; //~ ERROR no field `f32` on type `(u8, u8)`
45-
s.1.1f32; //~ ERROR suffixes on a tuple index are invalid
46-
s.1.1e1f32; //~ ERROR no field `1e1` on type `(u8, u8)`
47-
//~| ERROR suffixes on a tuple index are invalid
63+
64+
{ s.1e1f32; } //~ ERROR no field `1e1` on type `S`
65+
//~| ERROR suffixes on a tuple index are invalid
66+
67+
{ s.1.f32; } //~ ERROR no field `f32` on type `(u8, u8)`
68+
69+
{ s.1.1f32; } //~ ERROR suffixes on a tuple index are invalid
70+
71+
{ s.1.1e1f32; } //~ ERROR no field `1e1` on type `(u8, u8)`
72+
//~| ERROR suffixes on a tuple index are invalid
73+
4874
{ s.1e+f32; } //~ ERROR unexpected token: `1e+f32`
4975
//~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+f32`
5076
//~| ERROR expected at least one digit in exponent
77+
5178
{ s.1e-f32; } //~ ERROR unexpected token: `1e-f32`
5279
//~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-f32`
5380
//~| ERROR expected at least one digit in exponent
81+
5482
{ s.1e+1f32; } //~ ERROR unexpected token: `1e+1f32`
5583
//~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+1f32`
84+
5685
{ s.1e-1f32; } //~ ERROR unexpected token: `1e-1f32`
5786
//~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-1f32`
87+
5888
{ s.1.1e+1f32; } //~ ERROR unexpected token: `1.1e+1f32`
5989
//~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e+1f32`
90+
6091
{ s.1.1e-1f32; } //~ ERROR unexpected token: `1.1e-1f32`
6192
//~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e-1f32`
6293
}

‎tests/ui/parser/float-field.stderr

+116-110
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.