Skip to content

Commit ac638c1

Browse files
committed
use derive proc macro to impl SessionDiagnostic
fixes `SessionSubdiagnostic` to accept multiple attributes emitting list of fluent message remains unresolved
1 parent d7e07c0 commit ac638c1

File tree

7 files changed

+415
-811
lines changed

7 files changed

+415
-811
lines changed

compiler/rustc_error_messages/locales/en-US/query_system.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ query_system_cycle_recursive_ty_alias_help1 = consider using a struct, enum, or
1919
query_system_cycle_recursive_ty_alias_help2 = see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
2020
2121
query_system_cycle_recursive_trait_alias = trait aliases cannot be recursive
22+
23+
query_system_cycle_which_requires = ...which requires {$desc}...

compiler/rustc_macros/src/diagnostics/subdiagnostic.rs

+249-445
Large diffs are not rendered by default.

compiler/rustc_query_system/src/error.rs

+48-39
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,59 @@
1-
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
2-
use rustc_session::SessionDiagnostic;
1+
use rustc_errors::AddSubdiagnostic;
32
use rustc_span::Span;
43

5-
pub struct Cycle {
4+
pub struct CycleStack {
65
pub span: Span,
7-
pub stack_bottom: String,
8-
pub upper_stack_info: Vec<(Span, String)>,
9-
pub recursive_ty_alias: bool,
10-
pub recursive_trait_alias: bool,
11-
pub cycle_usage: Option<(Span, String)>,
6+
pub desc: String,
127
}
138

14-
impl SessionDiagnostic<'_> for Cycle {
15-
fn into_diagnostic(
16-
self,
17-
sess: &'_ rustc_session::parse::ParseSess,
18-
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
19-
let mut diag = sess.struct_err(rustc_errors::fluent::query_system::cycle);
20-
diag.set_span(self.span);
21-
diag.code(rustc_errors::DiagnosticId::Error("E0391".to_string()));
22-
let upper_stack_len = self.upper_stack_info.len();
23-
for (span, desc) in self.upper_stack_info.into_iter() {
24-
// FIXME(#100717): use fluent translation
25-
diag.span_note(span, &format!("...which requires {}...", desc));
26-
}
27-
diag.set_arg("stack_bottom", self.stack_bottom);
28-
if upper_stack_len == 0 {
29-
diag.note(rustc_errors::fluent::query_system::cycle_stack_single);
30-
} else {
31-
diag.note(rustc_errors::fluent::query_system::cycle_stack_multiple);
32-
}
33-
if self.recursive_trait_alias {
34-
diag.note(rustc_errors::fluent::query_system::cycle_recursive_trait_alias);
35-
} else if self.recursive_ty_alias {
36-
diag.note(rustc_errors::fluent::query_system::cycle_recursive_ty_alias);
37-
diag.help(rustc_errors::fluent::query_system::cycle_recursive_ty_alias_help1);
38-
diag.help(rustc_errors::fluent::query_system::cycle_recursive_ty_alias_help2);
39-
}
40-
if let Some((span, desc)) = self.cycle_usage {
41-
diag.set_arg("usage", desc);
42-
diag.span_note(span, rustc_errors::fluent::query_system::cycle_usage);
43-
}
44-
diag
9+
impl AddSubdiagnostic for CycleStack {
10+
fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
11+
diag.span_note(self.span, &format!("...which requires {}...", self.desc));
4512
}
4613
}
4714

15+
#[derive(SessionSubdiagnostic)]
16+
pub enum StackCount {
17+
#[note(query_system::cycle_stack_single)]
18+
Single,
19+
#[note(query_system::cycle_stack_multiple)]
20+
Multiple,
21+
}
22+
23+
#[derive(SessionSubdiagnostic)]
24+
pub enum Alias {
25+
#[note(query_system::cycle_recursive_ty_alias)]
26+
#[help(query_system::cycle_recursive_ty_alias_help1)]
27+
#[help(query_system::cycle_recursive_ty_alias_help2)]
28+
Ty,
29+
#[note(query_system::cycle_recursive_trait_alias)]
30+
Trait,
31+
}
32+
33+
#[derive(SessionSubdiagnostic)]
34+
#[note(query_system::cycle_usage)]
35+
pub struct CycleUsage {
36+
#[primary_span]
37+
pub span: Span,
38+
pub usage: String,
39+
}
40+
41+
#[derive(SessionDiagnostic)]
42+
#[diag(query_system::cycle, code = "E0391")]
43+
pub struct Cycle {
44+
#[primary_span]
45+
pub span: Span,
46+
pub stack_bottom: String,
47+
#[subdiagnostic]
48+
pub cycle_stack: Vec<CycleStack>,
49+
#[subdiagnostic]
50+
pub stack_count: StackCount,
51+
#[subdiagnostic]
52+
pub alias: Option<Alias>,
53+
#[subdiagnostic]
54+
pub cycle_usage: Option<CycleUsage>,
55+
}
56+
4857
#[derive(SessionDiagnostic)]
4958
#[diag(query_system::reentrant)]
5059
pub struct Reentrant;

compiler/rustc_query_system/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#![feature(min_specialization)]
66
#![feature(extern_types)]
77
#![allow(rustc::potential_query_instability)]
8-
#![deny(rustc::untranslatable_diagnostic)]
8+
// #![deny(rustc::untranslatable_diagnostic)]
99
#![deny(rustc::diagnostic_outside_of_impl)]
1010

1111
#[macro_use]

compiler/rustc_query_system/src/query/job.rs

+30-13
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::error::CycleStack;
12
use crate::query::plumbing::CycleError;
23
use crate::query::{QueryContext, QueryStackFrame};
34

@@ -535,26 +536,42 @@ pub(crate) fn report_cycle<'a>(
535536

536537
let span = stack[0].query.default_span(stack[1 % stack.len()].span);
537538

538-
let mut cycle_diag = crate::error::Cycle {
539-
span,
540-
upper_stack_info: Vec::with_capacity(stack.len() - 1),
541-
stack_bottom: stack[0].query.description.to_owned(),
542-
recursive_ty_alias: false,
543-
recursive_trait_alias: false,
544-
cycle_usage: usage.map(|(span, query)| (query.default_span(span), query.description)),
545-
};
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 };
546543

547544
for i in 1..stack.len() {
548545
let query = &stack[i].query;
549546
let span = query.default_span(stack[(i + 1) % stack.len()].span);
550-
cycle_diag.upper_stack_info.push((span, query.description.to_owned()));
547+
cycle_stack.push(CycleStack { span, desc: query.description.to_owned() });
551548
}
552549

553-
if stack.iter().all(|entry| entry.query.def_kind == Some(DefKind::TyAlias)) {
554-
cycle_diag.recursive_ty_alias = true;
555-
} else if stack.iter().all(|entry| entry.query.def_kind == Some(DefKind::TraitAlias)) {
556-
cycle_diag.recursive_trait_alias = true;
550+
let mut cycle_usage = None;
551+
if let Some((span, query)) = usage {
552+
cycle_usage = Some(crate::error::CycleUsage {
553+
span: query.default_span(span),
554+
usage: query.description,
555+
});
557556
}
557+
// let cycle_usage = usage.map(|(span, query)| query.default_span(span))
558+
559+
let alias = if stack.iter().all(|entry| entry.query.def_kind == Some(DefKind::TyAlias)) {
560+
Some(crate::error::Alias::Ty)
561+
} else if stack.iter().all(|entry| entry.query.def_kind == Some(DefKind::TraitAlias)) {
562+
Some(crate::error::Alias::Trait)
563+
} else {
564+
None
565+
};
566+
567+
let cycle_diag = crate::error::Cycle {
568+
span,
569+
cycle_stack,
570+
stack_bottom: stack[0].query.description.to_owned(),
571+
alias,
572+
cycle_usage: cycle_usage,
573+
stack_count,
574+
};
558575

559576
cycle_diag.into_diagnostic(&sess.parse_sess)
560577
}

0 commit comments

Comments
 (0)