From dbb9bbb7242701845ced0ed44abcbe78282bd8a0 Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 13 Jan 2026 20:41:41 +0800 Subject: [PATCH 1/7] Fix wrong suggestion for returning async closure --- .../src/error_reporting/traits/suggestions.rs | 66 +++++++++++++++---- .../const_param_ty_bad.stderr | 5 +- .../suggest-create-closure-issue-150701.fixed | 15 +++++ .../suggest-create-closure-issue-150701.rs | 15 +++++ ...suggest-create-closure-issue-150701.stderr | 51 ++++++++++++++ ...theses-to-call-closure-issue-145404.stderr | 5 +- 6 files changed, 138 insertions(+), 19 deletions(-) create mode 100644 tests/ui/suggestions/suggest-create-closure-issue-150701.fixed create mode 100644 tests/ui/suggestions/suggest-create-closure-issue-150701.rs create mode 100644 tests/ui/suggestions/suggest-create-closure-issue-150701.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 511e9e85b5f60..7dfeb6379c427 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -835,23 +835,63 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .collect::>() .join(", "); - if matches!(obligation.cause.code(), ObligationCauseCode::FunctionArg { .. }) + if let ObligationCauseCode::FunctionArg { arg_hir_id, .. } = obligation.cause.code() && obligation.cause.span.can_be_used_for_suggestions() { - let (span, sugg) = if let Some(snippet) = - self.tcx.sess.source_map().span_to_snippet(obligation.cause.span).ok() - && snippet.starts_with("|") - { - (obligation.cause.span, format!("({snippet})({args})")) - } else { - (obligation.cause.span.shrink_to_hi(), format!("({args})")) + let span = obligation.cause.span; + + let arg_expr = match self.tcx.hir_node(*arg_hir_id) { + hir::Node::Expr(expr) => Some(expr), + _ => None, }; - // When the obligation error has been ensured to have been caused by - // an argument, the `obligation.cause.span` points at the expression - // of the argument, so we can provide a suggestion. Otherwise, we give - // a more general note. - err.span_suggestion_verbose(span, msg, sugg, Applicability::HasPlaceholders); + let is_closure_expr = + arg_expr.is_some_and(|expr| matches!(expr.kind, hir::ExprKind::Closure(..))); + + // If the user wrote `|| {}()`, suggesting to call the closure would produce `(|| {}())()`, + // which doesn't help and is often outright wrong. + if args.is_empty() + && let Some(expr) = arg_expr + && let hir::ExprKind::Closure(closure) = expr.kind + { + let mut body = self.tcx.hir_body(closure.body).value; + + // Async closures desugar to a closure returning a coroutine + if let hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async) = + closure.kind + { + let peeled = body.peel_blocks().peel_drop_temps(); + if let hir::ExprKind::Closure(inner) = peeled.kind { + body = self.tcx.hir_body(inner.body).value; + } + } + + let peeled_body = body.peel_blocks().peel_drop_temps(); + if let hir::ExprKind::Call(callee, call_args) = peeled_body.kind + && call_args.is_empty() + && let hir::ExprKind::Block(..) = callee.peel_blocks().peel_drop_temps().kind + { + return false; + } + } + + if is_closure_expr { + err.multipart_suggestion_verbose( + msg, + vec![ + (span.shrink_to_lo(), "(".to_string()), + (span.shrink_to_hi(), format!(")({args})")), + ], + Applicability::HasPlaceholders, + ); + } else { + err.span_suggestion_verbose( + span.shrink_to_hi(), + msg, + format!("({args})"), + Applicability::HasPlaceholders, + ); + } } else if let DefIdOrName::DefId(def_id) = def_id_or_name { let name = match self.tcx.hir_get_if_local(def_id) { Some(hir::Node::Expr(hir::Expr { diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr index 5109dccd96a1d..cb58dd96e3d3f 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr @@ -32,9 +32,8 @@ LL | fn check(_: impl std::marker::ConstParamTy_) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` help: use parentheses to call this closure | -LL - check(|| {}); -LL + check((|| {})()); - | +LL | check((|| {})()); + | + +++ error[E0277]: `fn()` can't be used as a const parameter type --> $DIR/const_param_ty_bad.rs:9:11 diff --git a/tests/ui/suggestions/suggest-create-closure-issue-150701.fixed b/tests/ui/suggestions/suggest-create-closure-issue-150701.fixed new file mode 100644 index 0000000000000..81b0a4e6a5cb8 --- /dev/null +++ b/tests/ui/suggestions/suggest-create-closure-issue-150701.fixed @@ -0,0 +1,15 @@ +// Regression test for #150701 + +//@ run-rustfix +//@ edition: 2024 + +use std::future::Future; + +fn f(_c: impl Future) {} + +fn main() { + f((async || {})()); //~ ERROR: expected function, found `()` + //~^ ERROR: is not a future + f((async || {})()); + //~^ ERROR: is not a future +} diff --git a/tests/ui/suggestions/suggest-create-closure-issue-150701.rs b/tests/ui/suggestions/suggest-create-closure-issue-150701.rs new file mode 100644 index 0000000000000..e7a5076d8f1d9 --- /dev/null +++ b/tests/ui/suggestions/suggest-create-closure-issue-150701.rs @@ -0,0 +1,15 @@ +// Regression test for #150701 + +//@ run-rustfix +//@ edition: 2024 + +use std::future::Future; + +fn f(_c: impl Future) {} + +fn main() { + f(async || {}()); //~ ERROR: expected function, found `()` + //~^ ERROR: is not a future + f(async || {}); + //~^ ERROR: is not a future +} diff --git a/tests/ui/suggestions/suggest-create-closure-issue-150701.stderr b/tests/ui/suggestions/suggest-create-closure-issue-150701.stderr new file mode 100644 index 0000000000000..52209123e5345 --- /dev/null +++ b/tests/ui/suggestions/suggest-create-closure-issue-150701.stderr @@ -0,0 +1,51 @@ +error[E0618]: expected function, found `()` + --> $DIR/suggest-create-closure-issue-150701.rs:11:16 + | +LL | f(async || {}()); + | ^^-- + | | + | call expression requires function + | +help: if you meant to create this closure and immediately call it, surround the closure with parentheses + | +LL | f((async || {})()); + | + + + +error[E0277]: `{async closure@$DIR/suggest-create-closure-issue-150701.rs:11:7: 11:15}` is not a future + --> $DIR/suggest-create-closure-issue-150701.rs:11:7 + | +LL | f(async || {}()); + | - ^^^^^^^^^^^^^ `{async closure@$DIR/suggest-create-closure-issue-150701.rs:11:7: 11:15}` is not a future + | | + | required by a bound introduced by this call + | + = help: the trait `Future` is not implemented for `{async closure@$DIR/suggest-create-closure-issue-150701.rs:11:7: 11:15}` +note: required by a bound in `f` + --> $DIR/suggest-create-closure-issue-150701.rs:8:15 + | +LL | fn f(_c: impl Future) {} + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `f` + +error[E0277]: `{async closure@$DIR/suggest-create-closure-issue-150701.rs:13:7: 13:15}` is not a future + --> $DIR/suggest-create-closure-issue-150701.rs:13:7 + | +LL | f(async || {}); + | - ^^^^^^^^^^^ `{async closure@$DIR/suggest-create-closure-issue-150701.rs:13:7: 13:15}` is not a future + | | + | required by a bound introduced by this call + | + = help: the trait `Future` is not implemented for `{async closure@$DIR/suggest-create-closure-issue-150701.rs:13:7: 13:15}` +note: required by a bound in `f` + --> $DIR/suggest-create-closure-issue-150701.rs:8:15 + | +LL | fn f(_c: impl Future) {} + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `f` +help: use parentheses to call this closure + | +LL | f((async || {})()); + | + +++ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0618. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/suggestions/use-parentheses-to-call-closure-issue-145404.stderr b/tests/ui/suggestions/use-parentheses-to-call-closure-issue-145404.stderr index cb6df5af7fb16..e32b2d4a30c80 100644 --- a/tests/ui/suggestions/use-parentheses-to-call-closure-issue-145404.stderr +++ b/tests/ui/suggestions/use-parentheses-to-call-closure-issue-145404.stderr @@ -14,9 +14,8 @@ LL | fn call(&self, _: impl Display) {} | ^^^^^^^ required by this bound in `S::call` help: use parentheses to call this closure | -LL - S.call(|| "hello"); -LL + S.call((|| "hello")()); - | +LL | S.call((|| "hello")()); + | + +++ error: aborting due to 1 previous error From f1d5fdefa8e8d7a2bacb640888bc6f4e4d1b6b6d Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Fri, 23 Jan 2026 23:18:36 -0600 Subject: [PATCH 2/7] Fix Hexagon ABI calling convention for small aggregates Small structs (<= 64 bits) were being passed with their fields split into separate arguments instead of being packed into register-sized chunks. This caused ABI mismatches. The fix properly casts small aggregates to consecutive register-sized chunks using Uniform::consecutive(), matching the Hexagon C ABI where small structs are packed into R1:0 register pair. This fixes tests like extern-pass-TwoU16s.rs and extern-pass-TwoU8s.rs. --- compiler/rustc_target/src/callconv/hexagon.rs | 58 +++++++++++++++---- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_target/src/callconv/hexagon.rs b/compiler/rustc_target/src/callconv/hexagon.rs index e08e6daa7405a..e07aa32251aa2 100644 --- a/compiler/rustc_target/src/callconv/hexagon.rs +++ b/compiler/rustc_target/src/callconv/hexagon.rs @@ -1,36 +1,74 @@ -use rustc_abi::TyAbiInterface; +use rustc_abi::{HasDataLayout, TyAbiInterface}; -use crate::callconv::{ArgAbi, FnAbi}; +use crate::callconv::{ArgAbi, FnAbi, Reg, Uniform}; -fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { - if ret.layout.is_aggregate() && ret.layout.size.bits() > 64 { - ret.make_indirect(); - } else { +fn classify_ret<'a, Ty, C>(_cx: &C, ret: &mut ArgAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, +{ + if !ret.layout.is_sized() { + return; + } + if !ret.layout.is_aggregate() { ret.extend_integer_width_to(32); + return; + } + + let size = ret.layout.size; + let bits = size.bits(); + + // Aggregates larger than 64 bits are returned indirectly + if bits > 64 { + ret.make_indirect(); + return; } + + // Small aggregates are returned in registers + // Cast to appropriate register type to ensure proper ABI + let align = ret.layout.align.bytes(); + ret.cast_to(Uniform::consecutive(if align <= 4 { Reg::i32() } else { Reg::i64() }, size)); } fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) where Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { + if !arg.layout.is_sized() { + return; + } if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { arg.make_indirect(); return; } - if arg.layout.is_aggregate() && arg.layout.size.bits() > 64 { - arg.make_indirect(); - } else { + if !arg.layout.is_aggregate() { arg.extend_integer_width_to(32); + return; } + + let size = arg.layout.size; + let bits = size.bits(); + + // Aggregates larger than 64 bits are passed indirectly + if bits > 64 { + arg.make_indirect(); + return; + } + + // Small aggregates are passed in registers + // Cast to consecutive register-sized chunks to match the C ABI + let align = arg.layout.align.bytes(); + arg.cast_to(Uniform::consecutive(if align <= 4 { Reg::i32() } else { Reg::i64() }, size)); } pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) where Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !fn_abi.ret.is_ignore() { - classify_ret(&mut fn_abi.ret); + classify_ret(cx, &mut fn_abi.ret); } for arg in fn_abi.args.iter_mut() { From b1925a9791a3097065af228f9b109430b92d75de Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Sat, 24 Jan 2026 13:46:00 -0600 Subject: [PATCH 3/7] Fix Hexagon ABI calling convention for aggregates Correct the handling of aggregate types in extern "C" functions to match the Hexagon ABI specification: - Aggregates up to 32 bits: passed/returned in a single register (R0) - Aggregates 33-64 bits: passed/returned in a register pair (R1:R0) - Aggregates > 64 bits: passed on stack via byval, returned via sret This fixes all tests/ui/abi/extern/ tests for Hexagon, including: - extern-pass-TwoU8s, extern-pass-TwoU16s, extern-pass-TwoU32s - extern-pass-TwoU64s, extern-pass-FiveU16s - extern-return-TwoU8s, extern-return-TwoU16s, extern-return-TwoU32s - extern-return-TwoU64s, extern-return-FiveU16s --- compiler/rustc_target/src/callconv/hexagon.rs | 40 ++++++++++--------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_target/src/callconv/hexagon.rs b/compiler/rustc_target/src/callconv/hexagon.rs index e07aa32251aa2..1e0f1f769c3b0 100644 --- a/compiler/rustc_target/src/callconv/hexagon.rs +++ b/compiler/rustc_target/src/callconv/hexagon.rs @@ -10,24 +10,25 @@ where if !ret.layout.is_sized() { return; } + if !ret.layout.is_aggregate() { ret.extend_integer_width_to(32); return; } + // Per the Hexagon ABI: + // - Aggregates up to 32 bits are returned in R0 + // - Aggregates 33-64 bits are returned in R1:R0 + // - Aggregates > 64 bits are returned indirectly via hidden first argument let size = ret.layout.size; let bits = size.bits(); - - // Aggregates larger than 64 bits are returned indirectly - if bits > 64 { + if bits <= 32 { + ret.cast_to(Uniform::new(Reg::i32(), size)); + } else if bits <= 64 { + ret.cast_to(Uniform::new(Reg::i64(), size)); + } else { ret.make_indirect(); - return; } - - // Small aggregates are returned in registers - // Cast to appropriate register type to ensure proper ABI - let align = ret.layout.align.bytes(); - ret.cast_to(Uniform::consecutive(if align <= 4 { Reg::i32() } else { Reg::i64() }, size)); } fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) @@ -42,24 +43,25 @@ where arg.make_indirect(); return; } + if !arg.layout.is_aggregate() { arg.extend_integer_width_to(32); return; } + // Per the Hexagon ABI: + // - Aggregates up to 32 bits are passed in a single register + // - Aggregates 33-64 bits are passed in a register pair + // - Aggregates > 64 bits are passed on the stack let size = arg.layout.size; let bits = size.bits(); - - // Aggregates larger than 64 bits are passed indirectly - if bits > 64 { - arg.make_indirect(); - return; + if bits <= 32 { + arg.cast_to(Uniform::new(Reg::i32(), size)); + } else if bits <= 64 { + arg.cast_to(Uniform::new(Reg::i64(), size)); + } else { + arg.pass_by_stack_offset(None); } - - // Small aggregates are passed in registers - // Cast to consecutive register-sized chunks to match the C ABI - let align = arg.layout.align.bytes(); - arg.cast_to(Uniform::consecutive(if align <= 4 { Reg::i32() } else { Reg::i64() }, size)); } pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) From 4d47b07353e2d5014f08dc5ff9b913c1df1e2c58 Mon Sep 17 00:00:00 2001 From: arferreira Date: Wed, 11 Mar 2026 22:39:51 -0400 Subject: [PATCH 4/7] Detect existing turbofish on method calls to suppress useless suggestion --- .../error_reporting/infer/need_type_info.rs | 5 +++- .../inference/useless-turbofish-suggestion.rs | 28 +++++++++++++++++++ .../useless-turbofish-suggestion.stderr | 20 +++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 tests/ui/inference/useless-turbofish-suggestion.rs create mode 100644 tests/ui/inference/useless-turbofish-suggestion.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index 80e97d36c23f0..629bd30d88e8e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -1030,12 +1030,15 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { let args = self.node_args_opt(expr.hir_id)?; let span = tcx.hir_span(segment.hir_id); let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi()); + let have_turbofish = segment.args.is_some_and(|args| { + args.args.iter().any(|arg| arg.is_ty_or_const()) + }); InsertableGenericArgs { insert_span, args, generics_def_id: def_id, def_id, - have_turbofish: false, + have_turbofish, } }; return Box::new(insertable.into_iter()); diff --git a/tests/ui/inference/useless-turbofish-suggestion.rs b/tests/ui/inference/useless-turbofish-suggestion.rs new file mode 100644 index 0000000000000..ed86df6296cad --- /dev/null +++ b/tests/ui/inference/useless-turbofish-suggestion.rs @@ -0,0 +1,28 @@ +// Regression test for #153732. +// +// When a method call already has turbofish type arguments, don't suggest +// rewriting them — the suggestion just rewrites user syntax into +// fully-qualified form without resolving anything. +// +// The span still points at the method name rather than the unresolved `_`; +// fixing that is left as future work. + +struct S; + +impl S { + fn f(self, _a: A) -> B { + todo!() + } +} + +fn with_turbofish() { + S.f::(42); + //~^ ERROR type annotations needed +} + +fn without_turbofish() { + S.f(42); + //~^ ERROR type annotations needed +} + +fn main() {} diff --git a/tests/ui/inference/useless-turbofish-suggestion.stderr b/tests/ui/inference/useless-turbofish-suggestion.stderr new file mode 100644 index 0000000000000..25b05801aa470 --- /dev/null +++ b/tests/ui/inference/useless-turbofish-suggestion.stderr @@ -0,0 +1,20 @@ +error[E0282]: type annotations needed + --> $DIR/useless-turbofish-suggestion.rs:19:7 + | +LL | S.f::(42); + | ^ cannot infer type of the type parameter `B` declared on the method `f` + +error[E0282]: type annotations needed + --> $DIR/useless-turbofish-suggestion.rs:24:7 + | +LL | S.f(42); + | ^ cannot infer type of the type parameter `B` declared on the method `f` + | +help: consider specifying the generic arguments + | +LL | S.f::(42); + | ++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0282`. From 675290a40d580f5063bad9ec24ed3a94da96339b Mon Sep 17 00:00:00 2001 From: Urhengulas Date: Wed, 11 Mar 2026 17:29:12 +0100 Subject: [PATCH 5/7] Fix that `./x test --no-doc` actually keeps the same behaviour for backwards compatability --- src/bootstrap/src/core/config/flags.rs | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index a2e5def39d07c..1665448e6d3c8 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -570,16 +570,21 @@ impl Subcommand { pub fn test_target(&self) -> TestTarget { match *self { - Subcommand::Test { all_targets, doc, tests, .. } - | Subcommand::Miri { all_targets, doc, tests, .. } => match (all_targets, doc, tests) { - (true, true, _) | (true, _, true) | (_, true, true) => { - panic!("You can only set one of `--all-targets`, `--doc` and `--tests`.") + Subcommand::Test { mut all_targets, doc, tests, no_doc, .. } + | Subcommand::Miri { mut all_targets, doc, tests, no_doc, .. } => { + // for backwards compatibility --no-doc keeps working + all_targets = all_targets || no_doc; + + match (all_targets, doc, tests) { + (true, true, _) | (true, _, true) | (_, true, true) => { + panic!("You can only set one of `--all-targets`, `--doc` and `--tests`.") + } + (true, false, false) => TestTarget::AllTargets, + (false, true, false) => TestTarget::DocOnly, + (false, false, true) => TestTarget::Tests, + (false, false, false) => TestTarget::Default, } - (true, false, false) => TestTarget::AllTargets, - (false, true, false) => TestTarget::DocOnly, - (false, false, true) => TestTarget::Tests, - (false, false, false) => TestTarget::Default, - }, + } _ => TestTarget::Default, } } From 6e954d376a84ac6da5006abba7800d5663c51639 Mon Sep 17 00:00:00 2001 From: arferreira Date: Thu, 12 Mar 2026 06:28:54 -0400 Subject: [PATCH 6/7] Bless issue-23041 test after turbofish suggestion suppression --- tests/ui/issues/issue-23041.stderr | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/ui/issues/issue-23041.stderr b/tests/ui/issues/issue-23041.stderr index bd0e457fa9da5..4d7266c7c98d7 100644 --- a/tests/ui/issues/issue-23041.stderr +++ b/tests/ui/issues/issue-23041.stderr @@ -3,12 +3,6 @@ error[E0282]: type annotations needed | LL | b.downcast_ref::_>(); | ^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the method `downcast_ref` - | -help: consider specifying the generic argument - | -LL - b.downcast_ref::_>(); -LL + b.downcast_ref:: _>(); - | error: aborting due to 1 previous error From bee28ef7b23f48b759ce6c358a50cba5d24698d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 12 Mar 2026 14:24:32 +0100 Subject: [PATCH 7/7] Remove `MTLock` --- compiler/rustc_data_structures/src/sync.rs | 37 ------------------- compiler/rustc_monomorphize/src/collector.rs | 22 +++++------ src/doc/rustc-dev-guide/src/parallel-rustc.md | 1 - 3 files changed, 11 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 31768fe189aef..327c28fd13890 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -21,11 +21,6 @@ //! | `Lock` | `RefCell` | `RefCell` or | //! | | | `parking_lot::Mutex` | //! | `RwLock` | `RefCell` | `parking_lot::RwLock` | -//! | `MTLock` [^1] | `T` | `Lock` | -//! -//! [^1]: `MTLock` is similar to `Lock`, but the serial version avoids the cost -//! of a `RefCell`. This is appropriate when interior mutability is not -//! required. use std::collections::HashMap; use std::hash::{BuildHasher, Hash}; @@ -106,38 +101,6 @@ mod mode { } } -// FIXME(parallel_compiler): Get rid of these aliases across the compiler. - -#[derive(Debug, Default)] -pub struct MTLock(Lock); - -impl MTLock { - #[inline(always)] - pub fn new(inner: T) -> Self { - MTLock(Lock::new(inner)) - } - - #[inline(always)] - pub fn into_inner(self) -> T { - self.0.into_inner() - } - - #[inline(always)] - pub fn get_mut(&mut self) -> &mut T { - self.0.get_mut() - } - - #[inline(always)] - pub fn lock(&self) -> LockGuard<'_, T> { - self.0.lock() - } - - #[inline(always)] - pub fn lock_mut(&self) -> LockGuard<'_, T> { - self.lock() - } -} - /// This makes locks panic if they are already held. /// It is only useful when you are running in a single thread const ERROR_CHECKING: bool = false; diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index f6bb70b214468..8bd6730ab0eba 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -209,7 +209,7 @@ use std::cell::OnceCell; use std::ops::ControlFlow; use rustc_data_structures::fx::FxIndexMap; -use rustc_data_structures::sync::{MTLock, par_for_each_in}; +use rustc_data_structures::sync::{Lock, par_for_each_in}; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_hir as hir; use rustc_hir::attrs::InlineAttr; @@ -251,12 +251,12 @@ pub(crate) enum MonoItemCollectionStrategy { /// The state that is shared across the concurrent threads that are doing collection. struct SharedState<'tcx> { /// Items that have been or are currently being recursively collected. - visited: MTLock>>, + visited: Lock>>, /// Items that have been or are currently being recursively treated as "mentioned", i.e., their /// consts are evaluated but nothing is added to the collection. - mentioned: MTLock>>, + mentioned: Lock>>, /// Which items are being used where, for better errors. - usage_map: MTLock>, + usage_map: Lock>, } pub(crate) struct UsageMap<'tcx> { @@ -359,7 +359,7 @@ fn collect_items_root<'tcx>( state: &SharedState<'tcx>, recursion_limit: Limit, ) { - if !state.visited.lock_mut().insert(starting_item.node) { + if !state.visited.lock().insert(starting_item.node) { // We've been here already, no need to search again. return; } @@ -568,7 +568,7 @@ fn collect_items_rec<'tcx>( // This is part of the output of collection and hence only relevant for "used" items. // ("Mentioned" items are only considered internally during collection.) if mode == CollectionMode::UsedItems { - state.usage_map.lock_mut().record_used(starting_item.node, &used_items); + state.usage_map.lock().record_used(starting_item.node, &used_items); } { @@ -576,13 +576,13 @@ fn collect_items_rec<'tcx>( if mode == CollectionMode::UsedItems { used_items .items - .retain(|k, _| visited.get_mut_or_init(|| state.visited.lock_mut()).insert(*k)); + .retain(|k, _| visited.get_mut_or_init(|| state.visited.lock()).insert(*k)); } let mut mentioned = OnceCell::default(); mentioned_items.items.retain(|k, _| { !visited.get_or_init(|| state.visited.lock()).contains(k) - && mentioned.get_mut_or_init(|| state.mentioned.lock_mut()).insert(*k) + && mentioned.get_mut_or_init(|| state.mentioned.lock()).insert(*k) }); } if mode == CollectionMode::MentionedItems { @@ -1810,9 +1810,9 @@ pub(crate) fn collect_crate_mono_items<'tcx>( debug!("building mono item graph, beginning at roots"); let state = SharedState { - visited: MTLock::new(UnordSet::default()), - mentioned: MTLock::new(UnordSet::default()), - usage_map: MTLock::new(UsageMap::new()), + visited: Lock::new(UnordSet::default()), + mentioned: Lock::new(UnordSet::default()), + usage_map: Lock::new(UsageMap::new()), }; let recursion_limit = tcx.recursion_limit(); diff --git a/src/doc/rustc-dev-guide/src/parallel-rustc.md b/src/doc/rustc-dev-guide/src/parallel-rustc.md index ce69b66c2daf5..f83aaa639ecc2 100644 --- a/src/doc/rustc-dev-guide/src/parallel-rustc.md +++ b/src/doc/rustc-dev-guide/src/parallel-rustc.md @@ -48,7 +48,6 @@ are implemented differently depending on whether `parallel-compiler` is true. | -------------------------------- | --------------------------------------------------- | ------------ | | Lock\ | (parking_lot::Mutex\) | (std::cell::RefCell) | | RwLock\ | (parking_lot::RwLock\) | (std::cell::RefCell) | -| MTLock\ | (Lock\) | (T) | | ReadGuard | parking_lot::RwLockReadGuard | std::cell::Ref | | MappedReadGuard | parking_lot::MappedRwLockReadGuard | std::cell::Ref | | WriteGuard | parking_lot::RwLockWriteGuard | std::cell::RefMut |