Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

migrate rustc_query_system to use SessionDiagnostic #100844

Merged
merged 5 commits into from
Sep 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -48,6 +48,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