Skip to content

Commit ca6097f

Browse files
authored
Rollup merge of rust-lang#103051 - davidtwco:translation-tidying-up, r=compiler-errors
translation: doc comments with derives, subdiagnostic-less enum variants, more derive use - Adds support for `doc` attributes in the diagnostic derives so that documentation comments don't result in the derive failing. - Adds support for enum variants in the subdiagnostic derive to not actually correspond to an addition to a diagnostic. - Made use of the derive in more places in the `rustc_ast_lowering`, `rustc_ast_passes`, `rustc_lint`, `rustc_session`, `rustc_infer` - taking advantage of recent additions like eager subdiagnostics, multispan suggestions, etc. cc rust-lang#100717
2 parents 483a78d + 913f597 commit ca6097f

File tree

17 files changed

+286
-238
lines changed

17 files changed

+286
-238
lines changed

compiler/rustc_ast_lowering/src/errors.rs

+18-41
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
use rustc_errors::{
2-
fluent, AddToDiagnostic, Applicability, Diagnostic, DiagnosticArgFromDisplay,
3-
SubdiagnosticMessage,
4-
};
1+
use rustc_errors::DiagnosticArgFromDisplay;
52
use rustc_macros::{Diagnostic, Subdiagnostic};
63
use rustc_span::{symbol::Ident, Span, Symbol};
74

@@ -15,25 +12,15 @@ pub struct GenericTypeWithParentheses {
1512
pub sub: Option<UseAngleBrackets>,
1613
}
1714

18-
#[derive(Clone, Copy)]
15+
#[derive(Clone, Copy, Subdiagnostic)]
16+
#[multipart_suggestion(ast_lowering::use_angle_brackets, applicability = "maybe-incorrect")]
1917
pub struct UseAngleBrackets {
18+
#[suggestion_part(code = "<")]
2019
pub open_param: Span,
20+
#[suggestion_part(code = ">")]
2121
pub close_param: Span,
2222
}
2323

24-
impl AddToDiagnostic for UseAngleBrackets {
25-
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
26-
where
27-
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
28-
{
29-
diag.multipart_suggestion(
30-
fluent::ast_lowering::use_angle_brackets,
31-
vec![(self.open_param, String::from("<")), (self.close_param, String::from(">"))],
32-
Applicability::MaybeIncorrect,
33-
);
34-
}
35-
}
36-
3724
#[derive(Diagnostic)]
3825
#[diag(ast_lowering::invalid_abi, code = "E0703")]
3926
#[note]
@@ -68,30 +55,20 @@ pub struct AssocTyParentheses {
6855
pub sub: AssocTyParenthesesSub,
6956
}
7057

71-
#[derive(Clone, Copy)]
58+
#[derive(Clone, Copy, Subdiagnostic)]
7259
pub enum AssocTyParenthesesSub {
73-
Empty { parentheses_span: Span },
74-
NotEmpty { open_param: Span, close_param: Span },
75-
}
76-
77-
impl AddToDiagnostic for AssocTyParenthesesSub {
78-
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
79-
where
80-
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
81-
{
82-
match self {
83-
Self::Empty { parentheses_span } => diag.multipart_suggestion(
84-
fluent::ast_lowering::remove_parentheses,
85-
vec![(parentheses_span, String::new())],
86-
Applicability::MaybeIncorrect,
87-
),
88-
Self::NotEmpty { open_param, close_param } => diag.multipart_suggestion(
89-
fluent::ast_lowering::use_angle_brackets,
90-
vec![(open_param, String::from("<")), (close_param, String::from(">"))],
91-
Applicability::MaybeIncorrect,
92-
),
93-
};
94-
}
60+
#[multipart_suggestion(ast_lowering::remove_parentheses)]
61+
Empty {
62+
#[suggestion_part(code = "")]
63+
parentheses_span: Span,
64+
},
65+
#[multipart_suggestion(ast_lowering::use_angle_brackets)]
66+
NotEmpty {
67+
#[suggestion_part(code = "<")]
68+
open_param: Span,
69+
#[suggestion_part(code = ">")]
70+
close_param: Span,
71+
},
9572
}
9673

9774
#[derive(Diagnostic)]

compiler/rustc_ast_passes/src/ast_validation.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc_ast::*;
1414
use rustc_ast_pretty::pprust::{self, State};
1515
use rustc_data_structures::fx::FxHashMap;
1616
use rustc_errors::{error_code, fluent, pluralize, struct_span_err, Applicability};
17+
use rustc_macros::Subdiagnostic;
1718
use rustc_parse::validate_attr;
1819
use rustc_session::lint::builtin::{
1920
DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY,
@@ -1782,15 +1783,17 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) ->
17821783
}
17831784

17841785
/// Used to forbid `let` expressions in certain syntactic locations.
1785-
#[derive(Clone, Copy)]
1786+
#[derive(Clone, Copy, Subdiagnostic)]
17861787
pub(crate) enum ForbiddenLetReason {
17871788
/// `let` is not valid and the source environment is not important
17881789
GenericForbidden,
17891790
/// A let chain with the `||` operator
1790-
NotSupportedOr(Span),
1791+
#[note(ast_passes::not_supported_or)]
1792+
NotSupportedOr(#[primary_span] Span),
17911793
/// A let chain with invalid parentheses
17921794
///
17931795
/// For example, `let 1 = 1 && (expr && expr)` is allowed
17941796
/// but `(let 1 = 1 && (let 1 = 1 && (let 1 = 1))) && let a = 1` is not
1795-
NotSupportedParentheses(Span),
1797+
#[note(ast_passes::not_supported_parentheses)]
1798+
NotSupportedParentheses(#[primary_span] Span),
17961799
}

compiler/rustc_ast_passes/src/errors.rs

-17
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,6 @@ pub struct ForbiddenLet {
1616
pub(crate) reason: ForbiddenLetReason,
1717
}
1818

19-
impl AddToDiagnostic for ForbiddenLetReason {
20-
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
21-
where
22-
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
23-
{
24-
match self {
25-
Self::GenericForbidden => {}
26-
Self::NotSupportedOr(span) => {
27-
diag.span_note(span, fluent::ast_passes::not_supported_or);
28-
}
29-
Self::NotSupportedParentheses(span) => {
30-
diag.span_note(span, fluent::ast_passes::not_supported_parentheses);
31-
}
32-
}
33-
}
34-
}
35-
3619
#[derive(Diagnostic)]
3720
#[diag(ast_passes::forbidden_let_stable)]
3821
#[note]

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,9 @@ infer_region_explanation = {$pref_kind ->
164164
}
165165
166166
infer_mismatched_static_lifetime = incompatible lifetime on type
167-
infer_msl_impl_note = ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
167+
infer_does_not_outlive_static_from_impl = ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
168+
infer_implicit_static_lifetime_note = this has an implicit `'static` lifetime requirement
169+
infer_implicit_static_lifetime_suggestion = consider relaxing the implicit `'static` requirement
168170
infer_msl_introduces_static = introduces a `'static` lifetime requirement
169171
infer_msl_unmet_req = because this has an unmet lifetime requirement
170172
infer_msl_trait_note = this has an implicit `'static` lifetime requirement

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

+4
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,7 @@ session_crate_name_empty = crate name must not be empty
5454
session_invalid_character_in_create_name = invalid character `{$character}` in crate name: `{$crate_name}`
5555
5656
session_expr_parentheses_needed = parentheses are required to parse this as an expression
57+
58+
session_skipping_const_checks = skipping const checks
59+
session_unleashed_feature_help_named = skipping check for `{$gate}` feature
60+
session_unleashed_feature_help_unnamed = skipping check that does not even have a feature gate

compiler/rustc_errors/src/diagnostic_impls.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
use crate::{
22
fluent, DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg,
33
};
4-
use rustc_target::abi::TargetDataLayoutErrors;
5-
use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
6-
74
use rustc_ast as ast;
85
use rustc_ast_pretty::pprust;
96
use rustc_hir as hir;
7+
use rustc_lint_defs::Level;
108
use rustc_span::edition::Edition;
119
use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol};
10+
use rustc_target::abi::TargetDataLayoutErrors;
11+
use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
1212
use std::borrow::Cow;
1313
use std::fmt;
1414
use std::num::ParseIntError;
@@ -155,6 +155,21 @@ impl IntoDiagnosticArg for ast::token::TokenKind {
155155
}
156156
}
157157

158+
impl IntoDiagnosticArg for Level {
159+
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
160+
DiagnosticArgValue::Str(Cow::Borrowed(match self {
161+
Level::Allow => "-A",
162+
Level::Warn => "-W",
163+
Level::ForceWarn(_) => "--force-warn",
164+
Level::Deny => "-D",
165+
Level::Forbid => "-F",
166+
Level::Expect(_) => {
167+
unreachable!("lints with the level of `expect` should not run this code");
168+
}
169+
}))
170+
}
171+
}
172+
158173
impl IntoDiagnostic<'_, !> for TargetDataLayoutErrors<'_> {
159174
fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, !> {
160175
let mut diag;

compiler/rustc_infer/src/errors/mod.rs

+29-42
Original file line numberDiff line numberDiff line change
@@ -459,47 +459,34 @@ impl AddToDiagnostic for IntroducesStaticBecauseUnmetLifetimeReq {
459459
}
460460
}
461461

462-
pub struct ImplNote {
463-
pub impl_span: Option<Span>,
464-
}
465-
466-
impl AddToDiagnostic for ImplNote {
467-
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
468-
where
469-
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
470-
{
471-
match self.impl_span {
472-
Some(span) => diag.span_note(span, fluent::infer::msl_impl_note),
473-
None => diag.note(fluent::infer::msl_impl_note),
474-
};
475-
}
476-
}
477-
478-
pub enum TraitSubdiag {
479-
Note { span: Span },
480-
Sugg { span: Span },
462+
// FIXME(#100717): replace with a `Option<Span>` when subdiagnostic supports that
463+
#[derive(Subdiagnostic)]
464+
pub enum DoesNotOutliveStaticFromImpl {
465+
#[note(infer::does_not_outlive_static_from_impl)]
466+
Spanned {
467+
#[primary_span]
468+
span: Span,
469+
},
470+
#[note(infer::does_not_outlive_static_from_impl)]
471+
Unspanned,
481472
}
482473

483-
// FIXME(#100717) used in `Vec<TraitSubdiag>` so requires eager translation/list support
484-
impl AddToDiagnostic for TraitSubdiag {
485-
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
486-
where
487-
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
488-
{
489-
match self {
490-
TraitSubdiag::Note { span } => {
491-
diag.span_note(span, "this has an implicit `'static` lifetime requirement");
492-
}
493-
TraitSubdiag::Sugg { span } => {
494-
diag.span_suggestion_verbose(
495-
span,
496-
"consider relaxing the implicit `'static` requirement",
497-
" + '_".to_owned(),
498-
rustc_errors::Applicability::MaybeIncorrect,
499-
);
500-
}
501-
}
502-
}
474+
#[derive(Subdiagnostic)]
475+
pub enum ImplicitStaticLifetimeSubdiag {
476+
#[note(infer::implicit_static_lifetime_note)]
477+
Note {
478+
#[primary_span]
479+
span: Span,
480+
},
481+
#[suggestion_verbose(
482+
infer::implicit_static_lifetime_suggestion,
483+
code = " + '_",
484+
applicability = "maybe-incorrect"
485+
)]
486+
Sugg {
487+
#[primary_span]
488+
span: Span,
489+
},
503490
}
504491

505492
#[derive(Diagnostic)]
@@ -512,7 +499,7 @@ pub struct MismatchedStaticLifetime<'a> {
512499
#[subdiagnostic]
513500
pub expl: Option<note_and_explain::RegionExplanation<'a>>,
514501
#[subdiagnostic]
515-
pub impl_note: ImplNote,
516-
#[subdiagnostic]
517-
pub trait_subdiags: Vec<TraitSubdiag>,
502+
pub does_not_outlive_static_from_impl: DoesNotOutliveStaticFromImpl,
503+
#[subdiagnostic(eager)]
504+
pub implicit_static_lifetimes: Vec<ImplicitStaticLifetimeSubdiag>,
518505
}

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
//! to hold.
33
44
use crate::errors::{note_and_explain, IntroducesStaticBecauseUnmetLifetimeReq};
5-
use crate::errors::{ImplNote, MismatchedStaticLifetime, TraitSubdiag};
5+
use crate::errors::{
6+
DoesNotOutliveStaticFromImpl, ImplicitStaticLifetimeSubdiag, MismatchedStaticLifetime,
7+
};
68
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
79
use crate::infer::lexical_region_resolve::RegionResolutionError;
810
use crate::infer::{SubregionOrigin, TypeTrace};
@@ -56,7 +58,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
5658
note_and_explain::SuffixKind::Continues,
5759
);
5860
let mut impl_span = None;
59-
let mut trait_subdiags = Vec::new();
61+
let mut implicit_static_lifetimes = Vec::new();
6062
if let Some(impl_node) = self.tcx().hir().get_if_local(*impl_def_id) {
6163
// If an impl is local, then maybe this isn't what they want. Try to
6264
// be as helpful as possible with implicit lifetimes.
@@ -90,10 +92,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
9092
// Otherwise, point at all implicit static lifetimes
9193

9294
for span in &traits {
93-
trait_subdiags.push(TraitSubdiag::Note { span: *span });
95+
implicit_static_lifetimes
96+
.push(ImplicitStaticLifetimeSubdiag::Note { span: *span });
9497
// It would be nice to put this immediately under the above note, but they get
9598
// pushed to the end.
96-
trait_subdiags.push(TraitSubdiag::Sugg { span: span.shrink_to_hi() });
99+
implicit_static_lifetimes
100+
.push(ImplicitStaticLifetimeSubdiag::Sugg { span: span.shrink_to_hi() });
97101
}
98102
}
99103
} else {
@@ -105,8 +109,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
105109
cause_span: cause.span,
106110
unmet_lifetime_reqs: multispan_subdiag,
107111
expl,
108-
impl_note: ImplNote { impl_span },
109-
trait_subdiags,
112+
does_not_outlive_static_from_impl: impl_span
113+
.map(|span| DoesNotOutliveStaticFromImpl::Spanned { span })
114+
.unwrap_or(DoesNotOutliveStaticFromImpl::Unspanned),
115+
implicit_static_lifetimes,
110116
};
111117
let reported = self.tcx().sess.emit_err(err);
112118
Some(reported)

compiler/rustc_lint/src/errors.rs

+2-23
Original file line numberDiff line numberDiff line change
@@ -88,34 +88,13 @@ pub struct BuiltinEllpisisInclusiveRangePatterns {
8888
pub replace: String,
8989
}
9090

91+
#[derive(Subdiagnostic)]
92+
#[note(lint::requested_level)]
9193
pub struct RequestedLevel {
9294
pub level: Level,
9395
pub lint_name: String,
9496
}
9597

96-
impl AddToDiagnostic for RequestedLevel {
97-
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
98-
where
99-
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
100-
{
101-
diag.note(fluent::lint::requested_level);
102-
diag.set_arg(
103-
"level",
104-
match self.level {
105-
Level::Allow => "-A",
106-
Level::Warn => "-W",
107-
Level::ForceWarn(_) => "--force-warn",
108-
Level::Deny => "-D",
109-
Level::Forbid => "-F",
110-
Level::Expect(_) => {
111-
unreachable!("lints with the level of `expect` should not run this code");
112-
}
113-
},
114-
);
115-
diag.set_arg("lint_name", self.lint_name);
116-
}
117-
}
118-
11998
#[derive(Diagnostic)]
12099
#[diag(lint::unsupported_group, code = "E0602")]
121100
pub struct UnsupportedGroup {

0 commit comments

Comments
 (0)