Skip to content

Commit 5459333

Browse files
authored
Rollup merge of #117241 - compiler-errors:auto-trait-leak-cycle, r=oli-obk
Stash and cancel cycle errors for auto trait leakage in opaques We don't need to emit a traditional cycle error when we have a selection error that explains what's going on but in more detail. We may want to augment this error to actually point out the cycle, now that the cycle error is not being emitted. We could do that by storing the set of opaques that was in the `CyclePlaceholder` that gets returned from `type_of_opaque`. r? `@oli-obk` cc `@estebank` #117235
2 parents 203292e + 1836c1f commit 5459333

File tree

15 files changed

+55
-234
lines changed

15 files changed

+55
-234
lines changed

compiler/rustc_errors/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,8 @@ pub enum StashKey {
508508
TraitMissingMethod,
509509
OpaqueHiddenTypeMismatch,
510510
MaybeForgetReturn,
511+
/// Query cycle detected, stashing in favor of a better error.
512+
Cycle,
511513
}
512514

513515
fn default_track_diagnostic(d: &mut Diagnostic, f: &mut dyn FnMut(&mut Diagnostic)) {

compiler/rustc_macros/src/query.rs

+8
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ struct QueryModifiers {
9797
/// A cycle error results in a delay_bug call
9898
cycle_delay_bug: Option<Ident>,
9999

100+
/// A cycle error results in a stashed cycle error that can be unstashed and canceled later
101+
cycle_stash: Option<Ident>,
102+
100103
/// Don't hash the result, instead just mark a query red if it runs
101104
no_hash: Option<Ident>,
102105

@@ -127,6 +130,7 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
127130
let mut desc = None;
128131
let mut fatal_cycle = None;
129132
let mut cycle_delay_bug = None;
133+
let mut cycle_stash = None;
130134
let mut no_hash = None;
131135
let mut anon = None;
132136
let mut eval_always = None;
@@ -181,6 +185,8 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
181185
try_insert!(fatal_cycle = modifier);
182186
} else if modifier == "cycle_delay_bug" {
183187
try_insert!(cycle_delay_bug = modifier);
188+
} else if modifier == "cycle_stash" {
189+
try_insert!(cycle_stash = modifier);
184190
} else if modifier == "no_hash" {
185191
try_insert!(no_hash = modifier);
186192
} else if modifier == "anon" {
@@ -208,6 +214,7 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
208214
desc,
209215
fatal_cycle,
210216
cycle_delay_bug,
217+
cycle_stash,
211218
no_hash,
212219
anon,
213220
eval_always,
@@ -329,6 +336,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
329336
fatal_cycle,
330337
arena_cache,
331338
cycle_delay_bug,
339+
cycle_stash,
332340
no_hash,
333341
anon,
334342
eval_always,

compiler/rustc_middle/src/query/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ rustc_queries! {
251251
"computing type of opaque `{path}`",
252252
path = tcx.def_path_str(key),
253253
}
254+
cycle_stash
254255
}
255256

256257
query type_alias_is_lazy(key: DefId) -> bool {

compiler/rustc_query_impl/src/plumbing.rs

+3
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ macro_rules! handle_cycle_error {
197197
([(fatal_cycle) $($rest:tt)*]) => {{
198198
rustc_query_system::HandleCycleError::Fatal
199199
}};
200+
([(cycle_stash) $($rest:tt)*]) => {{
201+
rustc_query_system::HandleCycleError::Stash
202+
}};
200203
([(cycle_delay_bug) $($rest:tt)*]) => {{
201204
rustc_query_system::HandleCycleError::DelayBug
202205
}};

compiler/rustc_query_system/src/error.rs

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub enum HandleCycleError {
1515
Error,
1616
Fatal,
1717
DelayBug,
18+
Stash,
1819
}
1920

2021
#[derive(Subdiagnostic)]

compiler/rustc_query_system/src/query/plumbing.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
1919
use rustc_data_structures::sync::Lock;
2020
#[cfg(parallel_compiler)]
2121
use rustc_data_structures::{outline, sync};
22-
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, FatalError};
22+
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, FatalError, StashKey};
2323
use rustc_span::{Span, DUMMY_SP};
2424
use std::cell::Cell;
2525
use std::collections::hash_map::Entry;
@@ -133,6 +133,17 @@ where
133133
let guar = error.delay_as_bug();
134134
query.value_from_cycle_error(*qcx.dep_context(), &cycle_error.cycle, guar)
135135
}
136+
Stash => {
137+
let guar = if let Some(root) = cycle_error.cycle.first()
138+
&& let Some(span) = root.query.span
139+
{
140+
error.stash(span, StashKey::Cycle);
141+
qcx.dep_context().sess().delay_span_bug(span, "delayed cycle error")
142+
} else {
143+
error.emit()
144+
};
145+
query.value_from_cycle_error(*qcx.dep_context(), &cycle_error.cycle, guar)
146+
}
136147
}
137148
}
138149

compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

+7
Original file line numberDiff line numberDiff line change
@@ -3104,6 +3104,13 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
31043104
);
31053105
}
31063106
};
3107+
3108+
if let Some(diag) =
3109+
self.tcx.sess.diagnostic().steal_diagnostic(self.tcx.def_span(def_id), StashKey::Cycle)
3110+
{
3111+
diag.cancel();
3112+
}
3113+
31073114
err
31083115
}
31093116

tests/ui/impl-trait/auto-trait-leak.rs

-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ fn main() {}
99
// independently resolved and only require the concrete
1010
// return type, which can't depend on the obligation.
1111
fn cycle1() -> impl Clone {
12-
//~^ ERROR cycle detected
13-
//~| ERROR cycle detected
1412
send(cycle2().clone());
1513

1614
Rc::new(Cell::new(5))
+3-65
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,5 @@
1-
error[E0391]: cycle detected when computing type of opaque `cycle1::{opaque#0}`
2-
--> $DIR/auto-trait-leak.rs:11:16
3-
|
4-
LL | fn cycle1() -> impl Clone {
5-
| ^^^^^^^^^^
6-
|
7-
note: ...which requires type-checking `cycle1`...
8-
--> $DIR/auto-trait-leak.rs:14:5
9-
|
10-
LL | send(cycle2().clone());
11-
| ^^^^
12-
= note: ...which requires evaluating trait selection obligation `cycle2::{opaque#0}: core::marker::Send`...
13-
note: ...which requires computing type of opaque `cycle2::{opaque#0}`...
14-
--> $DIR/auto-trait-leak.rs:19:16
15-
|
16-
LL | fn cycle2() -> impl Clone {
17-
| ^^^^^^^^^^
18-
note: ...which requires type-checking `cycle2`...
19-
--> $DIR/auto-trait-leak.rs:20:5
20-
|
21-
LL | send(cycle1().clone());
22-
| ^^^^
23-
= note: ...which requires evaluating trait selection obligation `cycle1::{opaque#0}: core::marker::Send`...
24-
= note: ...which again requires computing type of opaque `cycle1::{opaque#0}`, completing the cycle
25-
note: cycle used when computing type of `cycle1::{opaque#0}`
26-
--> $DIR/auto-trait-leak.rs:11:16
27-
|
28-
LL | fn cycle1() -> impl Clone {
29-
| ^^^^^^^^^^
30-
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
31-
32-
error[E0391]: cycle detected when computing type of opaque `cycle1::{opaque#0}`
33-
--> $DIR/auto-trait-leak.rs:11:16
34-
|
35-
LL | fn cycle1() -> impl Clone {
36-
| ^^^^^^^^^^
37-
|
38-
note: ...which requires type-checking `cycle1`...
39-
--> $DIR/auto-trait-leak.rs:14:5
40-
|
41-
LL | send(cycle2().clone());
42-
| ^^^^
43-
= note: ...which requires evaluating trait selection obligation `cycle2::{opaque#0}: core::marker::Send`...
44-
note: ...which requires computing type of opaque `cycle2::{opaque#0}`...
45-
--> $DIR/auto-trait-leak.rs:19:16
46-
|
47-
LL | fn cycle2() -> impl Clone {
48-
| ^^^^^^^^^^
49-
note: ...which requires type-checking `cycle2`...
50-
--> $DIR/auto-trait-leak.rs:19:1
51-
|
52-
LL | fn cycle2() -> impl Clone {
53-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
54-
= note: ...which again requires computing type of opaque `cycle1::{opaque#0}`, completing the cycle
55-
note: cycle used when computing type of `cycle1::{opaque#0}`
56-
--> $DIR/auto-trait-leak.rs:11:16
57-
|
58-
LL | fn cycle1() -> impl Clone {
59-
| ^^^^^^^^^^
60-
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
61-
621
error: cannot check whether the hidden type of opaque type satisfies auto traits
63-
--> $DIR/auto-trait-leak.rs:20:10
2+
--> $DIR/auto-trait-leak.rs:18:10
643
|
654
LL | send(cycle1().clone());
665
| ---- ^^^^^^^^^^^^^^^^
@@ -73,7 +12,7 @@ note: opaque type is declared here
7312
LL | fn cycle1() -> impl Clone {
7413
| ^^^^^^^^^^
7514
note: this item depends on auto traits of the hidden type, but may also be registering the hidden type. This is not supported right now. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
76-
--> $DIR/auto-trait-leak.rs:19:4
15+
--> $DIR/auto-trait-leak.rs:17:4
7716
|
7817
LL | fn cycle2() -> impl Clone {
7918
| ^^^^^^
@@ -83,6 +22,5 @@ note: required by a bound in `send`
8322
LL | fn send<T: Send>(_: T) {}
8423
| ^^^^ required by this bound in `send`
8524

86-
error: aborting due to 3 previous errors
25+
error: aborting due to previous error
8726

88-
For more information about this error, try `rustc --explain E0391`.

tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs

-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55

66
mod m {
77
pub type Foo = impl std::fmt::Debug;
8-
//~^ ERROR: cycle detected when computing type of opaque `m::Foo::{opaque#0}` [E0391]
9-
//~| ERROR: cycle detected when computing type of opaque `m::Foo::{opaque#0}` [E0391]
10-
118
pub fn foo() -> Foo {
129
22_u32
1310
}
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,5 @@
1-
error[E0391]: cycle detected when computing type of opaque `m::Foo::{opaque#0}`
2-
--> $DIR/auto-trait-leakage3.rs:7:20
3-
|
4-
LL | pub type Foo = impl std::fmt::Debug;
5-
| ^^^^^^^^^^^^^^^^^^^^
6-
|
7-
note: ...which requires type-checking `m::bar`...
8-
--> $DIR/auto-trait-leakage3.rs:16:9
9-
|
10-
LL | is_send(foo());
11-
| ^^^^^^^
12-
= note: ...which requires evaluating trait selection obligation `m::Foo: core::marker::Send`...
13-
= note: ...which again requires computing type of opaque `m::Foo::{opaque#0}`, completing the cycle
14-
note: cycle used when computing type of `m::Foo::{opaque#0}`
15-
--> $DIR/auto-trait-leakage3.rs:7:20
16-
|
17-
LL | pub type Foo = impl std::fmt::Debug;
18-
| ^^^^^^^^^^^^^^^^^^^^
19-
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
20-
21-
error[E0391]: cycle detected when computing type of opaque `m::Foo::{opaque#0}`
22-
--> $DIR/auto-trait-leakage3.rs:7:20
23-
|
24-
LL | pub type Foo = impl std::fmt::Debug;
25-
| ^^^^^^^^^^^^^^^^^^^^
26-
|
27-
note: ...which requires type-checking `m::bar`...
28-
--> $DIR/auto-trait-leakage3.rs:15:5
29-
|
30-
LL | pub fn bar() {
31-
| ^^^^^^^^^^^^
32-
= note: ...which again requires computing type of opaque `m::Foo::{opaque#0}`, completing the cycle
33-
note: cycle used when computing type of `m::Foo::{opaque#0}`
34-
--> $DIR/auto-trait-leakage3.rs:7:20
35-
|
36-
LL | pub type Foo = impl std::fmt::Debug;
37-
| ^^^^^^^^^^^^^^^^^^^^
38-
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
39-
401
error: cannot check whether the hidden type of `auto_trait_leakage3[211d]::m::Foo::{opaque#0}` satisfies auto traits
41-
--> $DIR/auto-trait-leakage3.rs:16:17
2+
--> $DIR/auto-trait-leakage3.rs:13:17
423
|
434
LL | is_send(foo());
445
| ------- ^^^^^
@@ -51,16 +12,15 @@ note: opaque type is declared here
5112
LL | pub type Foo = impl std::fmt::Debug;
5213
| ^^^^^^^^^^^^^^^^^^^^
5314
note: this item depends on auto traits of the hidden type, but may also be registering the hidden type. This is not supported right now. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
54-
--> $DIR/auto-trait-leakage3.rs:15:12
15+
--> $DIR/auto-trait-leakage3.rs:12:12
5516
|
5617
LL | pub fn bar() {
5718
| ^^^
5819
note: required by a bound in `is_send`
59-
--> $DIR/auto-trait-leakage3.rs:20:19
20+
--> $DIR/auto-trait-leakage3.rs:17:19
6021
|
6122
LL | fn is_send<T: Send>(_: T) {}
6223
| ^^^^ required by this bound in `is_send`
6324

64-
error: aborting due to 3 previous errors
25+
error: aborting due to previous error
6526

66-
For more information about this error, try `rustc --explain E0391`.

tests/ui/type-alias-impl-trait/inference-cycle.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,14 @@
33

44
mod m {
55
pub type Foo = impl std::fmt::Debug;
6-
//~^ ERROR cycle detected
7-
//~| ERROR cycle detected
8-
9-
// Cycle: error today, but it'd be nice if it eventually worked
106

117
pub fn foo() -> Foo {
128
is_send(bar())
139
}
1410

1511
pub fn bar() {
16-
is_send(foo()); // Today: error
12+
// Cycle: error today, but it'd be nice if it eventually worked
13+
is_send(foo());
1714
//~^ ERROR: cannot check whether the hidden type of `inference_cycle[4ecc]::m::Foo::{opaque#0}` satisfies auto traits
1815
}
1916

Original file line numberDiff line numberDiff line change
@@ -1,46 +1,7 @@
1-
error[E0391]: cycle detected when computing type of opaque `m::Foo::{opaque#0}`
2-
--> $DIR/inference-cycle.rs:5:20
3-
|
4-
LL | pub type Foo = impl std::fmt::Debug;
5-
| ^^^^^^^^^^^^^^^^^^^^
6-
|
7-
note: ...which requires type-checking `m::bar`...
8-
--> $DIR/inference-cycle.rs:16:9
9-
|
10-
LL | is_send(foo()); // Today: error
11-
| ^^^^^^^
12-
= note: ...which requires evaluating trait selection obligation `m::Foo: core::marker::Send`...
13-
= note: ...which again requires computing type of opaque `m::Foo::{opaque#0}`, completing the cycle
14-
note: cycle used when computing type of `m::Foo::{opaque#0}`
15-
--> $DIR/inference-cycle.rs:5:20
16-
|
17-
LL | pub type Foo = impl std::fmt::Debug;
18-
| ^^^^^^^^^^^^^^^^^^^^
19-
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
20-
21-
error[E0391]: cycle detected when computing type of opaque `m::Foo::{opaque#0}`
22-
--> $DIR/inference-cycle.rs:5:20
23-
|
24-
LL | pub type Foo = impl std::fmt::Debug;
25-
| ^^^^^^^^^^^^^^^^^^^^
26-
|
27-
note: ...which requires type-checking `m::bar`...
28-
--> $DIR/inference-cycle.rs:15:5
29-
|
30-
LL | pub fn bar() {
31-
| ^^^^^^^^^^^^
32-
= note: ...which again requires computing type of opaque `m::Foo::{opaque#0}`, completing the cycle
33-
note: cycle used when computing type of `m::Foo::{opaque#0}`
34-
--> $DIR/inference-cycle.rs:5:20
35-
|
36-
LL | pub type Foo = impl std::fmt::Debug;
37-
| ^^^^^^^^^^^^^^^^^^^^
38-
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
39-
401
error: cannot check whether the hidden type of `inference_cycle[4ecc]::m::Foo::{opaque#0}` satisfies auto traits
41-
--> $DIR/inference-cycle.rs:16:17
2+
--> $DIR/inference-cycle.rs:13:17
423
|
43-
LL | is_send(foo()); // Today: error
4+
LL | is_send(foo());
445
| ------- ^^^^^
456
| |
467
| required by a bound introduced by this call
@@ -51,16 +12,15 @@ note: opaque type is declared here
5112
LL | pub type Foo = impl std::fmt::Debug;
5213
| ^^^^^^^^^^^^^^^^^^^^
5314
note: this item depends on auto traits of the hidden type, but may also be registering the hidden type. This is not supported right now. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
54-
--> $DIR/inference-cycle.rs:15:12
15+
--> $DIR/inference-cycle.rs:11:12
5516
|
5617
LL | pub fn bar() {
5718
| ^^^
5819
note: required by a bound in `is_send`
59-
--> $DIR/inference-cycle.rs:24:19
20+
--> $DIR/inference-cycle.rs:21:19
6021
|
6122
LL | fn is_send<T: Send>(_: T) {}
6223
| ^^^^ required by this bound in `is_send`
6324

64-
error: aborting due to 3 previous errors
25+
error: aborting due to previous error
6526

66-
For more information about this error, try `rustc --explain E0391`.

tests/ui/type-alias-impl-trait/reveal_local.rs

-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
use std::fmt::Debug;
44

55
type Foo = impl Debug;
6-
//~^ ERROR cycle detected
7-
//~| ERROR cycle detected
8-
//~| ERROR cycle detected
96

107
fn is_send<T: Send>() {}
118

0 commit comments

Comments
 (0)