Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stash and cancel cycle errors for auto trait leakage in opaques #117241

Merged
merged 1 commit into from Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_errors/src/lib.rs
Expand Up @@ -508,6 +508,8 @@ pub enum StashKey {
TraitMissingMethod,
OpaqueHiddenTypeMismatch,
MaybeForgetReturn,
/// Query cycle detected, stashing in favor of a better error.
Cycle,
}

fn default_track_diagnostic(d: &mut Diagnostic, f: &mut dyn FnMut(&mut Diagnostic)) {
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_macros/src/query.rs
Expand Up @@ -97,6 +97,9 @@ struct QueryModifiers {
/// A cycle error results in a delay_bug call
cycle_delay_bug: Option<Ident>,

/// A cycle error results in a stashed cycle error that can be unstashed and canceled later
cycle_stash: Option<Ident>,

/// Don't hash the result, instead just mark a query red if it runs
no_hash: Option<Ident>,

Expand Down Expand Up @@ -127,6 +130,7 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
let mut desc = None;
let mut fatal_cycle = None;
let mut cycle_delay_bug = None;
let mut cycle_stash = None;
let mut no_hash = None;
let mut anon = None;
let mut eval_always = None;
Expand Down Expand Up @@ -181,6 +185,8 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
try_insert!(fatal_cycle = modifier);
} else if modifier == "cycle_delay_bug" {
try_insert!(cycle_delay_bug = modifier);
} else if modifier == "cycle_stash" {
try_insert!(cycle_stash = modifier);
} else if modifier == "no_hash" {
try_insert!(no_hash = modifier);
} else if modifier == "anon" {
Expand Down Expand Up @@ -208,6 +214,7 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
desc,
fatal_cycle,
cycle_delay_bug,
cycle_stash,
no_hash,
anon,
eval_always,
Expand Down Expand Up @@ -329,6 +336,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
fatal_cycle,
arena_cache,
cycle_delay_bug,
cycle_stash,
no_hash,
anon,
eval_always,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/query/mod.rs
Expand Up @@ -251,6 +251,7 @@ rustc_queries! {
"computing type of opaque `{path}`",
path = tcx.def_path_str(key),
}
cycle_stash
}

query type_alias_is_lazy(key: DefId) -> bool {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_query_impl/src/plumbing.rs
Expand Up @@ -197,6 +197,9 @@ macro_rules! handle_cycle_error {
([(fatal_cycle) $($rest:tt)*]) => {{
rustc_query_system::HandleCycleError::Fatal
}};
([(cycle_stash) $($rest:tt)*]) => {{
rustc_query_system::HandleCycleError::Stash
}};
([(cycle_delay_bug) $($rest:tt)*]) => {{
rustc_query_system::HandleCycleError::DelayBug
}};
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_query_system/src/error.rs
Expand Up @@ -15,6 +15,7 @@ pub enum HandleCycleError {
Error,
Fatal,
DelayBug,
Stash,
}

#[derive(Subdiagnostic)]
Expand Down
13 changes: 12 additions & 1 deletion compiler/rustc_query_system/src/query/plumbing.rs
Expand Up @@ -19,7 +19,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::sync::Lock;
#[cfg(parallel_compiler)]
use rustc_data_structures::{outline, sync};
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, FatalError};
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, FatalError, StashKey};
use rustc_span::{Span, DUMMY_SP};
use std::cell::Cell;
use std::collections::hash_map::Entry;
Expand Down Expand Up @@ -133,6 +133,17 @@ where
let guar = error.delay_as_bug();
query.value_from_cycle_error(*qcx.dep_context(), &cycle_error.cycle, guar)
}
Stash => {
let guar = if let Some(root) = cycle_error.cycle.first()
&& let Some(span) = root.query.span
{
error.stash(span, StashKey::Cycle);
qcx.dep_context().sess().delay_span_bug(span, "delayed cycle error")
} else {
error.emit()
};
query.value_from_cycle_error(*qcx.dep_context(), &cycle_error.cycle, guar)
}
}
}

Expand Down
Expand Up @@ -3071,6 +3071,13 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
);
}
};

if let Some(diag) =
self.tcx.sess.diagnostic().steal_diagnostic(self.tcx.def_span(def_id), StashKey::Cycle)
{
diag.cancel();
}

err
}

Expand Down
2 changes: 0 additions & 2 deletions tests/ui/impl-trait/auto-trait-leak.rs
Expand Up @@ -9,8 +9,6 @@ fn main() {}
// independently resolved and only require the concrete
// return type, which can't depend on the obligation.
fn cycle1() -> impl Clone {
//~^ ERROR cycle detected
//~| ERROR cycle detected
send(cycle2().clone());

Rc::new(Cell::new(5))
Expand Down
68 changes: 3 additions & 65 deletions tests/ui/impl-trait/auto-trait-leak.stderr
@@ -1,66 +1,5 @@
error[E0391]: cycle detected when computing type of opaque `cycle1::{opaque#0}`
--> $DIR/auto-trait-leak.rs:11:16
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^
|
note: ...which requires type-checking `cycle1`...
--> $DIR/auto-trait-leak.rs:14:5
|
LL | send(cycle2().clone());
| ^^^^
= note: ...which requires evaluating trait selection obligation `cycle2::{opaque#0}: core::marker::Send`...
note: ...which requires computing type of opaque `cycle2::{opaque#0}`...
--> $DIR/auto-trait-leak.rs:19:16
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^
note: ...which requires type-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:20:5
|
LL | send(cycle1().clone());
| ^^^^
= note: ...which requires evaluating trait selection obligation `cycle1::{opaque#0}: core::marker::Send`...
= note: ...which again requires computing type of opaque `cycle1::{opaque#0}`, completing the cycle
note: cycle used when computing type of `cycle1::{opaque#0}`
--> $DIR/auto-trait-leak.rs:11:16
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^
= 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

error[E0391]: cycle detected when computing type of opaque `cycle1::{opaque#0}`
--> $DIR/auto-trait-leak.rs:11:16
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^
|
note: ...which requires type-checking `cycle1`...
--> $DIR/auto-trait-leak.rs:14:5
|
LL | send(cycle2().clone());
| ^^^^
= note: ...which requires evaluating trait selection obligation `cycle2::{opaque#0}: core::marker::Send`...
note: ...which requires computing type of opaque `cycle2::{opaque#0}`...
--> $DIR/auto-trait-leak.rs:19:16
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^
note: ...which requires type-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:19:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which again requires computing type of opaque `cycle1::{opaque#0}`, completing the cycle
note: cycle used when computing type of `cycle1::{opaque#0}`
--> $DIR/auto-trait-leak.rs:11:16
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^
= 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

error: cannot check whether the hidden type of opaque type satisfies auto traits
--> $DIR/auto-trait-leak.rs:20:10
--> $DIR/auto-trait-leak.rs:18:10
|
LL | send(cycle1().clone());
| ---- ^^^^^^^^^^^^^^^^
Expand All @@ -73,7 +12,7 @@ note: opaque type is declared here
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^
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
--> $DIR/auto-trait-leak.rs:19:4
--> $DIR/auto-trait-leak.rs:17:4
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^
Expand All @@ -83,6 +22,5 @@ note: required by a bound in `send`
LL | fn send<T: Send>(_: T) {}
| ^^^^ required by this bound in `send`

error: aborting due to 3 previous errors
error: aborting due to previous error

For more information about this error, try `rustc --explain E0391`.
3 changes: 0 additions & 3 deletions tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs
Expand Up @@ -5,9 +5,6 @@

mod m {
pub type Foo = impl std::fmt::Debug;
//~^ ERROR: cycle detected when computing type of opaque `m::Foo::{opaque#0}` [E0391]
//~| ERROR: cycle detected when computing type of opaque `m::Foo::{opaque#0}` [E0391]

pub fn foo() -> Foo {
22_u32
}
Expand Down
48 changes: 4 additions & 44 deletions tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr
@@ -1,44 +1,5 @@
error[E0391]: cycle detected when computing type of opaque `m::Foo::{opaque#0}`
--> $DIR/auto-trait-leakage3.rs:7:20
|
LL | pub type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires type-checking `m::bar`...
--> $DIR/auto-trait-leakage3.rs:16:9
|
LL | is_send(foo());
| ^^^^^^^
= note: ...which requires evaluating trait selection obligation `m::Foo: core::marker::Send`...
= note: ...which again requires computing type of opaque `m::Foo::{opaque#0}`, completing the cycle
note: cycle used when computing type of `m::Foo::{opaque#0}`
--> $DIR/auto-trait-leakage3.rs:7:20
|
LL | pub type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
= 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

error[E0391]: cycle detected when computing type of opaque `m::Foo::{opaque#0}`
--> $DIR/auto-trait-leakage3.rs:7:20
|
LL | pub type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires type-checking `m::bar`...
--> $DIR/auto-trait-leakage3.rs:15:5
|
LL | pub fn bar() {
| ^^^^^^^^^^^^
= note: ...which again requires computing type of opaque `m::Foo::{opaque#0}`, completing the cycle
note: cycle used when computing type of `m::Foo::{opaque#0}`
--> $DIR/auto-trait-leakage3.rs:7:20
|
LL | pub type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
= 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

error: cannot check whether the hidden type of `auto_trait_leakage3[211d]::m::Foo::{opaque#0}` satisfies auto traits
--> $DIR/auto-trait-leakage3.rs:16:17
--> $DIR/auto-trait-leakage3.rs:13:17
|
LL | is_send(foo());
| ------- ^^^^^
Expand All @@ -51,16 +12,15 @@ note: opaque type is declared here
LL | pub type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
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
--> $DIR/auto-trait-leakage3.rs:15:12
--> $DIR/auto-trait-leakage3.rs:12:12
|
LL | pub fn bar() {
| ^^^
note: required by a bound in `is_send`
--> $DIR/auto-trait-leakage3.rs:20:19
--> $DIR/auto-trait-leakage3.rs:17:19
|
LL | fn is_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `is_send`

error: aborting due to 3 previous errors
error: aborting due to previous error

For more information about this error, try `rustc --explain E0391`.
7 changes: 2 additions & 5 deletions tests/ui/type-alias-impl-trait/inference-cycle.rs
Expand Up @@ -3,17 +3,14 @@

mod m {
pub type Foo = impl std::fmt::Debug;
//~^ ERROR cycle detected
//~| ERROR cycle detected

// Cycle: error today, but it'd be nice if it eventually worked

pub fn foo() -> Foo {
is_send(bar())
}

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

Expand Down
50 changes: 5 additions & 45 deletions tests/ui/type-alias-impl-trait/inference-cycle.stderr
@@ -1,46 +1,7 @@
error[E0391]: cycle detected when computing type of opaque `m::Foo::{opaque#0}`
--> $DIR/inference-cycle.rs:5:20
|
LL | pub type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires type-checking `m::bar`...
--> $DIR/inference-cycle.rs:16:9
|
LL | is_send(foo()); // Today: error
| ^^^^^^^
= note: ...which requires evaluating trait selection obligation `m::Foo: core::marker::Send`...
= note: ...which again requires computing type of opaque `m::Foo::{opaque#0}`, completing the cycle
note: cycle used when computing type of `m::Foo::{opaque#0}`
--> $DIR/inference-cycle.rs:5:20
|
LL | pub type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
= 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

error[E0391]: cycle detected when computing type of opaque `m::Foo::{opaque#0}`
--> $DIR/inference-cycle.rs:5:20
|
LL | pub type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires type-checking `m::bar`...
--> $DIR/inference-cycle.rs:15:5
|
LL | pub fn bar() {
| ^^^^^^^^^^^^
= note: ...which again requires computing type of opaque `m::Foo::{opaque#0}`, completing the cycle
note: cycle used when computing type of `m::Foo::{opaque#0}`
--> $DIR/inference-cycle.rs:5:20
|
LL | pub type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
= 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

error: cannot check whether the hidden type of `inference_cycle[4ecc]::m::Foo::{opaque#0}` satisfies auto traits
--> $DIR/inference-cycle.rs:16:17
--> $DIR/inference-cycle.rs:13:17
|
LL | is_send(foo()); // Today: error
LL | is_send(foo());
| ------- ^^^^^
| |
| required by a bound introduced by this call
Expand All @@ -51,16 +12,15 @@ note: opaque type is declared here
LL | pub type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
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
--> $DIR/inference-cycle.rs:15:12
--> $DIR/inference-cycle.rs:11:12
|
LL | pub fn bar() {
| ^^^
note: required by a bound in `is_send`
--> $DIR/inference-cycle.rs:24:19
--> $DIR/inference-cycle.rs:21:19
|
LL | fn is_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `is_send`

error: aborting due to 3 previous errors
error: aborting due to previous error

For more information about this error, try `rustc --explain E0391`.
3 changes: 0 additions & 3 deletions tests/ui/type-alias-impl-trait/reveal_local.rs
Expand Up @@ -3,9 +3,6 @@
use std::fmt::Debug;

type Foo = impl Debug;
//~^ ERROR cycle detected
//~| ERROR cycle detected
//~| ERROR cycle detected

fn is_send<T: Send>() {}

Expand Down