Skip to content

Commit

Permalink
Auto merge of #106228 - matthiaskrgr:rollup-jsznhww, r=matthiaskrgr
Browse files Browse the repository at this point in the history
Rollup of 8 pull requests

Successful merges:

 - #104402 (Move `ReentrantMutex` to `std::sync`)
 - #104493 (available_parallelism: Gracefully handle zero value cfs_period_us)
 - #105359 (Make sentinel value configurable in `library/std/src/sys_common/thread_local_key.rs`)
 - #105497 (Clarify `catch_unwind` docs about panic hooks)
 - #105570 (Properly calculate best failure in macro matching)
 - #105702 (Format only modified files)
 - #105998 (adjust message on non-unwinding panic)
 - #106161 (Iterator::find: link to Iterator::position in docs for discoverability)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Dec 28, 2022
2 parents 270c94e + 89ccd70 commit 9709a43
Show file tree
Hide file tree
Showing 19 changed files with 213 additions and 31 deletions.
40 changes: 30 additions & 10 deletions compiler/rustc_expand/src/mbe/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub(super) fn failed_to_match_macro<'cx>(
return result;
}

let Some((token, label, remaining_matcher)) = tracker.best_failure else {
let Some(BestFailure { token, msg: label, remaining_matcher, .. }) = tracker.best_failure else {
return DummyResult::any(sp);
};

Expand Down Expand Up @@ -95,11 +95,24 @@ struct CollectTrackerAndEmitter<'a, 'cx, 'matcher> {
cx: &'a mut ExtCtxt<'cx>,
remaining_matcher: Option<&'matcher MatcherLoc>,
/// Which arm's failure should we report? (the one furthest along)
best_failure: Option<(Token, &'static str, MatcherLoc)>,
best_failure: Option<BestFailure>,
root_span: Span,
result: Option<Box<dyn MacResult + 'cx>>,
}

struct BestFailure {
token: Token,
position_in_tokenstream: usize,
msg: &'static str,
remaining_matcher: MatcherLoc,
}

impl BestFailure {
fn is_better_position(&self, position: usize) -> bool {
position > self.position_in_tokenstream
}
}

impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, 'matcher> {
fn before_match_loc(&mut self, parser: &TtParser, matcher: &'matcher MatcherLoc) {
if self.remaining_matcher.is_none()
Expand All @@ -119,18 +132,25 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx,
"should not collect detailed info for successful macro match",
);
}
Failure(token, msg) => match self.best_failure {
Some((ref best_token, _, _)) if best_token.span.lo() >= token.span.lo() => {}
_ => {
self.best_failure = Some((
token.clone(),
Failure(token, approx_position, msg) => {
debug!(?token, ?msg, "a new failure of an arm");

if self
.best_failure
.as_ref()
.map_or(true, |failure| failure.is_better_position(*approx_position))
{
self.best_failure = Some(BestFailure {
token: token.clone(),
position_in_tokenstream: *approx_position,
msg,
self.remaining_matcher
remaining_matcher: self
.remaining_matcher
.expect("must have collected matcher already")
.clone(),
))
})
}
},
}
Error(err_sp, msg) => {
let span = err_sp.substitute_dummy(self.root_span);
self.cx.struct_span_err(span, msg).emit();
Expand Down
13 changes: 11 additions & 2 deletions compiler/rustc_expand/src/mbe/macro_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,8 @@ pub(crate) enum ParseResult<T> {
Success(T),
/// Arm failed to match. If the second parameter is `token::Eof`, it indicates an unexpected
/// end of macro invocation. Otherwise, it indicates that no rules expected the given token.
Failure(Token, &'static str),
/// The usize is the approximate position of the token in the input token stream.
Failure(Token, usize, &'static str),
/// Fatal error (malformed macro?). Abort compilation.
Error(rustc_span::Span, String),
ErrorReported(ErrorGuaranteed),
Expand Down Expand Up @@ -455,6 +456,7 @@ impl TtParser {
&mut self,
matcher: &'matcher [MatcherLoc],
token: &Token,
approx_position: usize,
track: &mut T,
) -> Option<NamedParseResult> {
// Matcher positions that would be valid if the macro invocation was over now. Only
Expand Down Expand Up @@ -598,6 +600,7 @@ impl TtParser {
token::Eof,
if token.span.is_dummy() { token.span } else { token.span.shrink_to_hi() },
),
approx_position,
"missing tokens in macro arguments",
),
})
Expand Down Expand Up @@ -627,7 +630,12 @@ impl TtParser {

// Process `cur_mps` until either we have finished the input or we need to get some
// parsing from the black-box parser done.
let res = self.parse_tt_inner(matcher, &parser.token, track);
let res = self.parse_tt_inner(
matcher,
&parser.token,
parser.approx_token_stream_pos(),
track,
);
if let Some(res) = res {
return res;
}
Expand All @@ -642,6 +650,7 @@ impl TtParser {
// parser: syntax error.
return Failure(
parser.token.clone(),
parser.approx_token_stream_pos(),
"no rules expected this token in macro call",
);
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_expand/src/mbe/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,8 @@ pub(super) fn try_match_macro<'matcher, T: Tracker<'matcher>>(

return Ok((i, named_matches));
}
Failure(_, _) => {
trace!("Failed to match arm, trying the next one");
Failure(_, reached_position, _) => {
trace!(%reached_position, "Failed to match arm, trying the next one");
// Try the next arm.
}
Error(_, _) => {
Expand Down Expand Up @@ -432,7 +432,7 @@ pub fn compile_declarative_macro(
let argument_map =
match tt_parser.parse_tt(&mut Cow::Owned(parser), &argument_gram, &mut NoopTracker) {
Success(m) => m,
Failure(token, msg) => {
Failure(token, _, msg) => {
let s = parse_failure_msg(&token);
let sp = token.span.substitute_dummy(def.span);
let mut err = sess.parse_sess.span_diagnostic.struct_span_err(sp, &s);
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,10 @@ impl<'a> Parser<'a> {
pub fn clear_expected_tokens(&mut self) {
self.expected_tokens.clear();
}

pub fn approx_token_stream_pos(&self) -> usize {
self.token_cursor.num_next_calls
}
}

pub(crate) fn make_unclosed_delims_error(
Expand Down
3 changes: 3 additions & 0 deletions library/core/src/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2654,7 +2654,10 @@ pub trait Iterator {
/// argument is a double reference. You can see this effect in the
/// examples below, with `&&x`.
///
/// If you need the index of the element, see [`position()`].
///
/// [`Some(element)`]: Some
/// [`position()`]: Iterator::position
///
/// # Examples
///
Expand Down
3 changes: 1 addition & 2 deletions library/std/src/io/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ use crate::fmt;
use crate::fs::File;
use crate::io::{self, BufReader, IoSlice, IoSliceMut, LineWriter, Lines};
use crate::sync::atomic::{AtomicBool, Ordering};
use crate::sync::{Arc, Mutex, MutexGuard, OnceLock};
use crate::sync::{Arc, Mutex, MutexGuard, OnceLock, ReentrantMutex, ReentrantMutexGuard};
use crate::sys::stdio;
use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};

type LocalStream = Arc<Mutex<Vec<u8>>>;

Expand Down
3 changes: 3 additions & 0 deletions library/std/src/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ where
/// aborting the process as well. This function *only* catches unwinding panics,
/// not those that abort the process.
///
/// Note that if a custom panic hook has been set, it will be invoked before
/// the panic is caught, before unwinding.
///
/// Also note that unwinding into Rust code with a foreign exception (e.g.
/// an exception thrown from C++ code) is undefined behavior.
///
Expand Down
6 changes: 5 additions & 1 deletion library/std/src/panicking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,11 @@ fn rust_panic_with_hook(
// have limited options. Currently our preference is to
// just abort. In the future we may consider resuming
// unwinding or otherwise exiting the thread cleanly.
rtprintpanic!("thread panicked while panicking. aborting.\n");
if !can_unwind {
rtprintpanic!("thread caused non-unwinding panic. aborting.\n");
} else {
rtprintpanic!("thread panicked while panicking. aborting.\n");
}
crate::sys::abort_internal();
}

Expand Down
3 changes: 3 additions & 0 deletions library/std/src/sync/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ pub use self::lazy_lock::LazyLock;
#[unstable(feature = "once_cell", issue = "74465")]
pub use self::once_lock::OnceLock;

pub(crate) use self::remutex::{ReentrantMutex, ReentrantMutexGuard};

pub mod mpsc;

mod barrier;
Expand All @@ -187,4 +189,5 @@ mod mutex;
mod once;
mod once_lock;
mod poison;
mod remutex;
mod rwlock;
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{ReentrantMutex, ReentrantMutexGuard};
use crate::cell::RefCell;
use crate::sync::Arc;
use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
use crate::thread;

#[test]
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/sys/unix/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ mod cgroups {
let limit = raw_quota.next()?;
let period = raw_quota.next()?;
match (limit.parse::<usize>(), period.parse::<usize>()) {
(Ok(limit), Ok(period)) => {
(Ok(limit), Ok(period)) if period > 0 => {
quota = quota.min(limit / period);
}
_ => {}
Expand Down Expand Up @@ -565,7 +565,7 @@ mod cgroups {
let period = parse_file("cpu.cfs_period_us");

match (limit, period) {
(Some(limit), Some(period)) => quota = quota.min(limit / period),
(Some(limit), Some(period)) if period > 0 => quota = quota.min(limit / period),
_ => {}
}

Expand Down
1 change: 0 additions & 1 deletion library/std/src/sys_common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ pub mod lazy_box;
pub mod memchr;
pub mod once;
pub mod process;
pub mod remutex;
pub mod thread;
pub mod thread_info;
pub mod thread_local_dtor;
Expand Down
25 changes: 17 additions & 8 deletions library/std/src/sys_common/thread_local_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,14 @@ pub struct Key {
/// This value specifies no destructor by default.
pub const INIT: StaticKey = StaticKey::new(None);

// Define a sentinel value that is unlikely to be returned
// as a TLS key (but it may be returned).
const KEY_SENTVAL: usize = 0;

impl StaticKey {
#[rustc_const_unstable(feature = "thread_local_internals", issue = "none")]
pub const fn new(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> StaticKey {
StaticKey { key: atomic::AtomicUsize::new(0), dtor }
StaticKey { key: atomic::AtomicUsize::new(KEY_SENTVAL), dtor }
}

/// Gets the value associated with this TLS key
Expand All @@ -144,31 +148,36 @@ impl StaticKey {
#[inline]
unsafe fn key(&self) -> imp::Key {
match self.key.load(Ordering::Relaxed) {
0 => self.lazy_init() as imp::Key,
KEY_SENTVAL => self.lazy_init() as imp::Key,
n => n as imp::Key,
}
}

unsafe fn lazy_init(&self) -> usize {
// POSIX allows the key created here to be 0, but the compare_exchange
// below relies on using 0 as a sentinel value to check who won the
// POSIX allows the key created here to be KEY_SENTVAL, but the compare_exchange
// below relies on using KEY_SENTVAL as a sentinel value to check who won the
// race to set the shared TLS key. As far as I know, there is no
// guaranteed value that cannot be returned as a posix_key_create key,
// so there is no value we can initialize the inner key with to
// prove that it has not yet been set. As such, we'll continue using a
// value of 0, but with some gyrations to make sure we have a non-0
// value of KEY_SENTVAL, but with some gyrations to make sure we have a non-KEY_SENTVAL
// value returned from the creation routine.
// FIXME: this is clearly a hack, and should be cleaned up.
let key1 = imp::create(self.dtor);
let key = if key1 != 0 {
let key = if key1 as usize != KEY_SENTVAL {
key1
} else {
let key2 = imp::create(self.dtor);
imp::destroy(key1);
key2
};
rtassert!(key != 0);
match self.key.compare_exchange(0, key as usize, Ordering::SeqCst, Ordering::SeqCst) {
rtassert!(key as usize != KEY_SENTVAL);
match self.key.compare_exchange(
KEY_SENTVAL,
key as usize,
Ordering::SeqCst,
Ordering::SeqCst,
) {
// The CAS succeeded, so we've created the actual key
Ok(_) => key as usize,
// If someone beat us to the punch, use their key instead
Expand Down
1 change: 1 addition & 0 deletions src/bootstrap/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Several unsupported `./configure` options have been removed: `optimize`, `parallel-compiler`. These can still be enabled with `--set`, although it isn't recommended.
- `remote-test-server`'s `verbose` argument has been removed in favor of the `--verbose` flag
- `remote-test-server`'s `remote` argument has been removed in favor of the `--bind` flag. Use `--bind 0.0.0.0:12345` to replicate the behavior of the `remote` argument.
- `x.py fmt` now formats only files modified between the merge-base of HEAD and the last commit in the master branch of the rust-lang repository and the current working directory. To restore old behaviour, use `x.py fmt .`. The check mode is not affected by this change. [#105702](https://github.com/rust-lang/rust/pull/105702)

### Non-breaking changes

Expand Down
1 change: 1 addition & 0 deletions src/bootstrap/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ fn clean_default(build: &Build, all: bool) {
rm_rf(&build.out.join("tmp"));
rm_rf(&build.out.join("dist"));
rm_rf(&build.out.join("bootstrap"));
rm_rf(&build.out.join("rustfmt.stamp"));

for host in &build.hosts {
let entries = match build.out.join(host.triple).read_dir() {
Expand Down
Loading

0 comments on commit 9709a43

Please sign in to comment.