From 9c591c65086679d22639504d7d0c0623564cfd7a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 20 Mar 2026 00:40:47 +0100 Subject: [PATCH] Start migrating `DecorateDiagCompat::Builtin` items to `DecorateDiagCompat::Dynamic` --- compiler/rustc_errors/src/decorate_diag.rs | 21 ++++++++++++++++++++ compiler/rustc_errors/src/lib.rs | 2 +- compiler/rustc_lint/src/early/diagnostics.rs | 7 ------- compiler/rustc_lint/src/lints.rs | 18 ----------------- compiler/rustc_lint_defs/src/lib.rs | 1 - compiler/rustc_parse/src/errors.rs | 18 +++++++++++++++++ compiler/rustc_parse/src/parser/expr.rs | 14 ++++++++++--- 7 files changed, 51 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_errors/src/decorate_diag.rs b/compiler/rustc_errors/src/decorate_diag.rs index a11082e29663..bfdebafeaf5c 100644 --- a/compiler/rustc_errors/src/decorate_diag.rs +++ b/compiler/rustc_errors/src/decorate_diag.rs @@ -14,6 +14,18 @@ pub enum DecorateDiagCompat { Builtin(BuiltinLintDiag), } +pub struct DynamicDiag< + F: for<'a> FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + 'static, +>(Box); + +impl FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + 'static> + DynamicDiag +{ + pub fn new(f: F) -> Self { + Self(Box::new(f)) + } +} + impl std::fmt::Debug for DecorateDiagCompat { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("DecorateDiagCompat").finish() @@ -34,6 +46,15 @@ fn from(b: BuiltinLintDiag) -> Self { } } +impl FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + 'static> + From> for DecorateDiagCompat +{ + #[inline] + fn from(d: DynamicDiag) -> Self { + Self::Dynamic(d.0) + } +} + /// Lints that are buffered up early on in the `Session` before the /// `LintLevels` is calculated. #[derive(Debug)] diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 8c57544c54b8..45cab3802a7e 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -34,7 +34,7 @@ Ansi256Color, AnsiColor, Color, EffectIter, Effects, Reset, RgbColor, Style as Anstyle, }; pub use codes::*; -pub use decorate_diag::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer}; +pub use decorate_diag::{BufferedEarlyLint, DecorateDiagCompat, DynamicDiag, LintBuffer}; pub use diagnostic::{ BugAbort, Diag, DiagDecorator, DiagInner, DiagLocation, DiagStyledString, Diagnostic, EmissionGuarantee, FatalAbort, StringPart, Subdiag, Subdiagnostic, diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index c282eb34cf4d..54e18dd32207 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -170,13 +170,6 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { lints::ReservedMultihash { suggestion }.into_diag(dcx, level) } } - BuiltinLintDiag::BreakWithLabelAndLoop(sugg_span) => lints::BreakWithLabelAndLoop { - sub: lints::BreakWithLabelAndLoopSub { - left: sugg_span.shrink_to_lo(), - right: sugg_span.shrink_to_hi(), - }, - } - .into_diag(dcx, level), BuiltinLintDiag::DeprecatedWhereclauseLocation(left_sp, sugg) => { let suggestion = match sugg { Some((right_sp, sugg)) => lints::DeprecatedWhereClauseLocationSugg::MoveToEnd { diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 02448035216e..2d1a8fae1d40 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -3220,24 +3220,6 @@ pub(crate) struct RawPrefix { pub suggestion: Span, } -#[derive(Diagnostic)] -#[diag( - "this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression" -)] -pub(crate) struct BreakWithLabelAndLoop { - #[subdiagnostic] - pub sub: BreakWithLabelAndLoopSub, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion("wrap this expression in parentheses", applicability = "machine-applicable")] -pub(crate) struct BreakWithLabelAndLoopSub { - #[suggestion_part(code = "(")] - pub left: Span, - #[suggestion_part(code = ")")] - pub right: Span, -} - #[derive(Diagnostic)] #[diag("where clause not allowed here")] #[note("see issue #89122 for more information")] diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index ef7067b25baa..2ac75f9dd94c 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -686,7 +686,6 @@ pub enum BuiltinLintDiag { is_string: bool, suggestion: Span, }, - BreakWithLabelAndLoop(Span), UnicodeTextFlow(Span, String), DeprecatedWhereclauseLocation(Span, Option<(Span, String)>), SingleUseLifetime { diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index f4f718292205..45dc29d059ba 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -4499,3 +4499,21 @@ pub(super) fn from_token(token: &Token) -> Option { } } } + +#[derive(Diagnostic)] +#[diag( + "this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression" +)] +pub(crate) struct BreakWithLabelAndLoop { + #[subdiagnostic] + pub sub: BreakWithLabelAndLoopSub, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("wrap this expression in parentheses", applicability = "machine-applicable")] +pub(crate) struct BreakWithLabelAndLoopSub { + #[suggestion_part(code = "(")] + pub left: Span, + #[suggestion_part(code = ")")] + pub right: Span, +} diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index adfc68f4bb22..923effc239d2 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -19,10 +19,9 @@ StmtKind, Ty, TyKind, UnOp, UnsafeBinderCastKind, YieldKind, }; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_errors::{Applicability, Diag, PResult, StashKey, Subdiagnostic}; +use rustc_errors::{Applicability, Diag, Diagnostic, PResult, StashKey, Subdiagnostic}; use rustc_literal_escaper::unescape_char; use rustc_session::errors::{ExprParenthesesNeeded, report_lit_error}; -use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP; use rustc_span::edition::Edition; use rustc_span::{BytePos, ErrorGuaranteed, Ident, Pos, Span, Spanned, Symbol, kw, respan, sym}; @@ -1921,11 +1920,20 @@ fn parse_expr_break(&mut self) -> PResult<'a, Box> { _ => false, } { + let span = expr.span; self.psess.buffer_lint( BREAK_WITH_LABEL_AND_LOOP, lo.to(expr.span), ast::CRATE_NODE_ID, - BuiltinLintDiag::BreakWithLabelAndLoop(expr.span), + rustc_errors::DynamicDiag::new(move |dcx, level| { + errors::BreakWithLabelAndLoop { + sub: errors::BreakWithLabelAndLoopSub { + left: span.shrink_to_lo(), + right: span.shrink_to_hi(), + }, + } + .into_diag(dcx, level) + }), ); }