Skip to content

Commit

Permalink
Rollup merge of #100844 - evopen:migrate-diag, r=davidtwco
Browse files Browse the repository at this point in the history
migrate rustc_query_system to use SessionDiagnostic

issues:
* variable list is not supported in fluent
* ~~cannot have two sub diagnostic with the same tag (eg. 2 .note or 2 .help)~~

allow multiple tag with SessionSubdiagnostic derive
  • Loading branch information
matthiaskrgr authored Aug 31, 2022
2 parents 2af2cda + 7ce59eb commit 22c5c83
Show file tree
Hide file tree
Showing 10 changed files with 475 additions and 804 deletions.
25 changes: 25 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/query_system.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
query_system_reentrant = internal compiler error: re-entrant incremental verify failure, suppressing message
query_system_increment_compilation = internal compiler error: encountered incremental compilation error with {$dep_node}
.help = This is a known issue with the compiler. Run {$run_cmd} to allow your project to compile
query_system_increment_compilation_note1 = Please follow the instructions below to create a bug report with the provided information
query_system_increment_compilation_note2 = See <https://github.com/rust-lang/rust/issues/84970> for more information
query_system_cycle = cycle detected when {$stack_bottom}
query_system_cycle_usage = cycle used when {$usage}
query_system_cycle_stack_single = ...which immediately requires {$stack_bottom} again
query_system_cycle_stack_multiple = ...which again requires {$stack_bottom}, completing the cycle
query_system_cycle_recursive_ty_alias = type aliases cannot be recursive
query_system_cycle_recursive_ty_alias_help1 = consider using a struct, enum, or union instead to break the cycle
query_system_cycle_recursive_ty_alias_help2 = see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
query_system_cycle_recursive_trait_alias = trait aliases cannot be recursive
query_system_cycle_which_requires = ...which requires {$desc}...
query_system_query_overflow = queries overflow the depth limit!
1 change: 1 addition & 0 deletions compiler/rustc_error_messages/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ fluent_messages! {
passes => "../locales/en-US/passes.ftl",
plugin_impl => "../locales/en-US/plugin_impl.ftl",
privacy => "../locales/en-US/privacy.ftl",
query_system => "../locales/en-US/query_system.ftl",
save_analysis => "../locales/en-US/save_analysis.ftl",
ty_utils => "../locales/en-US/ty_utils.ftl",
typeck => "../locales/en-US/typeck.ftl",
Expand Down
694 changes: 249 additions & 445 deletions compiler/rustc_macros/src/diagnostics/subdiagnostic.rs

Large diffs are not rendered by default.

73 changes: 73 additions & 0 deletions compiler/rustc_query_system/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use rustc_errors::AddSubdiagnostic;
use rustc_span::Span;

pub struct CycleStack {
pub span: Span,
pub desc: String,
}

impl AddSubdiagnostic for CycleStack {
fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
diag.span_note(self.span, &format!("...which requires {}...", self.desc));
}
}

#[derive(SessionSubdiagnostic)]
pub enum StackCount {
#[note(query_system::cycle_stack_single)]
Single,
#[note(query_system::cycle_stack_multiple)]
Multiple,
}

#[derive(SessionSubdiagnostic)]
pub enum Alias {
#[note(query_system::cycle_recursive_ty_alias)]
#[help(query_system::cycle_recursive_ty_alias_help1)]
#[help(query_system::cycle_recursive_ty_alias_help2)]
Ty,
#[note(query_system::cycle_recursive_trait_alias)]
Trait,
}

#[derive(SessionSubdiagnostic)]
#[note(query_system::cycle_usage)]
pub struct CycleUsage {
#[primary_span]
pub span: Span,
pub usage: String,
}

#[derive(SessionDiagnostic)]
#[diag(query_system::cycle, code = "E0391")]
pub struct Cycle {
#[primary_span]
pub span: Span,
pub stack_bottom: String,
#[subdiagnostic]
pub cycle_stack: Vec<CycleStack>,
#[subdiagnostic]
pub stack_count: StackCount,
#[subdiagnostic]
pub alias: Option<Alias>,
#[subdiagnostic]
pub cycle_usage: Option<CycleUsage>,
}

#[derive(SessionDiagnostic)]
#[diag(query_system::reentrant)]
pub struct Reentrant;

#[derive(SessionDiagnostic)]
#[diag(query_system::increment_compilation)]
#[help]
#[note(query_system::increment_compilation_note1)]
#[note(query_system::increment_compilation_note2)]
pub struct IncrementCompilation {
pub run_cmd: String,
pub dep_node: String,
}

#[derive(SessionDiagnostic)]
#[diag(query_system::query_overflow)]
pub struct QueryOverflow;
3 changes: 3 additions & 0 deletions compiler/rustc_query_system/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#![feature(min_specialization)]
#![feature(extern_types)]
#![allow(rustc::potential_query_instability)]
// #![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]

#[macro_use]
extern crate tracing;
Expand All @@ -15,5 +17,6 @@ extern crate rustc_macros;

pub mod cache;
pub mod dep_graph;
mod error;
pub mod ich;
pub mod query;
69 changes: 33 additions & 36 deletions compiler/rustc_query_system/src/query/job.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
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,
};
use rustc_session::Session;
use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Handler, Level};
use rustc_hir::def::DefKind;
use rustc_session::{Session, SessionDiagnostic};
use rustc_span::Span;

use std::hash::Hash;
Expand Down Expand Up @@ -536,46 +535,44 @@ pub(crate) fn report_cycle<'a>(
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));
}

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
));
}

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 <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information");
} else {
err.note("trait aliases cannot be recursive");
}
cycle_stack.push(CycleStack { span, desc: query.description.to_owned() });
}

let mut cycle_usage = None;
if let Some((span, query)) = usage {
err.span_note(query.default_span(span), &format!("cycle used when {}", query.description));
cycle_usage = Some(crate::error::CycleUsage {
span: query.default_span(span),
usage: 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)
}

pub fn print_query_stack<CTX: QueryContext>(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_query_system/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,6 @@ pub trait QueryContext: HasDepContext {
) -> R;

fn depth_limit_error(&self) {
self.dep_context().sess().fatal("queries overflow the depth limit!");
self.dep_context().sess().emit_fatal(crate::error::QueryOverflow);
}
}
14 changes: 5 additions & 9 deletions compiler/rustc_query_system/src/query/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -618,16 +618,12 @@ fn incremental_verify_ich_cold(sess: &Session, dep_node: DebugArg<'_>, result: D
let old_in_panic = INSIDE_VERIFY_PANIC.with(|in_panic| in_panic.replace(true));

if old_in_panic {
sess.struct_err(
"internal compiler error: re-entrant incremental verify failure, suppressing message",
)
.emit();
sess.emit_err(crate::error::Reentrant);
} else {
sess.struct_err(&format!("internal compiler error: encountered incremental compilation error with {:?}", dep_node))
.help(&format!("This is a known issue with the compiler. Run {} to allow your project to compile", run_cmd))
.note("Please follow the instructions below to create a bug report with the provided information")
.note("See <https://github.com/rust-lang/rust/issues/84970> for more information")
.emit();
sess.emit_err(crate::error::IncrementCompilation {
run_cmd,
dep_node: format!("{:?}", dep_node),
});
panic!("Found unstable fingerprints for {:?}: {:?}", dep_node, result);
}

Expand Down
Loading

0 comments on commit 22c5c83

Please sign in to comment.