|
1 | 1 | use crate::dep_graph::DepContext;
|
2 | 2 | use crate::query::plumbing::CycleError;
|
3 |
| -use crate::query::{QueryContext, QueryStackFrame}; |
| 3 | +use crate::query::{QueryContext, QueryStackFrame, SimpleDefKind}; |
4 | 4 |
|
5 | 5 | use rustc_data_structures::fx::FxHashMap;
|
6 | 6 | use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, Handler, Level};
|
@@ -591,10 +591,33 @@ pub(crate) fn report_cycle<'a>(
|
591 | 591 | err.span_note(span, &format!("...which requires {}...", query.description));
|
592 | 592 | }
|
593 | 593 |
|
594 |
| - err.note(&format!( |
595 |
| - "...which again requires {}, completing the cycle", |
596 |
| - stack[0].query.description |
597 |
| - )); |
| 594 | + if stack.len() == 1 { |
| 595 | + err.note(&format!("...which immediately requires {} again", stack[0].query.description)); |
| 596 | + } else { |
| 597 | + err.note(&format!( |
| 598 | + "...which again requires {}, completing the cycle", |
| 599 | + stack[0].query.description |
| 600 | + )); |
| 601 | + } |
| 602 | + |
| 603 | + if stack.iter().all(|entry| { |
| 604 | + entry.query.def_kind.map_or(false, |def_kind| { |
| 605 | + matches!(def_kind, SimpleDefKind::TyAlias | SimpleDefKind::TraitAlias) |
| 606 | + }) |
| 607 | + }) { |
| 608 | + if stack.iter().all(|entry| { |
| 609 | + entry |
| 610 | + .query |
| 611 | + .def_kind |
| 612 | + .map_or(false, |def_kind| matches!(def_kind, SimpleDefKind::TyAlias)) |
| 613 | + }) { |
| 614 | + err.note("type aliases cannot be recursive"); |
| 615 | + err.help("consider using a struct, enum, or union instead to break the cycle"); |
| 616 | + err.help("see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information"); |
| 617 | + } else { |
| 618 | + err.note("trait aliases cannot be recursive"); |
| 619 | + } |
| 620 | + } |
598 | 621 |
|
599 | 622 | if let Some((span, query)) = usage {
|
600 | 623 | err.span_note(fix_span(span, &query), &format!("cycle used when {}", query.description));
|
|
0 commit comments