Skip to content

Commit 683c582

Browse files
committed
Auto merge of #96468 - davidtwco:diagnostic-translation-subdiagnostic, r=oli-obk
macros: subdiagnostic derive Add a new macro, `#[derive(SessionSubdiagnostic)]`, which can be applied to structs that represent subdiagnostics, such as labels, notes, helps or suggestions. `#[derive(SessionSubdiagnostic)]` can be used with the existing `#[derive(SessionDiagnostic)]`. All diagnostics implemented using either derive are translatable, and this new derive should make it easier to port existing diagnostics to using these derives. For example, consider the following subdiagnostic types... ```rust #[derive(SessionSubdiagnostic)] pub enum ExpectedIdentifierLabel<'tcx> { #[label(slug = "parser-expected-identifier")] WithoutFound { #[primary_span] span: Span, } #[label(slug = "parser-expected-identifier-found")] WithFound { #[primary_span] span: Span, found: String, } } #[derive(SessionSubdiagnostic)] #[suggestion_verbose(slug = "parser-raw-identifier")] pub struct RawIdentifierSuggestion<'tcx> { #[primary_span] span: Span, #[applicability] applicability: Applicability, ident: Ident, } ``` ...and the corresponding Fluent messages: ```fluent parser-expected-identifier = expected identifier parser-expected-identifier-found = expected identifier, found {$found} parser-raw-identifier = escape `{$ident}` to use it as an identifier ``` These can be emitted using the new `subdiagnostic` function on `Diagnostic`... ```rust diag.subdiagnostic(ExpectedIdentifierLabel::WithoutFound { span }); diag.subdiagnostic(RawIdentifierSuggestion { span, applicability, ident }); ``` ...or as part of a larger `#[derive(SessionDiagnostic)]`: ```rust #[derive(SessionDiagnostic)] #[error(slug = "parser-expected-identifier")] pub struct ExpectedIdentifier { #[primary_span] span: Span, token_descr: String, #[subdiagnostic] label: ExpectedIdentifierLabel, #[subdiagnostic] raw_identifier_suggestion: Option<RawIdentifierSuggestion>, } ``` ```rust sess.emit_err(ExpectedIdentifier { ... }); ``` r? `@oli-obk` cc `@pvdrz`
2 parents 87937d3 + dca8861 commit 683c582

File tree

32 files changed

+2758
-1105
lines changed

32 files changed

+2758
-1105
lines changed

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
237237
err.span_suggestion_verbose(
238238
span,
239239
"consider changing this to be mutable",
240-
" mut ".into(),
240+
" mut ",
241241
Applicability::MaybeIncorrect,
242242
);
243243
}

compiler/rustc_builtin_macros/src/deriving/default.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ fn validate_default_attribute(
235235
.span_suggestion_hidden(
236236
attr.span,
237237
"try using `#[default]`",
238-
"#[default]".into(),
238+
"#[default]",
239239
Applicability::MaybeIncorrect,
240240
)
241241
.emit();

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

+8
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,11 @@ typeck-value-of-associated-struct-already-specified =
8282
8383
typeck-address-of-temporary-taken = cannot take address of a temporary
8484
.label = temporary value
85+
86+
typeck-add-return-type-add = try adding a return type
87+
88+
typeck-add-return-type-missing-here = a return type might be missing here
89+
90+
typeck-expected-default-return-type = expected `()` because of default return type
91+
92+
typeck-expected-return-type = expected `{$expected}` because of return type

compiler/rustc_errors/src/diagnostic.rs

+21-7
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,13 @@ impl<'source> Into<FluentValue<'source>> for DiagnosticArgValue<'source> {
7878
}
7979
}
8080

81+
/// Trait implemented by error types. This should not be implemented manually. Instead, use
82+
/// `#[derive(SessionSubdiagnostic)]` -- see [rustc_macros::SessionSubdiagnostic].
83+
pub trait AddSubdiagnostic {
84+
/// Add a subdiagnostic to an existing diagnostic.
85+
fn add_to_diagnostic(self, diag: &mut Diagnostic);
86+
}
87+
8188
#[must_use]
8289
#[derive(Clone, Debug, Encodable, Decodable)]
8390
pub struct Diagnostic {
@@ -605,7 +612,7 @@ impl Diagnostic {
605612
&mut self,
606613
sp: Span,
607614
msg: impl Into<DiagnosticMessage>,
608-
suggestion: String,
615+
suggestion: impl ToString,
609616
applicability: Applicability,
610617
) -> &mut Self {
611618
self.span_suggestion_with_style(
@@ -623,13 +630,13 @@ impl Diagnostic {
623630
&mut self,
624631
sp: Span,
625632
msg: impl Into<DiagnosticMessage>,
626-
suggestion: String,
633+
suggestion: impl ToString,
627634
applicability: Applicability,
628635
style: SuggestionStyle,
629636
) -> &mut Self {
630637
self.push_suggestion(CodeSuggestion {
631638
substitutions: vec![Substitution {
632-
parts: vec![SubstitutionPart { snippet: suggestion, span: sp }],
639+
parts: vec![SubstitutionPart { snippet: suggestion.to_string(), span: sp }],
633640
}],
634641
msg: msg.into(),
635642
style,
@@ -643,7 +650,7 @@ impl Diagnostic {
643650
&mut self,
644651
sp: Span,
645652
msg: impl Into<DiagnosticMessage>,
646-
suggestion: String,
653+
suggestion: impl ToString,
647654
applicability: Applicability,
648655
) -> &mut Self {
649656
self.span_suggestion_with_style(
@@ -711,7 +718,7 @@ impl Diagnostic {
711718
&mut self,
712719
sp: Span,
713720
msg: impl Into<DiagnosticMessage>,
714-
suggestion: String,
721+
suggestion: impl ToString,
715722
applicability: Applicability,
716723
) -> &mut Self {
717724
self.span_suggestion_with_style(
@@ -734,7 +741,7 @@ impl Diagnostic {
734741
&mut self,
735742
sp: Span,
736743
msg: impl Into<DiagnosticMessage>,
737-
suggestion: String,
744+
suggestion: impl ToString,
738745
applicability: Applicability,
739746
) -> &mut Self {
740747
self.span_suggestion_with_style(
@@ -755,7 +762,7 @@ impl Diagnostic {
755762
&mut self,
756763
sp: Span,
757764
msg: impl Into<DiagnosticMessage>,
758-
suggestion: String,
765+
suggestion: impl ToString,
759766
applicability: Applicability,
760767
) -> &mut Self {
761768
self.span_suggestion_with_style(
@@ -768,6 +775,13 @@ impl Diagnostic {
768775
self
769776
}
770777

778+
/// Add a subdiagnostic from a type that implements `SessionSubdiagnostic` - see
779+
/// [rustc_macros::SessionSubdiagnostic].
780+
pub fn subdiagnostic(&mut self, subdiagnostic: impl AddSubdiagnostic) -> &mut Self {
781+
subdiagnostic.add_to_diagnostic(self);
782+
self
783+
}
784+
771785
pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self {
772786
self.span = sp.into();
773787
if let Some(span) = self.span.primary_span() {

compiler/rustc_errors/src/diagnostic_builder.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
477477
&mut self,
478478
sp: Span,
479479
msg: impl Into<DiagnosticMessage>,
480-
suggestion: String,
480+
suggestion: impl ToString,
481481
applicability: Applicability,
482482
) -> &mut Self);
483483
forward!(pub fn span_suggestions(
@@ -497,28 +497,28 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
497497
&mut self,
498498
sp: Span,
499499
msg: impl Into<DiagnosticMessage>,
500-
suggestion: String,
500+
suggestion: impl ToString,
501501
applicability: Applicability,
502502
) -> &mut Self);
503503
forward!(pub fn span_suggestion_verbose(
504504
&mut self,
505505
sp: Span,
506506
msg: impl Into<DiagnosticMessage>,
507-
suggestion: String,
507+
suggestion: impl ToString,
508508
applicability: Applicability,
509509
) -> &mut Self);
510510
forward!(pub fn span_suggestion_hidden(
511511
&mut self,
512512
sp: Span,
513513
msg: impl Into<DiagnosticMessage>,
514-
suggestion: String,
514+
suggestion: impl ToString,
515515
applicability: Applicability,
516516
) -> &mut Self);
517517
forward!(pub fn tool_only_span_suggestion(
518518
&mut self,
519519
sp: Span,
520520
msg: impl Into<DiagnosticMessage>,
521-
suggestion: String,
521+
suggestion: impl ToString,
522522
applicability: Applicability,
523523
) -> &mut Self);
524524

@@ -530,6 +530,11 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
530530
name: impl Into<Cow<'static, str>>,
531531
arg: DiagnosticArgValue<'static>,
532532
) -> &mut Self);
533+
534+
forward!(pub fn subdiagnostic(
535+
&mut self,
536+
subdiagnostic: impl crate::AddSubdiagnostic
537+
) -> &mut Self);
533538
}
534539

535540
impl<G: EmissionGuarantee> Debug for DiagnosticBuilder<'_, G> {

compiler/rustc_errors/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,8 @@ impl fmt::Display for ExplicitBug {
370370
impl error::Error for ExplicitBug {}
371371

372372
pub use diagnostic::{
373-
Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId, DiagnosticStyledString,
374-
IntoDiagnosticArg, SubDiagnostic,
373+
AddSubdiagnostic, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId,
374+
DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
375375
};
376376
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee};
377377
use std::backtrace::Backtrace;

compiler/rustc_expand/src/config.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ pub fn parse_cfg<'a>(meta_item: &'a MetaItem, sess: &Session) -> Option<&'a Meta
511511
err.span_suggestion(
512512
span,
513513
"expected syntax is",
514-
suggestion.into(),
514+
suggestion,
515515
Applicability::HasPlaceholders,
516516
);
517517
}

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2198,7 +2198,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
21982198
err.span_suggestion(
21992199
span.with_hi(before_close).shrink_to_hi(),
22002200
msg,
2201-
",".into(),
2201+
",",
22022202
Applicability::MachineApplicable,
22032203
);
22042204
} else {

compiler/rustc_lint/src/array_into_iter.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
129129
diag.span_suggestion(
130130
call.ident.span,
131131
"use `.iter()` instead of `.into_iter()` to avoid ambiguity",
132-
"iter".into(),
132+
"iter",
133133
Applicability::MachineApplicable,
134134
);
135135
if self.for_expr_span == expr.span {

compiler/rustc_lint/src/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ pub trait LintContext: Sized {
738738
db.span_suggestion_verbose(
739739
span.shrink_to_hi(),
740740
"insert whitespace here to avoid this being parsed as a prefix in Rust 2021",
741-
" ".into(),
741+
" ",
742742
Applicability::MachineApplicable,
743743
);
744744
}

compiler/rustc_lint/src/non_fmt_panic.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
176176
l.span_suggestion_verbose(
177177
arg_span.shrink_to_lo(),
178178
"add a \"{}\" format string to Display the message",
179-
"\"{}\", ".into(),
179+
"\"{}\", ",
180180
fmt_applicability,
181181
);
182182
} else if suggest_debug {
@@ -186,7 +186,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
186186
"add a \"{{:?}}\" format string to use the Debug implementation of `{}`",
187187
ty,
188188
),
189-
"\"{:?}\", ".into(),
189+
"\"{:?}\", ",
190190
fmt_applicability,
191191
);
192192
}
@@ -266,13 +266,13 @@ fn check_panic_str<'tcx>(
266266
l.span_suggestion(
267267
arg.span.shrink_to_hi(),
268268
&format!("add the missing argument{}", pluralize!(n_arguments)),
269-
", ...".into(),
269+
", ...",
270270
Applicability::HasPlaceholders,
271271
);
272272
l.span_suggestion(
273273
arg.span.shrink_to_lo(),
274274
"or add a \"{}\" format string to use the message literally",
275-
"\"{}\", ".into(),
275+
"\"{}\", ",
276276
Applicability::MachineApplicable,
277277
);
278278
}
@@ -297,7 +297,7 @@ fn check_panic_str<'tcx>(
297297
l.span_suggestion(
298298
arg.span.shrink_to_lo(),
299299
"add a \"{}\" format string to use the message literally",
300-
"\"{}\", ".into(),
300+
"\"{}\", ",
301301
Applicability::MachineApplicable,
302302
);
303303
}

0 commit comments

Comments
 (0)