From 2d854f9c340df887e30896f49270ae81feb3e227 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 2 Mar 2022 15:22:32 +0100 Subject: [PATCH 1/9] Remove num_cpus dependency from bootstrap, build-manifest and rustc_session --- Cargo.lock | 3 --- compiler/rustc_session/Cargo.toml | 1 - compiler/rustc_session/src/options.rs | 2 +- src/bootstrap/Cargo.toml | 1 - src/bootstrap/config.rs | 2 +- src/bootstrap/flags.rs | 2 +- src/bootstrap/lib.rs | 4 +++- src/tools/build-manifest/Cargo.toml | 1 - src/tools/build-manifest/src/main.rs | 2 +- 9 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f0c6e371c38..716f4d75014 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -221,7 +221,6 @@ dependencies = [ "getopts", "ignore", "libc", - "num_cpus", "once_cell", "opener", "pretty_assertions", @@ -249,7 +248,6 @@ dependencies = [ "anyhow", "flate2", "hex 0.4.2", - "num_cpus", "rayon", "serde", "serde_json", @@ -4241,7 +4239,6 @@ name = "rustc_session" version = "0.0.0" dependencies = [ "getopts", - "num_cpus", "rustc_ast", "rustc_data_structures", "rustc_errors", diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index 37cfc4a0dc3..6b1eaa4d399 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -15,6 +15,5 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_span = { path = "../rustc_span" } rustc_fs_util = { path = "../rustc_fs_util" } -num_cpus = "1.0" rustc_ast = { path = "../rustc_ast" } rustc_lint_defs = { path = "../rustc_lint_defs" } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index c2b13346cd6..43123d30ad5 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -551,7 +551,7 @@ mod parse { crate fn parse_threads(slot: &mut usize, v: Option<&str>) -> bool { match v.and_then(|s| s.parse().ok()) { Some(0) => { - *slot = ::num_cpus::get(); + *slot = std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get); true } Some(i) => { diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 592a137e379..02efc08cc79 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -37,7 +37,6 @@ test = false build_helper = { path = "../build_helper" } cmake = "0.1.38" filetime = "0.2" -num_cpus = "1.0" getopts = "0.2.19" cc = "1.0.69" libc = "0.2" diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index d6f77fe6cd6..ce76ccd5755 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -1187,7 +1187,7 @@ fn set(field: &mut T, val: Option) { fn threads_from_config(v: u32) -> u32 { match v { - 0 => num_cpus::get() as u32, + 0 => std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32, n => n, } } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 9180c5f03af..74528f2752f 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -208,7 +208,7 @@ To learn more about a subcommand, run `./x.py -h`", let j_msg = format!( "number of jobs to run in parallel; \ defaults to {} (this host's logical CPU count)", - num_cpus::get() + std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) ); opts.optopt("j", "jobs", &j_msg, "JOBS"); opts.optflag("h", "help", "print this help message"); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 86339c8d7f8..6a58de40181 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -917,7 +917,9 @@ impl Build { /// Returns the number of parallel jobs that have been configured for this /// build. fn jobs(&self) -> u32 { - self.config.jobs.unwrap_or_else(|| num_cpus::get() as u32) + self.config.jobs.unwrap_or_else(|| { + std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32 + }) } fn debuginfo_map_to(&self, which: GitRepo) -> Option { diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml index c022d3aa0ac..c437bde5ae6 100644 --- a/src/tools/build-manifest/Cargo.toml +++ b/src/tools/build-manifest/Cargo.toml @@ -13,4 +13,3 @@ tar = "0.4.29" sha2 = "0.10.1" rayon = "1.5.1" hex = "0.4.2" -num_cpus = "1.13.0" diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 8a62146abfc..378efeb6443 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -208,7 +208,7 @@ fn main() { let num_threads = if let Some(num) = env::var_os("BUILD_MANIFEST_NUM_THREADS") { num.to_str().unwrap().parse().expect("invalid number for BUILD_MANIFEST_NUM_THREADS") } else { - num_cpus::get() + std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) }; rayon::ThreadPoolBuilder::new() .num_threads(num_threads) From dadf2adbe9bbb528d8d143405014c08341d87187 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 3 Mar 2022 11:19:50 +0100 Subject: [PATCH 2/9] Rename JoinHandle::is_running to is_finished and update docs. Co-authored-by: Josh Triplett --- library/std/src/thread/mod.rs | 13 +++++++++---- library/std/src/thread/scoped.rs | 13 +++++++++---- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index beb60609934..712df02de75 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -1443,13 +1443,18 @@ impl JoinHandle { self.0.join() } - /// Checks if the associated thread is still running its main function. + /// Checks if the associated thread has finished running its main function. /// - /// This might return `false` for a brief moment after the thread's main + /// This might return `true` for a brief moment after the thread's main /// function has returned, but before the thread itself has stopped running. + /// However, once this returns `true`, [`join`][Self::join] can be expected + /// to return quickly, without blocking for any significant amount of time. + /// + /// This function does not block. To block while waiting on the thread to finish, + /// use [`join`][Self::join]. #[unstable(feature = "thread_is_running", issue = "90470")] - pub fn is_running(&self) -> bool { - Arc::strong_count(&self.0.packet) > 1 + pub fn is_finished(&self) -> bool { + Arc::strong_count(&self.0.packet) == 1 } } diff --git a/library/std/src/thread/scoped.rs b/library/std/src/thread/scoped.rs index 9dd7c15fc59..9b2cc4cbc6e 100644 --- a/library/std/src/thread/scoped.rs +++ b/library/std/src/thread/scoped.rs @@ -289,13 +289,18 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> { self.0.join() } - /// Checks if the associated thread is still running its main function. + /// Checks if the associated thread has finished running its main function. /// - /// This might return `false` for a brief moment after the thread's main + /// This might return `true` for a brief moment after the thread's main /// function has returned, but before the thread itself has stopped running. + /// However, once this returns `true`, [`join`][Self::join] can be expected + /// to return quickly, without blocking for any significant amount of time. + /// + /// This function does not block. To block while waiting on the thread to finish, + /// use [`join`][Self::join]. #[unstable(feature = "thread_is_running", issue = "90470")] - pub fn is_running(&self) -> bool { - Arc::strong_count(&self.0.packet) > 1 + pub fn is_finished(&self) -> bool { + Arc::strong_count(&self.0.packet) == 1 } } From c021ac35fa68d1d110c07ccf970a49e1f3a89607 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 3 Mar 2022 11:24:20 +0100 Subject: [PATCH 3/9] Update test. --- library/std/src/thread/tests.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs index 4f2c81731a3..3323ba36bf3 100644 --- a/library/std/src/thread/tests.rs +++ b/library/std/src/thread/tests.rs @@ -52,7 +52,7 @@ fn test_run_basic() { } #[test] -fn test_is_running() { +fn test_is_finished() { let b = Arc::new(Barrier::new(2)); let t = thread::spawn({ let b = b.clone(); @@ -63,14 +63,14 @@ fn test_is_running() { }); // Thread is definitely running here, since it's still waiting for the barrier. - assert_eq!(t.is_running(), true); + assert_eq!(t.is_finished(), false); // Unblock the barrier. b.wait(); - // Now check that t.is_running() becomes false within a reasonable time. + // Now check that t.is_finished() becomes true within a reasonable time. let start = Instant::now(); - while t.is_running() { + while !t.is_finished() { assert!(start.elapsed() < Duration::from_secs(2)); thread::sleep(Duration::from_millis(15)); } From af86b55735bac498756cddd837c3ebec68811122 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 3 Mar 2022 11:24:26 +0100 Subject: [PATCH 4/9] Remove unnecessary #![feature]s from doctest. --- library/std/src/thread/scoped.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/std/src/thread/scoped.rs b/library/std/src/thread/scoped.rs index 9b2cc4cbc6e..ea9623be63b 100644 --- a/library/std/src/thread/scoped.rs +++ b/library/std/src/thread/scoped.rs @@ -240,7 +240,6 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> { /// /// ``` /// #![feature(scoped_threads)] - /// #![feature(thread_is_running)] /// /// use std::thread; /// @@ -274,7 +273,6 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> { /// /// ``` /// #![feature(scoped_threads)] - /// #![feature(thread_is_running)] /// /// use std::thread; /// From 7f5bdf3ccbe4fb1df28da205777cee476953a937 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 2 Mar 2022 18:23:08 +0100 Subject: [PATCH 5/9] Remove some dead code from toolstate.rs --- src/bootstrap/toolstate.rs | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs index 2394c5e020d..08d08158062 100644 --- a/src/bootstrap/toolstate.rs +++ b/src/bootstrap/toolstate.rs @@ -24,7 +24,7 @@ const OS: Option<&str> = None; type ToolstateData = HashMap, ToolState>; -#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd)] +#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, PartialOrd)] #[serde(rename_all = "kebab-case")] /// Whether a tool can be compiled, tested or neither pub enum ToolState { @@ -50,13 +50,6 @@ impl fmt::Display for ToolState { } } -impl Default for ToolState { - fn default() -> Self { - // err on the safe side - ToolState::BuildFail - } -} - /// Number of days after the last promotion of beta. /// Its value is 41 on the Tuesday where "Promote master to beta (T-2)" happens. /// The Wednesday after this has value 0. @@ -466,13 +459,11 @@ fn publish_test_results(current_toolstate: &ToolstateData) { t!(fs::write(&history_path, file)); } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Deserialize)] struct RepoState { tool: String, windows: ToolState, linux: ToolState, - commit: String, - datetime: String, } impl RepoState { From e8f790fec7eda5ca722c38ca6b2ebf84399a0165 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 2 Mar 2022 18:29:00 +0100 Subject: [PATCH 6/9] Remove unused Default and Clone derives in config.rs --- src/bootstrap/config.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index d6f77fe6cd6..ccc6c49d2b2 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -387,7 +387,7 @@ macro_rules! derive_merge { derive_merge! { /// TOML representation of various global build decisions. - #[derive(Deserialize, Default, Clone)] + #[derive(Deserialize, Default)] #[serde(deny_unknown_fields, rename_all = "kebab-case")] struct Build { build: Option, @@ -434,7 +434,7 @@ derive_merge! { derive_merge! { /// TOML representation of various global install decisions. - #[derive(Deserialize, Default, Clone)] + #[derive(Deserialize)] #[serde(deny_unknown_fields, rename_all = "kebab-case")] struct Install { prefix: Option, @@ -449,7 +449,7 @@ derive_merge! { derive_merge! { /// TOML representation of how the LLVM build is configured. - #[derive(Deserialize, Default)] + #[derive(Deserialize)] #[serde(deny_unknown_fields, rename_all = "kebab-case")] struct Llvm { skip_rebuild: Option, @@ -483,7 +483,7 @@ derive_merge! { } derive_merge! { - #[derive(Deserialize, Default, Clone)] + #[derive(Deserialize)] #[serde(deny_unknown_fields, rename_all = "kebab-case")] struct Dist { sign_folder: Option, @@ -510,7 +510,7 @@ impl Default for StringOrBool { derive_merge! { /// TOML representation of how the Rust build is configured. - #[derive(Deserialize, Default)] + #[derive(Deserialize)] #[serde(deny_unknown_fields, rename_all = "kebab-case")] struct Rust { optimize: Option, @@ -565,7 +565,7 @@ derive_merge! { derive_merge! { /// TOML representation of how each build target is configured. - #[derive(Deserialize, Default)] + #[derive(Deserialize)] #[serde(deny_unknown_fields, rename_all = "kebab-case")] struct TomlTarget { cc: Option, From 004f2ed219378235c24a5d6bdb34337200e6eeed Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Fri, 4 Mar 2022 02:03:55 +0000 Subject: [PATCH 7/9] Do not recover from `Ty?` in macro parsing Follow up to #92746. Address #94510. --- .../rustc_parse/src/parser/diagnostics.rs | 6 ++-- .../rustc_parse/src/parser/nonterminal.rs | 2 +- compiler/rustc_parse/src/parser/ty.rs | 34 +++++++++++++------ .../parser/trailing-question-in-macro-type.rs | 14 ++++++++ .../trailing-question-in-macro-type.stderr | 9 +++++ 5 files changed, 50 insertions(+), 15 deletions(-) create mode 100644 src/test/ui/parser/trailing-question-in-macro-type.rs create mode 100644 src/test/ui/parser/trailing-question-in-macro-type.stderr diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index c7aa9ffc793..40daf4eb28f 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1,5 +1,5 @@ use super::pat::Expected; -use super::ty::{AllowPlus, IsAsCast}; +use super::ty::{AllowPlus, RecoverQuestionMark}; use super::{ BlockMode, CommaRecoveryMode, Parser, PathStyle, RecoverColon, RecoverComma, Restrictions, SemiColonMode, SeqSep, TokenExpectType, TokenType, @@ -1049,9 +1049,9 @@ impl<'a> Parser<'a> { pub(super) fn maybe_recover_from_question_mark( &mut self, ty: P, - is_as_cast: IsAsCast, + recover_question_mark: RecoverQuestionMark, ) -> P { - if let IsAsCast::Yes = is_as_cast { + if let RecoverQuestionMark::No = recover_question_mark { return ty; } if self.token == token::Question { diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 83e0a4997ad..40902fa1833 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -140,7 +140,7 @@ impl<'a> Parser<'a> { } NonterminalKind::Ty => { - token::NtTy(self.collect_tokens_no_attrs(|this| this.parse_ty())?) + token::NtTy(self.collect_tokens_no_attrs(|this| this.parse_no_question_mark_recover())?) } // this could be handled like a token, since it is one NonterminalKind::Ident diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 0b01f9e927f..436c5bd4fca 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -44,7 +44,7 @@ pub(super) enum RecoverQPath { No, } -pub(super) enum IsAsCast { +pub(super) enum RecoverQuestionMark { Yes, No, } @@ -105,7 +105,7 @@ impl<'a> Parser<'a> { RecoverQPath::Yes, RecoverReturnSign::Yes, None, - IsAsCast::No, + RecoverQuestionMark::Yes, ) } @@ -119,7 +119,7 @@ impl<'a> Parser<'a> { RecoverQPath::Yes, RecoverReturnSign::Yes, Some(ty_params), - IsAsCast::No, + RecoverQuestionMark::Yes, ) } @@ -133,7 +133,7 @@ impl<'a> Parser<'a> { RecoverQPath::Yes, RecoverReturnSign::Yes, None, - IsAsCast::No, + RecoverQuestionMark::Yes, ) } @@ -150,7 +150,7 @@ impl<'a> Parser<'a> { RecoverQPath::Yes, RecoverReturnSign::Yes, None, - IsAsCast::No, + RecoverQuestionMark::Yes, ) } @@ -163,9 +163,21 @@ impl<'a> Parser<'a> { RecoverQPath::Yes, RecoverReturnSign::Yes, None, - IsAsCast::Yes, + RecoverQuestionMark::No, ) } + + pub(super) fn parse_no_question_mark_recover(&mut self) -> PResult<'a, P> { + self.parse_ty_common( + AllowPlus::Yes, + AllowCVariadic::No, + RecoverQPath::Yes, + RecoverReturnSign::Yes, + None, + RecoverQuestionMark::No, + ) + } + /// Parse a type without recovering `:` as `->` to avoid breaking code such as `where fn() : for<'a>` pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, P> { self.parse_ty_common( @@ -174,7 +186,7 @@ impl<'a> Parser<'a> { RecoverQPath::Yes, RecoverReturnSign::OnlyFatArrow, None, - IsAsCast::No, + RecoverQuestionMark::Yes, ) } @@ -193,7 +205,7 @@ impl<'a> Parser<'a> { recover_qpath, recover_return_sign, None, - IsAsCast::No, + RecoverQuestionMark::Yes, )?; FnRetTy::Ty(ty) } else if recover_return_sign.can_recover(&self.token.kind) { @@ -214,7 +226,7 @@ impl<'a> Parser<'a> { recover_qpath, recover_return_sign, None, - IsAsCast::No, + RecoverQuestionMark::Yes, )?; FnRetTy::Ty(ty) } else { @@ -229,7 +241,7 @@ impl<'a> Parser<'a> { recover_qpath: RecoverQPath, recover_return_sign: RecoverReturnSign, ty_generics: Option<&Generics>, - is_as_cast: IsAsCast, + recover_question_mark: RecoverQuestionMark, ) -> PResult<'a, P> { let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes; maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery); @@ -305,7 +317,7 @@ impl<'a> Parser<'a> { // Try to recover from use of `+` with incorrect priority. self.maybe_report_ambiguous_plus(allow_plus, impl_dyn_multi, &ty); self.maybe_recover_from_bad_type_plus(allow_plus, &ty)?; - let ty = self.maybe_recover_from_question_mark(ty, is_as_cast); + let ty = self.maybe_recover_from_question_mark(ty, recover_question_mark); self.maybe_recover_from_bad_qpath(ty, allow_qpath_recovery) } diff --git a/src/test/ui/parser/trailing-question-in-macro-type.rs b/src/test/ui/parser/trailing-question-in-macro-type.rs new file mode 100644 index 00000000000..e2a681ddd11 --- /dev/null +++ b/src/test/ui/parser/trailing-question-in-macro-type.rs @@ -0,0 +1,14 @@ +macro_rules! fn_expr { + ($return_type:ty : $body:expr) => { + (|| -> $return_type { $body })() + }; + ($body:expr) => { + (|| $body)() + }; +} + + +fn main() { + fn_expr!{ o?.when(|&i| i > 0)?.when(|&i| i%2 == 0) }; + //~^ ERROR cannot find value `o` in this scope +} diff --git a/src/test/ui/parser/trailing-question-in-macro-type.stderr b/src/test/ui/parser/trailing-question-in-macro-type.stderr new file mode 100644 index 00000000000..c096ae04fbb --- /dev/null +++ b/src/test/ui/parser/trailing-question-in-macro-type.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `o` in this scope + --> $DIR/trailing-question-in-macro-type.rs:12:15 + | +LL | fn_expr!{ o?.when(|&i| i > 0)?.when(|&i| i%2 == 0) }; + | ^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`. From bca67fe02f010754b5522c2c6234375cffa66b81 Mon Sep 17 00:00:00 2001 From: reez12g Date: Tue, 22 Feb 2022 08:37:52 +0900 Subject: [PATCH 8/9] Add #[track_caller] to track callers when initializing poisoned Once --- library/std/src/sync/once.rs | 2 ++ src/test/ui/issues/issue-87707.rs | 15 +++++++++++++++ src/test/ui/issues/issue-87707.run.stderr | 3 +++ 3 files changed, 20 insertions(+) create mode 100644 src/test/ui/issues/issue-87707.rs create mode 100644 src/test/ui/issues/issue-87707.run.stderr diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs index f76d0759561..511de863dc5 100644 --- a/library/std/src/sync/once.rs +++ b/library/std/src/sync/once.rs @@ -256,6 +256,7 @@ impl Once { /// /// [poison]: struct.Mutex.html#poisoning #[stable(feature = "rust1", since = "1.0.0")] + #[track_caller] pub fn call_once(&self, f: F) where F: FnOnce(), @@ -390,6 +391,7 @@ impl Once { // currently no way to take an `FnOnce` and call it via virtual dispatch // without some allocation overhead. #[cold] + #[track_caller] fn call_inner(&self, ignore_poisoning: bool, init: &mut dyn FnMut(&OnceState)) { let mut state_and_queue = self.state_and_queue.load(Ordering::Acquire); loop { diff --git a/src/test/ui/issues/issue-87707.rs b/src/test/ui/issues/issue-87707.rs new file mode 100644 index 00000000000..d2e9343f86c --- /dev/null +++ b/src/test/ui/issues/issue-87707.rs @@ -0,0 +1,15 @@ +// test for #87707 +// edition:2018 +// run-fail +// check-run-results + +use std::sync::Once; +use std::panic; + +fn main() { + let o = Once::new(); + let _ = panic::catch_unwind(|| { + o.call_once(|| panic!("Here Once instance is poisoned.")); + }); + o.call_once(|| {}); +} diff --git a/src/test/ui/issues/issue-87707.run.stderr b/src/test/ui/issues/issue-87707.run.stderr new file mode 100644 index 00000000000..8f82ccc0c2a --- /dev/null +++ b/src/test/ui/issues/issue-87707.run.stderr @@ -0,0 +1,3 @@ +thread 'main' panicked at 'Here Once instance is poisoned.', $DIR/issue-87707.rs:12:24 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +thread 'main' panicked at 'Once instance has previously been poisoned', $DIR/issue-87707.rs:14:7 From 18528a2ddb84cf62be69d8c8893731e50c859eb9 Mon Sep 17 00:00:00 2001 From: est31 Date: Fri, 4 Mar 2022 10:35:00 +0100 Subject: [PATCH 9/9] Use if let instead of manual match --- src/librustdoc/clean/types.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 78928fb4059..c0e7cd0b1f5 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1506,11 +1506,11 @@ impl Type { } crate fn projection(&self) -> Option<(&Type, DefId, PathSegment)> { - let (self_, trait_, assoc) = match self { - QPath { self_type, trait_, assoc, .. } => (self_type, trait_, assoc), - _ => return None, - }; - Some((&self_, trait_.def_id(), *assoc.clone())) + if let QPath { self_type, trait_, assoc, .. } = self { + Some((&self_type, trait_.def_id(), *assoc.clone())) + } else { + None + } } fn inner_def_id(&self, cache: Option<&Cache>) -> Option {