From f697a00f760c17547ef4282fd6af5b9f3c433dcf Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Tue, 21 Nov 2023 11:43:29 +0000 Subject: [PATCH 1/5] improve help for multiple `#[default]` variants --- .../src/deriving/default.rs | 17 +++-- tests/ui/deriving/issue-105101.rs | 9 --- tests/ui/deriving/issue-105101.stderr | 29 --------- tests/ui/deriving/multiple-defaults.rs | 41 ++++++++++++ tests/ui/deriving/multiple-defaults.stderr | 62 +++++++++++++++++++ 5 files changed, 111 insertions(+), 47 deletions(-) delete mode 100644 tests/ui/deriving/issue-105101.rs delete mode 100644 tests/ui/deriving/issue-105101.stderr create mode 100644 tests/ui/deriving/multiple-defaults.rs create mode 100644 tests/ui/deriving/multiple-defaults.stderr diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 07b172bc757..43874a242f2 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -127,18 +127,17 @@ fn extract_default_variant<'a>( [first, rest @ ..] => { let suggs = default_variants .iter() - .map(|variant| { - let spans = default_variants + .filter_map(|variant| { + let keep = attr::find_by_name(&variant.attrs, kw::Default)?.span; + let spans: Vec = default_variants .iter() - .filter_map(|v| { - if v.span == variant.span { - None - } else { - Some(attr::find_by_name(&v.attrs, kw::Default)?.span) - } + .flat_map(|v| { + attr::filter_by_name(&v.attrs, kw::Default) + .filter_map(|attr| (attr.span != keep).then_some(attr.span)) }) .collect(); - errors::MultipleDefaultsSugg { spans, ident: variant.ident } + (!spans.is_empty()) + .then_some(errors::MultipleDefaultsSugg { spans, ident: variant.ident }) }) .collect(); cx.emit_err(errors::MultipleDefaults { diff --git a/tests/ui/deriving/issue-105101.rs b/tests/ui/deriving/issue-105101.rs deleted file mode 100644 index 1a377feb919..00000000000 --- a/tests/ui/deriving/issue-105101.rs +++ /dev/null @@ -1,9 +0,0 @@ -// compile-flags: --crate-type=lib - -#[derive(Default)] //~ ERROR multiple declared defaults -enum E { - #[default] - A, - #[default] - A, //~ ERROR defined multiple times -} diff --git a/tests/ui/deriving/issue-105101.stderr b/tests/ui/deriving/issue-105101.stderr deleted file mode 100644 index 0f6f67043f3..00000000000 --- a/tests/ui/deriving/issue-105101.stderr +++ /dev/null @@ -1,29 +0,0 @@ -error: multiple declared defaults - --> $DIR/issue-105101.rs:3:10 - | -LL | #[derive(Default)] - | ^^^^^^^ -... -LL | A, - | - first default -LL | #[default] -LL | A, - | - additional default - | - = note: only one variant can be default - = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0428]: the name `A` is defined multiple times - --> $DIR/issue-105101.rs:8:5 - | -LL | A, - | - previous definition of the type `A` here -LL | #[default] -LL | A, - | ^ `A` redefined here - | - = note: `A` must be defined only once in the type namespace of this enum - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0428`. diff --git a/tests/ui/deriving/multiple-defaults.rs b/tests/ui/deriving/multiple-defaults.rs new file mode 100644 index 00000000000..2024a55200b --- /dev/null +++ b/tests/ui/deriving/multiple-defaults.rs @@ -0,0 +1,41 @@ +// compile-flags: --crate-type=lib + +// When we get multiple `#[default]` variants, we emit several tool-only suggestions +// to remove all except one of the `#[default]`s. + +#[derive(Default)] //~ ERROR multiple declared defaults +enum A { + #[default] //~ HELP make `B` default + #[default] //~ HELP make `A` default + A, + #[default] // also "HELP make `A` default", but compiletest can't handle multispans + B, +} + +// Originally, we took each defaulted variant and emitted the suggestion for every variant +// with a different identifier, causing an ICE when multiple variants have the same identifier: +// https://github.com/rust-lang/rust/pull/105106 +#[derive(Default)] //~ ERROR multiple declared defaults +enum E { + #[default] //~ HELP make `A` default + A, + #[default] //~ HELP make `A` default + A, //~ ERROR defined multiple times +} + +// Then, we took each defaulted variant and emitted the suggestion for every variant +// with a different span, causing an ICE when multiple variants have the same span: +// https://github.com/rust-lang/rust/issues/118119 +macro_rules! m { + { $($id:ident)* } => { + #[derive(Default)] //~ ERROR multiple declared defaults + enum F { + $( + #[default] + $id, + )* + } + } +} + +m! { A B } diff --git a/tests/ui/deriving/multiple-defaults.stderr b/tests/ui/deriving/multiple-defaults.stderr new file mode 100644 index 00000000000..05fb6fecffa --- /dev/null +++ b/tests/ui/deriving/multiple-defaults.stderr @@ -0,0 +1,62 @@ +error: multiple declared defaults + --> $DIR/multiple-defaults.rs:6:10 + | +LL | #[derive(Default)] + | ^^^^^^^ +... +LL | A, + | - first default +LL | #[default] // also "HELP make `A` default", but compiletest can't handle multispans +LL | B, + | - additional default + | + = note: only one variant can be default + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: multiple declared defaults + --> $DIR/multiple-defaults.rs:18:10 + | +LL | #[derive(Default)] + | ^^^^^^^ +... +LL | A, + | - first default +LL | #[default] +LL | A, + | - additional default + | + = note: only one variant can be default + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0428]: the name `A` is defined multiple times + --> $DIR/multiple-defaults.rs:23:5 + | +LL | A, + | - previous definition of the type `A` here +LL | #[default] +LL | A, + | ^ `A` redefined here + | + = note: `A` must be defined only once in the type namespace of this enum + +error: multiple declared defaults + --> $DIR/multiple-defaults.rs:31:18 + | +LL | #[derive(Default)] + | ^^^^^^^ +... +LL | $id, + | --- + | | + | first default + | additional default +... +LL | m! { A B } + | ---------- in this macro invocation + | + = note: only one variant can be default + = note: this error originates in the derive macro `Default` which comes from the expansion of the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0428`. From 32fc54e5fa97cf4ed69ea97dcf631d747a33faae Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 22 Nov 2023 07:25:27 +0100 Subject: [PATCH 2/5] make the 'abi_unadjusted' feature internal --- compiler/rustc_feature/src/unstable.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index b11b190bded..86e1825d7b5 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -160,7 +160,7 @@ declare_features! ( // no-tracking-issue-start /// Allows using the `unadjusted` ABI; perma-unstable. - (unstable, abi_unadjusted, "1.16.0", None, None), + (internal, abi_unadjusted, "1.16.0", None, None), /// Allows using the `vectorcall` ABI. (unstable, abi_vectorcall, "1.7.0", None, None), /// Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`. From d5e4bd89222c149cec295757fe203b58aa522edf Mon Sep 17 00:00:00 2001 From: SparrowLii Date: Wed, 22 Nov 2023 15:28:09 +0800 Subject: [PATCH 3/5] print query map for deadlock when using parallel front end --- compiler/rustc_query_system/src/query/job.rs | 16 +++++++++++----- .../rustc_query_system/src/query/plumbing.rs | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index f2c1f84fccc..726bda76b01 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -38,7 +38,7 @@ pub struct QueryInfo { pub type QueryMap = FxHashMap; /// A value uniquely identifying an active query job. -#[derive(Copy, Clone, Eq, PartialEq, Hash)] +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct QueryJobId(pub NonZeroU64); impl QueryJobId { @@ -62,14 +62,14 @@ impl QueryJobId { } } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct QueryJobInfo { pub query: QueryStackFrame, pub job: QueryJob, } /// Represents an active query job. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct QueryJob { pub id: QueryJobId, @@ -182,6 +182,7 @@ impl QueryJobId { } #[cfg(parallel_compiler)] +#[derive(Debug)] struct QueryWaiter { query: Option, condvar: Condvar, @@ -198,13 +199,14 @@ impl QueryWaiter { } #[cfg(parallel_compiler)] +#[derive(Debug)] struct QueryLatchInfo { complete: bool, waiters: Vec>, } #[cfg(parallel_compiler)] -#[derive(Clone)] +#[derive(Clone, Debug)] pub(super) struct QueryLatch { info: Arc>, } @@ -540,7 +542,11 @@ pub fn deadlock(query_map: QueryMap, registry: &rayon_core::Registry) { // X to Y due to Rayon waiting and a true dependency from Y to X. The algorithm here // only considers the true dependency and won't detect a cycle. if !found_cycle { - panic!("deadlock detected"); + if query_map.len() == 0 { + panic!("deadlock detected without any query!") + } else { + panic!("deadlock detected! current query map:\n{:?}", query_map); + } } // FIXME: Ensure this won't cause a deadlock before we return diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 6c08df99e9d..ecbc7dc6b8f 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -203,7 +203,7 @@ where } } -#[derive(Clone)] +#[derive(Clone, Debug)] pub(crate) struct CycleError { /// The query and related span that uses the cycle. pub usage: Option<(Span, QueryStackFrame)>, From 15fbcc363680ce100a563aac304c389d0f57dfd4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 18 Nov 2023 19:29:39 +0000 Subject: [PATCH 4/5] Rework supertrait lint once again --- compiler/rustc_lint/messages.ftl | 3 +- .../src/deref_into_dyn_supertrait.rs | 42 +++++++++++-------- compiler/rustc_lint/src/lints.rs | 14 +++++-- .../trait-upcasting/deref-lint-regions.stderr | 2 +- tests/ui/traits/trait-upcasting/deref-lint.rs | 1 + .../traits/trait-upcasting/deref-lint.stderr | 4 +- .../deref-upcast-behavioral-change.rs | 34 +++++++++++++++ .../deref-upcast-behavioral-change.stderr | 16 +++++++ .../migrate-lint-different-substs.rs | 20 +++++++++ .../migrate-lint-different-substs.stderr | 14 +++++++ 10 files changed, 125 insertions(+), 25 deletions(-) create mode 100644 tests/ui/traits/trait-upcasting/deref-upcast-behavioral-change.rs create mode 100644 tests/ui/traits/trait-upcasting/deref-upcast-behavioral-change.stderr create mode 100644 tests/ui/traits/trait-upcasting/migrate-lint-different-substs.rs create mode 100644 tests/ui/traits/trait-upcasting/migrate-lint-different-substs.stderr diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 80b21bd8ece..2db610d640c 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -491,8 +491,9 @@ lint_requested_level = requested on the command line with `{$level} {$lint_name} lint_span_use_eq_ctxt = use `.eq_ctxt()` instead of `.ctxt() == .ctxt()` lint_supertrait_as_deref_target = this `Deref` implementation is covered by an implicit supertrait coercion + .label = `{$self_ty}` implements `Deref` which conflicts with supertrait `{$supertrait_principal}` + .label2 = target type is a supertrait of `{$self_ty}` .help = consider removing this implementation or replacing it with a method instead - .label = target type is a supertrait of `{$t}` lint_suspicious_double_ref_clone = using `.clone()` on a double reference, which returns `{$ty}` instead of cloning the inner type diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs index 93c7c37c655..98bafc0f263 100644 --- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs +++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs @@ -53,35 +53,43 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait { let tcx = cx.tcx; // `Deref` is being implemented for `t` if let hir::ItemKind::Impl(impl_) = item.kind + // the trait is a `Deref` implementation && let Some(trait_) = &impl_.of_trait - && let t = tcx.type_of(item.owner_id).instantiate_identity() - && let opt_did @ Some(did) = trait_.trait_def_id() - && opt_did == tcx.lang_items().deref_trait() - // `t` is `dyn t_principal` - && let ty::Dynamic(data, _, ty::Dyn) = t.kind() - && let Some(t_principal) = data.principal() + && let Some(did) = trait_.trait_def_id() + && Some(did) == tcx.lang_items().deref_trait() + // the self type is `dyn t_principal` + && let self_ty = tcx.type_of(item.owner_id).instantiate_identity() + && let ty::Dynamic(data, _, ty::Dyn) = self_ty.kind() + && let Some(self_principal) = data.principal() // `::Target` is `dyn target_principal` - && let Some(target) = cx.get_associated_type(t, did, "Target") + && let Some(target) = cx.get_associated_type(self_ty, did, "Target") && let ty::Dynamic(data, _, ty::Dyn) = target.kind() && let Some(target_principal) = data.principal() // `target_principal` is a supertrait of `t_principal` - && supertraits(tcx, t_principal.with_self_ty(tcx, tcx.types.trait_object_dummy_self)) - .any(|sup| { - tcx.erase_regions( - sup.map_bound(|x| ty::ExistentialTraitRef::erase_self_ty(tcx, x)), - ) == tcx.erase_regions(target_principal) - }) + && let Some(supertrait_principal) = supertraits(tcx, self_principal.with_self_ty(tcx, self_ty)) + .find(|supertrait| supertrait.def_id() == target_principal.def_id()) { - let t = tcx.erase_regions(t); - let label = impl_ + // erase regions in self type for better diagnostic presentation + let (self_ty, target_principal, supertrait_principal) = + tcx.erase_regions((self_ty, target_principal, supertrait_principal)); + let label2 = impl_ .items .iter() .find_map(|i| (i.ident.name == sym::Target).then_some(i.span)) .map(|label| SupertraitAsDerefTargetLabel { label }); + let span = tcx.def_span(item.owner_id.def_id); cx.emit_spanned_lint( DEREF_INTO_DYN_SUPERTRAIT, - tcx.def_span(item.owner_id.def_id), - SupertraitAsDerefTarget { t, label }, + span, + SupertraitAsDerefTarget { + self_ty, + supertrait_principal: supertrait_principal.map_bound(|trait_ref| { + ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref) + }), + target_principal, + label: span, + label2, + }, ); } } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 7fe488e1243..9fda53c2533 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -10,7 +10,9 @@ use rustc_errors::{ }; use rustc_hir::def_id::DefId; use rustc_macros::{LintDiagnostic, Subdiagnostic}; -use rustc_middle::ty::{inhabitedness::InhabitedPredicate, Clause, Ty, TyCtxt}; +use rustc_middle::ty::{ + inhabitedness::InhabitedPredicate, Clause, PolyExistentialTraitRef, Ty, TyCtxt, +}; use rustc_session::parse::ParseSess; use rustc_span::{edition::Edition, sym, symbol::Ident, Span, Symbol}; @@ -556,13 +558,17 @@ pub enum BuiltinSpecialModuleNameUsed { #[diag(lint_supertrait_as_deref_target)] #[help] pub struct SupertraitAsDerefTarget<'a> { - pub t: Ty<'a>, + pub self_ty: Ty<'a>, + pub supertrait_principal: PolyExistentialTraitRef<'a>, + pub target_principal: PolyExistentialTraitRef<'a>, + #[label] + pub label: Span, #[subdiagnostic] - pub label: Option, + pub label2: Option, } #[derive(Subdiagnostic)] -#[label(lint_label)] +#[label(lint_label2)] pub struct SupertraitAsDerefTargetLabel { #[primary_span] pub label: Span, diff --git a/tests/ui/traits/trait-upcasting/deref-lint-regions.stderr b/tests/ui/traits/trait-upcasting/deref-lint-regions.stderr index dd4aa8e9a07..557a4420a3d 100644 --- a/tests/ui/traits/trait-upcasting/deref-lint-regions.stderr +++ b/tests/ui/traits/trait-upcasting/deref-lint-regions.stderr @@ -2,7 +2,7 @@ warning: this `Deref` implementation is covered by an implicit supertrait coerci --> $DIR/deref-lint-regions.rs:8:1 | LL | impl<'a> Deref for dyn Foo<'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo<'_>` implements `Deref>` which conflicts with supertrait `Bar<'_>` LL | LL | type Target = dyn Bar<'a>; | -------------------------- target type is a supertrait of `dyn Foo<'_>` diff --git a/tests/ui/traits/trait-upcasting/deref-lint.rs b/tests/ui/traits/trait-upcasting/deref-lint.rs index dfca7b0fa68..68838d2ae20 100644 --- a/tests/ui/traits/trait-upcasting/deref-lint.rs +++ b/tests/ui/traits/trait-upcasting/deref-lint.rs @@ -8,6 +8,7 @@ trait B: A {} impl<'a> Deref for dyn 'a + B { //~^ WARN this `Deref` implementation is covered by an implicit supertrait coercion + type Target = dyn A; fn deref(&self) -> &Self::Target { todo!() diff --git a/tests/ui/traits/trait-upcasting/deref-lint.stderr b/tests/ui/traits/trait-upcasting/deref-lint.stderr index 0f7a61dfa80..5a13659edf5 100644 --- a/tests/ui/traits/trait-upcasting/deref-lint.stderr +++ b/tests/ui/traits/trait-upcasting/deref-lint.stderr @@ -2,8 +2,8 @@ warning: this `Deref` implementation is covered by an implicit supertrait coerci --> $DIR/deref-lint.rs:9:1 | LL | impl<'a> Deref for dyn 'a + B { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn B` implements `Deref` which conflicts with supertrait `A` +... LL | type Target = dyn A; | -------------------- target type is a supertrait of `dyn B` | diff --git a/tests/ui/traits/trait-upcasting/deref-upcast-behavioral-change.rs b/tests/ui/traits/trait-upcasting/deref-upcast-behavioral-change.rs new file mode 100644 index 00000000000..366eae1a58a --- /dev/null +++ b/tests/ui/traits/trait-upcasting/deref-upcast-behavioral-change.rs @@ -0,0 +1,34 @@ +#![deny(deref_into_dyn_supertrait)] +use std::ops::Deref; + +trait Bar {} +impl Bar for T {} + +trait Foo: Bar { + fn as_dyn_bar_u32<'a>(&self) -> &(dyn Bar + 'a); +} + +impl Foo for () { + fn as_dyn_bar_u32<'a>(&self) -> &(dyn Bar + 'a) { + self + } +} + +impl<'a> Deref for dyn Foo + 'a { + type Target = dyn Bar + 'a; + + fn deref(&self) -> &Self::Target { + self.as_dyn_bar_u32() + } +} + +fn take_dyn(x: &dyn Bar) -> T { + todo!() +} + +fn main() { + let x: &dyn Foo = &(); + let y = take_dyn(x); + let z: u32 = y; + //~^ ERROR mismatched types +} diff --git a/tests/ui/traits/trait-upcasting/deref-upcast-behavioral-change.stderr b/tests/ui/traits/trait-upcasting/deref-upcast-behavioral-change.stderr new file mode 100644 index 00000000000..e8bab322a38 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/deref-upcast-behavioral-change.stderr @@ -0,0 +1,16 @@ +error[E0308]: mismatched types + --> $DIR/deref-upcast-behavioral-change.rs:32:18 + | +LL | let z: u32 = y; + | --- ^ expected `u32`, found `i32` + | | + | expected due to this + | +help: you can convert an `i32` to a `u32` and panic if the converted value doesn't fit + | +LL | let z: u32 = y.try_into().unwrap(); + | ++++++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.rs b/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.rs new file mode 100644 index 00000000000..2c9126c863d --- /dev/null +++ b/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.rs @@ -0,0 +1,20 @@ +// check-pass + +use std::ops::Deref; + +trait Bar {} + +trait Foo: Bar { + fn as_dyn_bar_u32<'a>(&self) -> &(dyn Bar + 'a); +} + +impl<'a> Deref for dyn Foo + 'a { + //~^ WARN this `Deref` implementation is covered by an implicit supertrait coercion + type Target = dyn Bar + 'a; + + fn deref(&self) -> &Self::Target { + self.as_dyn_bar_u32() + } +} + +fn main() {} diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.stderr b/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.stderr new file mode 100644 index 00000000000..a447f9cf83b --- /dev/null +++ b/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.stderr @@ -0,0 +1,14 @@ +warning: this `Deref` implementation is covered by an implicit supertrait coercion + --> $DIR/migrate-lint-different-substs.rs:11:1 + | +LL | impl<'a> Deref for dyn Foo + 'a { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo` implements `Deref>` which conflicts with supertrait `Bar` +LL | +LL | type Target = dyn Bar + 'a; + | -------------------------------- target type is a supertrait of `dyn Foo` + | + = help: consider removing this implementation or replacing it with a method instead + = note: `#[warn(deref_into_dyn_supertrait)]` on by default + +warning: 1 warning emitted + From c238e875734143c829f6294b4e86e14795922c47 Mon Sep 17 00:00:00 2001 From: SparrowLii Date: Thu, 23 Nov 2023 10:35:33 +0800 Subject: [PATCH 5/5] Nit of deadlock detected --- compiler/rustc_query_system/src/query/job.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index 726bda76b01..b38d71733b5 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -545,7 +545,7 @@ pub fn deadlock(query_map: QueryMap, registry: &rayon_core::Registry) { if query_map.len() == 0 { panic!("deadlock detected without any query!") } else { - panic!("deadlock detected! current query map:\n{:?}", query_map); + panic!("deadlock detected! current query map:\n{:#?}", query_map); } }