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
This commit is contained in:
commit
5459333ffc
15 changed files with 55 additions and 234 deletions
|
@ -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)) {
|
||||
|
|
|
@ -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>,
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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" {
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}};
|
||||
|
|
|
@ -15,6 +15,7 @@ pub enum HandleCycleError {
|
|||
Error,
|
||||
Fatal,
|
||||
DelayBug,
|
||||
Stash,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
|
|
|
@ -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;
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3104,6 +3104,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
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue