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

Allow nesting subdiagnostics in #[derive(Subdiagnostic)] #124218

Merged
merged 4 commits into from
Apr 23, 2024
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
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl Subdiagnostic for InvalidAbiReason {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
_: F,
_: &F,
) {
#[allow(rustc::untranslatable_diagnostic)]
diag.note(self.0);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_ast_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ impl Subdiagnostic for EmptyLabelManySpans {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
_: F,
_: &F,
) {
diag.span_labels(self.0, "");
}
Expand Down Expand Up @@ -751,7 +751,7 @@ impl Subdiagnostic for StableFeature {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
_: F,
_: &F,
) {
diag.arg("name", self.name);
diag.arg("since", self.since);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ impl Subdiagnostic for FormatUnusedArg {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
f: F,
f: &F,
) {
diag.arg("named", self.named);
let msg = f(diag, crate::fluent_generated::builtin_macros_format_unused_arg.into());
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,15 +177,15 @@ where
{
/// Add a subdiagnostic to an existing diagnostic.
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
self.add_to_diag_with(diag, |_, m| m);
self.add_to_diag_with(diag, &|_, m| m);
}

/// Add a subdiagnostic to an existing diagnostic where `f` is invoked on every message used
/// (to optionally perform eager translation).
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
f: F,
f: &F,
);
}

Expand Down Expand Up @@ -1197,7 +1197,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
dcx: &crate::DiagCtxt,
subdiagnostic: impl Subdiagnostic,
) -> &mut Self {
subdiagnostic.add_to_diag_with(self, |diag, msg| {
subdiagnostic.add_to_diag_with(self, &|diag, msg| {
let args = diag.args.iter();
let msg = diag.subdiagnostic_message_to_diagnostic_message(msg);
dcx.eagerly_translate(msg, args)
Expand Down
66 changes: 37 additions & 29 deletions compiler/rustc_errors/src/diagnostic_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,36 @@ impl IntoDiagArg for rustc_lint_defs::Level {
}
}

impl<Id> IntoDiagArg for hir::def::Res<Id> {
fn into_diag_arg(self) -> DiagArgValue {
DiagArgValue::Str(Cow::Borrowed(self.descr()))
}
}

impl IntoDiagArg for DiagLocation {
fn into_diag_arg(self) -> DiagArgValue {
DiagArgValue::Str(Cow::from(self.to_string()))
}
}

impl IntoDiagArg for Backtrace {
fn into_diag_arg(self) -> DiagArgValue {
DiagArgValue::Str(Cow::from(self.to_string()))
}
}

impl IntoDiagArg for Level {
fn into_diag_arg(self) -> DiagArgValue {
DiagArgValue::Str(Cow::from(self.to_string()))
}
}

impl IntoDiagArg for type_ir::ClosureKind {
fn into_diag_arg(self) -> DiagArgValue {
DiagArgValue::Str(self.as_str().into())
}
}

#[derive(Clone)]
pub struct DiagSymbolList(Vec<Symbol>);

Expand All @@ -244,12 +274,6 @@ impl IntoDiagArg for DiagSymbolList {
}
}

impl<Id> IntoDiagArg for hir::def::Res<Id> {
fn into_diag_arg(self) -> DiagArgValue {
DiagArgValue::Str(Cow::Borrowed(self.descr()))
}
}

impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetDataLayoutErrors<'_> {
fn into_diag(self, dcx: &DiagCtxt, level: Level) -> Diag<'_, G> {
match self {
Expand Down Expand Up @@ -302,7 +326,7 @@ impl Subdiagnostic for SingleLabelManySpans {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
_: F,
_: &F,
) {
diag.span_labels(self.spans, self.label);
}
Expand All @@ -316,24 +340,6 @@ pub struct ExpectedLifetimeParameter {
pub count: usize,
}

impl IntoDiagArg for DiagLocation {
fn into_diag_arg(self) -> DiagArgValue {
DiagArgValue::Str(Cow::from(self.to_string()))
}
}

impl IntoDiagArg for Backtrace {
fn into_diag_arg(self) -> DiagArgValue {
DiagArgValue::Str(Cow::from(self.to_string()))
}
}

impl IntoDiagArg for Level {
fn into_diag_arg(self) -> DiagArgValue {
DiagArgValue::Str(Cow::from(self.to_string()))
}
}

#[derive(Subdiagnostic)]
#[suggestion(errors_indicate_anonymous_lifetime, code = "{suggestion}", style = "verbose")]
pub struct IndicateAnonymousLifetime {
Expand All @@ -343,8 +349,10 @@ pub struct IndicateAnonymousLifetime {
pub suggestion: String,
}

impl IntoDiagArg for type_ir::ClosureKind {
fn into_diag_arg(self) -> DiagArgValue {
DiagArgValue::Str(self.as_str().into())
}
#[derive(Subdiagnostic)]
pub struct ElidedLifetimeInPathSubdiag {
#[subdiagnostic]
pub expected: ExpectedLifetimeParameter,
#[subdiagnostic]
pub indicate: Option<IndicateAnonymousLifetime>,
}
33 changes: 15 additions & 18 deletions compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ pub use diagnostic::{
SubdiagMessageOp, Subdiagnostic,
};
pub use diagnostic_impls::{
DiagArgFromDisplay, DiagSymbolList, ExpectedLifetimeParameter, IndicateAnonymousLifetime,
SingleLabelManySpans,
DiagArgFromDisplay, DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter,
IndicateAnonymousLifetime, SingleLabelManySpans,
};
pub use emitter::ColorConfig;
pub use rustc_error_messages::{
Expand Down Expand Up @@ -1912,27 +1912,24 @@ impl Level {
}

// FIXME(eddyb) this doesn't belong here AFAICT, should be moved to callsite.
pub fn add_elided_lifetime_in_path_suggestion<G: EmissionGuarantee>(
pub fn elided_lifetime_in_path_suggestion(
source_map: &SourceMap,
diag: &mut Diag<'_, G>,
n: usize,
path_span: Span,
incl_angl_brckt: bool,
insertion_span: Span,
) {
diag.subdiagnostic(diag.dcx, ExpectedLifetimeParameter { span: path_span, count: n });
if !source_map.is_span_accessible(insertion_span) {
// Do not try to suggest anything if generated by a proc-macro.
return;
}
let anon_lts = vec!["'_"; n].join(", ");
let suggestion =
if incl_angl_brckt { format!("<{anon_lts}>") } else { format!("{anon_lts}, ") };

diag.subdiagnostic(
diag.dcx,
IndicateAnonymousLifetime { span: insertion_span.shrink_to_hi(), count: n, suggestion },
);
) -> ElidedLifetimeInPathSubdiag {
let expected = ExpectedLifetimeParameter { span: path_span, count: n };
// Do not try to suggest anything if generated by a proc-macro.
let indicate = source_map.is_span_accessible(insertion_span).then(|| {
let anon_lts = vec!["'_"; n].join(", ");
let suggestion =
if incl_angl_brckt { format!("<{anon_lts}>") } else { format!("{anon_lts}, ") };

IndicateAnonymousLifetime { span: insertion_span.shrink_to_hi(), count: n, suggestion }
});

ElidedLifetimeInPathSubdiag { expected, indicate }
}

pub fn report_ambiguity_error<'a, G: EmissionGuarantee>(
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_typeck/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ impl Subdiagnostic for TypeMismatchFruTypo {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
_f: F,
_f: &F,
) {
diag.arg("expr", self.expr.as_deref().unwrap_or("NONE"));

Expand Down Expand Up @@ -370,7 +370,7 @@ impl Subdiagnostic for RemoveSemiForCoerce {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
_f: F,
_f: &F,
) {
let mut multispan: MultiSpan = self.semi.into();
multispan.push_span_label(self.expr, fluent::hir_typeck_remove_semi_for_coerce_expr);
Expand Down Expand Up @@ -546,7 +546,7 @@ impl rustc_errors::Subdiagnostic for CastUnknownPointerSub {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
f: F,
f: &F,
) {
match self {
CastUnknownPointerSub::To(span) => {
Expand Down
18 changes: 9 additions & 9 deletions compiler/rustc_infer/src/errors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ impl Subdiagnostic for RegionOriginNote<'_> {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
_f: F,
_f: &F,
) {
let mut label_or_note = |span, msg: DiagMessage| {
let sub_count = diag.children.iter().filter(|d| d.span.is_dummy()).count();
Expand Down Expand Up @@ -304,7 +304,7 @@ impl Subdiagnostic for LifetimeMismatchLabels {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
_f: F,
_f: &F,
) {
match self {
LifetimeMismatchLabels::InRet { param_span, ret_span, span, label_var1 } => {
Expand Down Expand Up @@ -352,7 +352,7 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
_f: F,
_f: &F,
) {
let mut mk_suggestion = || {
let (
Expand Down Expand Up @@ -454,7 +454,7 @@ impl Subdiagnostic for IntroducesStaticBecauseUnmetLifetimeReq {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
mut self,
diag: &mut Diag<'_, G>,
_f: F,
_f: &F,
) {
self.unmet_requirements
.push_span_label(self.binding_span, fluent::infer_msl_introduces_static);
Expand Down Expand Up @@ -773,7 +773,7 @@ impl Subdiagnostic for ConsiderBorrowingParamHelp {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
f: F,
f: &F,
) {
let mut type_param_span: MultiSpan = self.spans.clone().into();
for &span in &self.spans {
Expand Down Expand Up @@ -818,7 +818,7 @@ impl Subdiagnostic for DynTraitConstraintSuggestion {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
f: F,
f: &F,
) {
let mut multi_span: MultiSpan = vec![self.span].into();
multi_span.push_span_label(self.span, fluent::infer_dtcs_has_lifetime_req_label);
Expand Down Expand Up @@ -865,7 +865,7 @@ impl Subdiagnostic for ReqIntroducedLocations {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
mut self,
diag: &mut Diag<'_, G>,
f: F,
f: &F,
) {
for sp in self.spans {
self.span.push_span_label(sp, fluent::infer_ril_introduced_here);
Expand All @@ -888,7 +888,7 @@ impl Subdiagnostic for MoreTargeted {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
_f: F,
_f: &F,
) {
diag.code(E0772);
diag.primary_message(fluent::infer_more_targeted);
Expand Down Expand Up @@ -1293,7 +1293,7 @@ impl Subdiagnostic for SuggestTuplePatternMany {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
f: F,
f: &F,
) {
diag.arg("path", self.path);
let message = f(diag, crate::fluent_generated::infer_stp_wrap_many.into());
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/errors/note_and_explain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ impl Subdiagnostic for RegionExplanation<'_> {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
f: F,
f: &F,
) {
diag.arg("pref_kind", self.prefix);
diag.arg("suff_kind", self.suffix);
Expand Down
18 changes: 10 additions & 8 deletions compiler/rustc_lint/src/context/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#![allow(rustc::untranslatable_diagnostic)]

use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
use rustc_errors::{add_elided_lifetime_in_path_suggestion, Diag};
use rustc_errors::{elided_lifetime_in_path_suggestion, Diag};
use rustc_errors::{Applicability, SuggestionStyle};
use rustc_middle::middle::stability;
use rustc_session::lint::BuiltinLintDiag;
Expand Down Expand Up @@ -74,13 +74,15 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di
diag.span_note(span_def, "the macro is defined here");
}
BuiltinLintDiag::ElidedLifetimesInPaths(n, path_span, incl_angl_brckt, insertion_span) => {
add_elided_lifetime_in_path_suggestion(
sess.source_map(),
diag,
n,
path_span,
incl_angl_brckt,
insertion_span,
diag.subdiagnostic(
sess.dcx(),
elided_lifetime_in_path_suggestion(
sess.source_map(),
n,
path_span,
incl_angl_brckt,
insertion_span,
),
);
}
BuiltinLintDiag::UnknownCrateTypes(span, note, sugg) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl Subdiagnostic for OverruledAttributeSub {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
_f: F,
_f: &F,
) {
match self {
OverruledAttributeSub::DefaultSource { id } => {
Expand Down
Loading
Loading