From 94a0819fe3a0d679c3042a77bfe6a2afc505daea Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:11:28 +0200 Subject: Adding upstream version 1.66.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_query_system/src/query/job.rs | 90 +++++++++++++++++----------- 1 file changed, 54 insertions(+), 36 deletions(-) (limited to 'compiler/rustc_query_system/src/query/job.rs') diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index 6d2aff381..ed65393f5 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -1,11 +1,12 @@ +use crate::error::CycleStack; use crate::query::plumbing::CycleError; use crate::query::{QueryContext, QueryStackFrame}; -use rustc_hir::def::DefKind; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{ - struct_span_err, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Handler, Level, + Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic, Level, }; +use rustc_hir::def::DefKind; use rustc_session::Session; use rustc_span::Span; @@ -60,6 +61,7 @@ impl QueryJobId { } } +#[derive(Clone)] pub struct QueryJobInfo { pub query: QueryStackFrame, pub job: QueryJob, @@ -117,10 +119,10 @@ impl QueryJob { } } -#[cfg(not(parallel_compiler))] impl QueryJobId { #[cold] #[inline(never)] + #[cfg(not(parallel_compiler))] pub(super) fn find_cycle_in_stack( &self, query_map: QueryMap, @@ -157,6 +159,24 @@ impl QueryJobId { panic!("did not find a cycle") } + + #[cold] + #[inline(never)] + pub fn try_find_layout_root(&self, query_map: QueryMap) -> Option<(QueryJobInfo, usize)> { + let mut last_layout = None; + let mut current_id = Some(*self); + let mut depth = 0; + + while let Some(id) = current_id { + let info = query_map.get(&id).unwrap(); + if info.query.name == "layout_of" { + depth += 1; + last_layout = Some((info.clone(), depth)); + } + current_id = info.job.parent; + } + last_layout + } } #[cfg(parallel_compiler)] @@ -531,51 +551,49 @@ pub fn deadlock(query_map: QueryMap, registry: &rayon_core::Registry) { #[cold] pub(crate) fn report_cycle<'a>( sess: &'a Session, - CycleError { usage, cycle: stack }: CycleError, + CycleError { usage, cycle: stack }: &CycleError, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { assert!(!stack.is_empty()); let span = stack[0].query.default_span(stack[1 % stack.len()].span); - let mut err = - struct_span_err!(sess, span, E0391, "cycle detected when {}", stack[0].query.description); + + let mut cycle_stack = Vec::new(); + + use crate::error::StackCount; + let stack_count = if stack.len() == 1 { StackCount::Single } else { StackCount::Multiple }; for i in 1..stack.len() { let query = &stack[i].query; let span = query.default_span(stack[(i + 1) % stack.len()].span); - err.span_note(span, &format!("...which requires {}...", query.description)); + cycle_stack.push(CycleStack { span, desc: query.description.to_owned() }); } - if stack.len() == 1 { - err.note(&format!("...which immediately requires {} again", stack[0].query.description)); - } else { - err.note(&format!( - "...which again requires {}, completing the cycle", - stack[0].query.description - )); + let mut cycle_usage = None; + if let Some((span, ref query)) = *usage { + cycle_usage = Some(crate::error::CycleUsage { + span: query.default_span(span), + usage: query.description.to_string(), + }); } - if stack.iter().all(|entry| { - entry - .query - .def_kind - .map_or(false, |def_kind| matches!(def_kind, DefKind::TyAlias | DefKind::TraitAlias)) - }) { - if stack.iter().all(|entry| { - entry.query.def_kind.map_or(false, |def_kind| matches!(def_kind, DefKind::TyAlias)) - }) { - err.note("type aliases cannot be recursive"); - err.help("consider using a struct, enum, or union instead to break the cycle"); - err.help("see for more information"); - } else { - err.note("trait aliases cannot be recursive"); - } - } - - if let Some((span, query)) = usage { - err.span_note(query.default_span(span), &format!("cycle used when {}", query.description)); - } - - err + let alias = if stack.iter().all(|entry| entry.query.def_kind == Some(DefKind::TyAlias)) { + Some(crate::error::Alias::Ty) + } else if stack.iter().all(|entry| entry.query.def_kind == Some(DefKind::TraitAlias)) { + Some(crate::error::Alias::Trait) + } else { + None + }; + + let cycle_diag = crate::error::Cycle { + span, + cycle_stack, + stack_bottom: stack[0].query.description.to_owned(), + alias, + cycle_usage: cycle_usage, + stack_count, + }; + + cycle_diag.into_diagnostic(&sess.parse_sess.span_diagnostic) } pub fn print_query_stack( -- cgit v1.2.3