Skip to content

Commit fc13ca6

Browse files
committed
Auto merge of rust-lang#118200 - matthiaskrgr:rollup-neka6xo, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - rust-lang#118131 (improve tool-only help for multiple `#[default]` variants) - rust-lang#118146 (Rework supertrait lint once again) - rust-lang#118167 (make the 'abi_unadjusted' feature internal) - rust-lang#118169 (print query map for deadlock when using parallel front end) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 1934665 + 0223a81 commit fc13ca6

18 files changed

+249
-79
lines changed

compiler/rustc_builtin_macros/src/deriving/default.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -127,18 +127,17 @@ fn extract_default_variant<'a>(
127127
[first, rest @ ..] => {
128128
let suggs = default_variants
129129
.iter()
130-
.map(|variant| {
131-
let spans = default_variants
130+
.filter_map(|variant| {
131+
let keep = attr::find_by_name(&variant.attrs, kw::Default)?.span;
132+
let spans: Vec<Span> = default_variants
132133
.iter()
133-
.filter_map(|v| {
134-
if v.span == variant.span {
135-
None
136-
} else {
137-
Some(attr::find_by_name(&v.attrs, kw::Default)?.span)
138-
}
134+
.flat_map(|v| {
135+
attr::filter_by_name(&v.attrs, kw::Default)
136+
.filter_map(|attr| (attr.span != keep).then_some(attr.span))
139137
})
140138
.collect();
141-
errors::MultipleDefaultsSugg { spans, ident: variant.ident }
139+
(!spans.is_empty())
140+
.then_some(errors::MultipleDefaultsSugg { spans, ident: variant.ident })
142141
})
143142
.collect();
144143
cx.emit_err(errors::MultipleDefaults {

compiler/rustc_feature/src/unstable.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ declare_features! (
160160
// no-tracking-issue-start
161161

162162
/// Allows using the `unadjusted` ABI; perma-unstable.
163-
(unstable, abi_unadjusted, "1.16.0", None, None),
163+
(internal, abi_unadjusted, "1.16.0", None, None),
164164
/// Allows using the `vectorcall` ABI.
165165
(unstable, abi_vectorcall, "1.7.0", None, None),
166166
/// Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`.

compiler/rustc_lint/messages.ftl

+2-1
Original file line numberDiff line numberDiff line change
@@ -491,8 +491,9 @@ lint_requested_level = requested on the command line with `{$level} {$lint_name}
491491
lint_span_use_eq_ctxt = use `.eq_ctxt()` instead of `.ctxt() == .ctxt()`
492492
493493
lint_supertrait_as_deref_target = this `Deref` implementation is covered by an implicit supertrait coercion
494+
.label = `{$self_ty}` implements `Deref<Target = dyn {$target_principal}>` which conflicts with supertrait `{$supertrait_principal}`
495+
.label2 = target type is a supertrait of `{$self_ty}`
494496
.help = consider removing this implementation or replacing it with a method instead
495-
.label = target type is a supertrait of `{$t}`
496497
497498
lint_suspicious_double_ref_clone =
498499
using `.clone()` on a double reference, which returns `{$ty}` instead of cloning the inner type

compiler/rustc_lint/src/deref_into_dyn_supertrait.rs

+25-17
Original file line numberDiff line numberDiff line change
@@ -53,35 +53,43 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
5353
let tcx = cx.tcx;
5454
// `Deref` is being implemented for `t`
5555
if let hir::ItemKind::Impl(impl_) = item.kind
56+
// the trait is a `Deref` implementation
5657
&& let Some(trait_) = &impl_.of_trait
57-
&& let t = tcx.type_of(item.owner_id).instantiate_identity()
58-
&& let opt_did @ Some(did) = trait_.trait_def_id()
59-
&& opt_did == tcx.lang_items().deref_trait()
60-
// `t` is `dyn t_principal`
61-
&& let ty::Dynamic(data, _, ty::Dyn) = t.kind()
62-
&& let Some(t_principal) = data.principal()
58+
&& let Some(did) = trait_.trait_def_id()
59+
&& Some(did) == tcx.lang_items().deref_trait()
60+
// the self type is `dyn t_principal`
61+
&& let self_ty = tcx.type_of(item.owner_id).instantiate_identity()
62+
&& let ty::Dynamic(data, _, ty::Dyn) = self_ty.kind()
63+
&& let Some(self_principal) = data.principal()
6364
// `<T as Deref>::Target` is `dyn target_principal`
64-
&& let Some(target) = cx.get_associated_type(t, did, "Target")
65+
&& let Some(target) = cx.get_associated_type(self_ty, did, "Target")
6566
&& let ty::Dynamic(data, _, ty::Dyn) = target.kind()
6667
&& let Some(target_principal) = data.principal()
6768
// `target_principal` is a supertrait of `t_principal`
68-
&& supertraits(tcx, t_principal.with_self_ty(tcx, tcx.types.trait_object_dummy_self))
69-
.any(|sup| {
70-
tcx.erase_regions(
71-
sup.map_bound(|x| ty::ExistentialTraitRef::erase_self_ty(tcx, x)),
72-
) == tcx.erase_regions(target_principal)
73-
})
69+
&& let Some(supertrait_principal) = supertraits(tcx, self_principal.with_self_ty(tcx, self_ty))
70+
.find(|supertrait| supertrait.def_id() == target_principal.def_id())
7471
{
75-
let t = tcx.erase_regions(t);
76-
let label = impl_
72+
// erase regions in self type for better diagnostic presentation
73+
let (self_ty, target_principal, supertrait_principal) =
74+
tcx.erase_regions((self_ty, target_principal, supertrait_principal));
75+
let label2 = impl_
7776
.items
7877
.iter()
7978
.find_map(|i| (i.ident.name == sym::Target).then_some(i.span))
8079
.map(|label| SupertraitAsDerefTargetLabel { label });
80+
let span = tcx.def_span(item.owner_id.def_id);
8181
cx.emit_spanned_lint(
8282
DEREF_INTO_DYN_SUPERTRAIT,
83-
tcx.def_span(item.owner_id.def_id),
84-
SupertraitAsDerefTarget { t, label },
83+
span,
84+
SupertraitAsDerefTarget {
85+
self_ty,
86+
supertrait_principal: supertrait_principal.map_bound(|trait_ref| {
87+
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
88+
}),
89+
target_principal,
90+
label: span,
91+
label2,
92+
},
8593
);
8694
}
8795
}

compiler/rustc_lint/src/lints.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ use rustc_errors::{
1010
};
1111
use rustc_hir::def_id::DefId;
1212
use rustc_macros::{LintDiagnostic, Subdiagnostic};
13-
use rustc_middle::ty::{inhabitedness::InhabitedPredicate, Clause, Ty, TyCtxt};
13+
use rustc_middle::ty::{
14+
inhabitedness::InhabitedPredicate, Clause, PolyExistentialTraitRef, Ty, TyCtxt,
15+
};
1416
use rustc_session::parse::ParseSess;
1517
use rustc_span::{edition::Edition, sym, symbol::Ident, Span, Symbol};
1618

@@ -556,13 +558,17 @@ pub enum BuiltinSpecialModuleNameUsed {
556558
#[diag(lint_supertrait_as_deref_target)]
557559
#[help]
558560
pub struct SupertraitAsDerefTarget<'a> {
559-
pub t: Ty<'a>,
561+
pub self_ty: Ty<'a>,
562+
pub supertrait_principal: PolyExistentialTraitRef<'a>,
563+
pub target_principal: PolyExistentialTraitRef<'a>,
564+
#[label]
565+
pub label: Span,
560566
#[subdiagnostic]
561-
pub label: Option<SupertraitAsDerefTargetLabel>,
567+
pub label2: Option<SupertraitAsDerefTargetLabel>,
562568
}
563569

564570
#[derive(Subdiagnostic)]
565-
#[label(lint_label)]
571+
#[label(lint_label2)]
566572
pub struct SupertraitAsDerefTargetLabel {
567573
#[primary_span]
568574
pub label: Span,

compiler/rustc_query_system/src/query/job.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ pub struct QueryInfo {
3838
pub type QueryMap = FxHashMap<QueryJobId, QueryJobInfo>;
3939

4040
/// A value uniquely identifying an active query job.
41-
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
41+
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
4242
pub struct QueryJobId(pub NonZeroU64);
4343

4444
impl QueryJobId {
@@ -62,14 +62,14 @@ impl QueryJobId {
6262
}
6363
}
6464

65-
#[derive(Clone)]
65+
#[derive(Clone, Debug)]
6666
pub struct QueryJobInfo {
6767
pub query: QueryStackFrame,
6868
pub job: QueryJob,
6969
}
7070

7171
/// Represents an active query job.
72-
#[derive(Clone)]
72+
#[derive(Clone, Debug)]
7373
pub struct QueryJob {
7474
pub id: QueryJobId,
7575

@@ -182,6 +182,7 @@ impl QueryJobId {
182182
}
183183

184184
#[cfg(parallel_compiler)]
185+
#[derive(Debug)]
185186
struct QueryWaiter {
186187
query: Option<QueryJobId>,
187188
condvar: Condvar,
@@ -198,13 +199,14 @@ impl QueryWaiter {
198199
}
199200

200201
#[cfg(parallel_compiler)]
202+
#[derive(Debug)]
201203
struct QueryLatchInfo {
202204
complete: bool,
203205
waiters: Vec<Arc<QueryWaiter>>,
204206
}
205207

206208
#[cfg(parallel_compiler)]
207-
#[derive(Clone)]
209+
#[derive(Clone, Debug)]
208210
pub(super) struct QueryLatch {
209211
info: Arc<Mutex<QueryLatchInfo>>,
210212
}
@@ -540,7 +542,11 @@ pub fn deadlock(query_map: QueryMap, registry: &rayon_core::Registry) {
540542
// X to Y due to Rayon waiting and a true dependency from Y to X. The algorithm here
541543
// only considers the true dependency and won't detect a cycle.
542544
if !found_cycle {
543-
panic!("deadlock detected");
545+
if query_map.len() == 0 {
546+
panic!("deadlock detected without any query!")
547+
} else {
548+
panic!("deadlock detected! current query map:\n{:#?}", query_map);
549+
}
544550
}
545551

546552
// FIXME: Ensure this won't cause a deadlock before we return

compiler/rustc_query_system/src/query/plumbing.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ where
203203
}
204204
}
205205

206-
#[derive(Clone)]
206+
#[derive(Clone, Debug)]
207207
pub(crate) struct CycleError {
208208
/// The query and related span that uses the cycle.
209209
pub usage: Option<(Span, QueryStackFrame)>,

tests/ui/deriving/issue-105101.rs

-9
This file was deleted.

tests/ui/deriving/issue-105101.stderr

-29
This file was deleted.
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// compile-flags: --crate-type=lib
2+
3+
// When we get multiple `#[default]` variants, we emit several tool-only suggestions
4+
// to remove all except one of the `#[default]`s.
5+
6+
#[derive(Default)] //~ ERROR multiple declared defaults
7+
enum A {
8+
#[default] //~ HELP make `B` default
9+
#[default] //~ HELP make `A` default
10+
A,
11+
#[default] // also "HELP make `A` default", but compiletest can't handle multispans
12+
B,
13+
}
14+
15+
// Originally, we took each defaulted variant and emitted the suggestion for every variant
16+
// with a different identifier, causing an ICE when multiple variants have the same identifier:
17+
// https://github.com/rust-lang/rust/pull/105106
18+
#[derive(Default)] //~ ERROR multiple declared defaults
19+
enum E {
20+
#[default] //~ HELP make `A` default
21+
A,
22+
#[default] //~ HELP make `A` default
23+
A, //~ ERROR defined multiple times
24+
}
25+
26+
// Then, we took each defaulted variant and emitted the suggestion for every variant
27+
// with a different span, causing an ICE when multiple variants have the same span:
28+
// https://github.com/rust-lang/rust/issues/118119
29+
macro_rules! m {
30+
{ $($id:ident)* } => {
31+
#[derive(Default)] //~ ERROR multiple declared defaults
32+
enum F {
33+
$(
34+
#[default]
35+
$id,
36+
)*
37+
}
38+
}
39+
}
40+
41+
m! { A B }
+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
error: multiple declared defaults
2+
--> $DIR/multiple-defaults.rs:6:10
3+
|
4+
LL | #[derive(Default)]
5+
| ^^^^^^^
6+
...
7+
LL | A,
8+
| - first default
9+
LL | #[default] // also "HELP make `A` default", but compiletest can't handle multispans
10+
LL | B,
11+
| - additional default
12+
|
13+
= note: only one variant can be default
14+
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
15+
16+
error: multiple declared defaults
17+
--> $DIR/multiple-defaults.rs:18:10
18+
|
19+
LL | #[derive(Default)]
20+
| ^^^^^^^
21+
...
22+
LL | A,
23+
| - first default
24+
LL | #[default]
25+
LL | A,
26+
| - additional default
27+
|
28+
= note: only one variant can be default
29+
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
30+
31+
error[E0428]: the name `A` is defined multiple times
32+
--> $DIR/multiple-defaults.rs:23:5
33+
|
34+
LL | A,
35+
| - previous definition of the type `A` here
36+
LL | #[default]
37+
LL | A,
38+
| ^ `A` redefined here
39+
|
40+
= note: `A` must be defined only once in the type namespace of this enum
41+
42+
error: multiple declared defaults
43+
--> $DIR/multiple-defaults.rs:31:18
44+
|
45+
LL | #[derive(Default)]
46+
| ^^^^^^^
47+
...
48+
LL | $id,
49+
| ---
50+
| |
51+
| first default
52+
| additional default
53+
...
54+
LL | m! { A B }
55+
| ---------- in this macro invocation
56+
|
57+
= note: only one variant can be default
58+
= 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)
59+
60+
error: aborting due to 4 previous errors
61+
62+
For more information about this error, try `rustc --explain E0428`.

tests/ui/traits/trait-upcasting/deref-lint-regions.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ warning: this `Deref` implementation is covered by an implicit supertrait coerci
22
--> $DIR/deref-lint-regions.rs:8:1
33
|
44
LL | impl<'a> Deref for dyn Foo<'a> {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo<'_>` implements `Deref<Target = dyn Bar<'_>>` which conflicts with supertrait `Bar<'_>`
66
LL |
77
LL | type Target = dyn Bar<'a>;
88
| -------------------------- target type is a supertrait of `dyn Foo<'_>`

tests/ui/traits/trait-upcasting/deref-lint.rs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ trait B: A {}
88

99
impl<'a> Deref for dyn 'a + B {
1010
//~^ WARN this `Deref` implementation is covered by an implicit supertrait coercion
11+
1112
type Target = dyn A;
1213
fn deref(&self) -> &Self::Target {
1314
todo!()

tests/ui/traits/trait-upcasting/deref-lint.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ warning: this `Deref` implementation is covered by an implicit supertrait coerci
22
--> $DIR/deref-lint.rs:9:1
33
|
44
LL | impl<'a> Deref for dyn 'a + B {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6-
LL |
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn B` implements `Deref<Target = dyn A>` which conflicts with supertrait `A`
6+
...
77
LL | type Target = dyn A;
88
| -------------------- target type is a supertrait of `dyn B`
99
|

0 commit comments

Comments
 (0)