|
| 1 | +use crate::error::CycleStack; |
1 | 2 | use crate::query::plumbing::CycleError;
|
2 | 3 | use crate::query::{QueryContext, QueryStackFrame};
|
3 |
| -use rustc_hir::def::DefKind; |
4 | 4 |
|
5 | 5 | use rustc_data_structures::fx::FxHashMap;
|
6 |
| -use rustc_errors::{ |
7 |
| - struct_span_err, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Handler, Level, |
8 |
| -}; |
9 |
| -use rustc_session::Session; |
| 6 | +use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Handler, Level}; |
| 7 | +use rustc_hir::def::DefKind; |
| 8 | +use rustc_session::{Session, SessionDiagnostic}; |
10 | 9 | use rustc_span::Span;
|
11 | 10 |
|
12 | 11 | use std::hash::Hash;
|
@@ -536,46 +535,44 @@ pub(crate) fn report_cycle<'a>(
|
536 | 535 | assert!(!stack.is_empty());
|
537 | 536 |
|
538 | 537 | let span = stack[0].query.default_span(stack[1 % stack.len()].span);
|
539 |
| - let mut err = |
540 |
| - struct_span_err!(sess, span, E0391, "cycle detected when {}", stack[0].query.description); |
| 538 | + |
| 539 | + let mut cycle_stack = Vec::new(); |
| 540 | + |
| 541 | + use crate::error::StackCount; |
| 542 | + let stack_count = if stack.len() == 1 { StackCount::Single } else { StackCount::Multiple }; |
541 | 543 |
|
542 | 544 | for i in 1..stack.len() {
|
543 | 545 | let query = &stack[i].query;
|
544 | 546 | let span = query.default_span(stack[(i + 1) % stack.len()].span);
|
545 |
| - err.span_note(span, &format!("...which requires {}...", query.description)); |
546 |
| - } |
547 |
| - |
548 |
| - if stack.len() == 1 { |
549 |
| - err.note(&format!("...which immediately requires {} again", stack[0].query.description)); |
550 |
| - } else { |
551 |
| - err.note(&format!( |
552 |
| - "...which again requires {}, completing the cycle", |
553 |
| - stack[0].query.description |
554 |
| - )); |
555 |
| - } |
556 |
| - |
557 |
| - if stack.iter().all(|entry| { |
558 |
| - entry |
559 |
| - .query |
560 |
| - .def_kind |
561 |
| - .map_or(false, |def_kind| matches!(def_kind, DefKind::TyAlias | DefKind::TraitAlias)) |
562 |
| - }) { |
563 |
| - if stack.iter().all(|entry| { |
564 |
| - entry.query.def_kind.map_or(false, |def_kind| matches!(def_kind, DefKind::TyAlias)) |
565 |
| - }) { |
566 |
| - err.note("type aliases cannot be recursive"); |
567 |
| - err.help("consider using a struct, enum, or union instead to break the cycle"); |
568 |
| - err.help("see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information"); |
569 |
| - } else { |
570 |
| - err.note("trait aliases cannot be recursive"); |
571 |
| - } |
| 547 | + cycle_stack.push(CycleStack { span, desc: query.description.to_owned() }); |
572 | 548 | }
|
573 | 549 |
|
| 550 | + let mut cycle_usage = None; |
574 | 551 | if let Some((span, query)) = usage {
|
575 |
| - err.span_note(query.default_span(span), &format!("cycle used when {}", query.description)); |
| 552 | + cycle_usage = Some(crate::error::CycleUsage { |
| 553 | + span: query.default_span(span), |
| 554 | + usage: query.description, |
| 555 | + }); |
576 | 556 | }
|
577 | 557 |
|
578 |
| - err |
| 558 | + let alias = if stack.iter().all(|entry| entry.query.def_kind == Some(DefKind::TyAlias)) { |
| 559 | + Some(crate::error::Alias::Ty) |
| 560 | + } else if stack.iter().all(|entry| entry.query.def_kind == Some(DefKind::TraitAlias)) { |
| 561 | + Some(crate::error::Alias::Trait) |
| 562 | + } else { |
| 563 | + None |
| 564 | + }; |
| 565 | + |
| 566 | + let cycle_diag = crate::error::Cycle { |
| 567 | + span, |
| 568 | + cycle_stack, |
| 569 | + stack_bottom: stack[0].query.description.to_owned(), |
| 570 | + alias, |
| 571 | + cycle_usage: cycle_usage, |
| 572 | + stack_count, |
| 573 | + }; |
| 574 | + |
| 575 | + cycle_diag.into_diagnostic(&sess.parse_sess) |
579 | 576 | }
|
580 | 577 |
|
581 | 578 | pub fn print_query_stack<CTX: QueryContext>(
|
|
0 commit comments