From 22b4a8cb86b4210da38cdec82b0c1382f09a7b39 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 26 Feb 2026 21:37:48 +0100 Subject: [PATCH] Update `decorate_builtin_lint` to use `Diagnostic` instead of `LintDiagnostic` --- compiler/rustc_hir_analysis/src/lib.rs | 32 +- compiler/rustc_lint/src/early.rs | 35 +- compiler/rustc_lint/src/early/diagnostics.rs | 378 ++++++++++-------- compiler/rustc_lint/src/lib.rs | 2 +- src/librustdoc/lib.rs | 36 +- .../consts/assoc-const-elided-lifetime.stderr | 8 +- .../elided-lifetime.stderr | 8 +- .../generic-associated-const.stderr | 4 +- .../static-trait-impl.stderr | 4 +- 9 files changed, 302 insertions(+), 205 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index a1c8b8421e7c..4c3abe5cd3a0 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -149,20 +149,30 @@ pub fn provide(providers: &mut Providers) { } fn emit_delayed_lint(lint: &DelayedLint, tcx: TyCtxt<'_>) { + struct DiagEmitter<'tcx> { + hir_id: rustc_hir::HirId, + tcx: TyCtxt<'tcx>, + span: Span, + } + + impl rustc_lint::EmitDiag for DiagEmitter<'_> { + fn emit( + &self, + lint: &'static rustc_lint::Lint, + diag: impl for<'a> rustc_errors::Diagnostic<'a, ()>, + ) { + self.tcx.emit_node_span_lint(lint, self.hir_id, self.span, diag); + } + } + match lint { DelayedLint::AttributeParsing(attribute_lint) => { - tcx.node_span_lint( + rustc_lint::decorate_attribute_lint( + &DiagEmitter { hir_id: attribute_lint.id, tcx, span: attribute_lint.span }, + tcx.sess, + Some(tcx), + &attribute_lint.kind, attribute_lint.lint_id.lint, - attribute_lint.id, - attribute_lint.span, - |diag| { - rustc_lint::decorate_attribute_lint( - tcx.sess, - Some(tcx), - &attribute_lint.kind, - diag, - ); - }, ); } } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 1c205035934b..6d87a488373d 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -7,7 +7,7 @@ use rustc_ast::visit::{self as ast_visit, Visitor, walk_list}; use rustc_ast::{self as ast, AttrVec, HasAttrs}; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_errors::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer}; +use rustc_errors::{BufferedEarlyLint, DecorateDiagCompat, Diagnostic, LintBuffer, MultiSpan}; use rustc_feature::Features; use rustc_middle::ty::{RegisteredTools, TyCtxt}; use rustc_session::Session; @@ -15,6 +15,7 @@ use rustc_span::{Ident, Span}; use tracing::debug; +use crate::Lint; use crate::context::{EarlyContext, LintContext, LintStore}; use crate::passes::{EarlyLintPass, EarlyLintPassObject}; @@ -32,16 +33,40 @@ pub struct EarlyContextAndPass<'ecx, 'tcx, T: EarlyLintPass> { pass: T, } +pub trait EmitDiag { + fn emit(&self, lint: &'static Lint, diag: impl for<'a> Diagnostic<'a, ()>); +} + +struct DiagEmitter<'a, 'b> { + ctx: &'a EarlyContext<'b>, + span: Option, +} + +impl EmitDiag for DiagEmitter<'_, '_> { + fn emit(&self, lint: &'static Lint, diag: impl for<'a> Diagnostic<'a, ()>) { + self.ctx.opt_span_diag_lint(lint, self.span.clone(), diag); + } +} + impl<'ecx, 'tcx, T: EarlyLintPass> EarlyContextAndPass<'ecx, 'tcx, T> { fn check_id(&mut self, id: ast::NodeId) { for early_lint in self.context.buffered.take(id) { let BufferedEarlyLint { span, node_id: _, lint_id, diagnostic } = early_lint; - self.context.opt_span_diag_lint(lint_id.lint, span, |diag| match diagnostic { + match diagnostic { DecorateDiagCompat::Builtin(b) => { - diagnostics::decorate_builtin_lint(self.context.sess(), self.tcx, b, diag); + diagnostics::decorate_builtin_lint( + &DiagEmitter { ctx: &self.context, span }, + self.context.sess(), + self.tcx, + b, + lint_id.lint, + ); } - DecorateDiagCompat::Dynamic(d) => d.decorate_lint_box(diag), - }); + DecorateDiagCompat::Dynamic(d) => { + self.context + .opt_span_lint(lint_id.lint, span, |diag| d.decorate_lint_box(diag)); + } + } } } diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index 7f13a7559b49..bc1f51f2b65a 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -1,9 +1,7 @@ use std::borrow::Cow; use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; -use rustc_errors::{ - Applicability, Diag, DiagArgValue, LintDiagnostic, elided_lifetime_in_path_suggestion, -}; +use rustc_errors::{Applicability, DiagArgValue, elided_lifetime_in_path_suggestion}; use rustc_hir::lints::{AttributeLintKind, FormatWarning}; use rustc_middle::middle::stability; use rustc_middle::ty::TyCtxt; @@ -12,15 +10,16 @@ use rustc_span::BytePos; use tracing::debug; -use crate::lints; +use crate::{EmitDiag, Lint, lints}; mod check_cfg; -pub fn decorate_builtin_lint)>( +pub fn decorate_builtin_lint( + ctx: &D, sess: &Session, tcx: Option>, diagnostic: BuiltinLintDiag, - callback: F, + lint: &'static Lint, ) { match diagnostic { BuiltinLintDiag::UnicodeTextFlow(comment_span, content) => { @@ -41,12 +40,15 @@ pub fn decorate_builtin_lint)>( spans: spans.iter().map(|(_c, span)| *span).collect(), }); - callback(lints::UnicodeTextFlow { - comment_span, - characters, - suggestions, - num_codepoints: spans.len(), - }); + ctx.emit( + lint, + lints::UnicodeTextFlow { + comment_span, + characters, + suggestions, + num_codepoints: spans.len(), + }, + ); } BuiltinLintDiag::AbsPathWithModule(mod_span) => { let (replacement, applicability) = match sess.source_map().span_to_snippet(mod_span) { @@ -59,20 +61,30 @@ pub fn decorate_builtin_lint)>( } Err(_) => ("crate::".to_string(), Applicability::HasPlaceholders), }; - callback(lints::AbsPathWithModule { - sugg: lints::AbsPathWithModuleSugg { span: mod_span, applicability, replacement }, - }); + ctx.emit( + lint, + lints::AbsPathWithModule { + sugg: lints::AbsPathWithModuleSugg { + span: mod_span, + applicability, + replacement, + }, + }, + ); } BuiltinLintDiag::ElidedLifetimesInPaths(n, path_span, incl_angl_brckt, insertion_span) => { - callback(lints::ElidedLifetimesInPaths { - subdiag: elided_lifetime_in_path_suggestion( - sess.source_map(), - n, - path_span, - incl_angl_brckt, - insertion_span, - ), - }); + ctx.emit( + lint, + lints::ElidedLifetimesInPaths { + subdiag: elided_lifetime_in_path_suggestion( + sess.source_map(), + n, + path_span, + incl_angl_brckt, + insertion_span, + ), + }, + ); } BuiltinLintDiag::UnusedImports { remove_whole_use, @@ -89,14 +101,17 @@ pub fn decorate_builtin_lint)>( let test_module_span = test_module_span.map(|span| sess.source_map().guess_head_span(span)); - callback(lints::UnusedImports { - sugg, - test_module_span, - num_snippets: span_snippets.len(), - span_snippets: DiagArgValue::StrListSepByAnd( - span_snippets.into_iter().map(Cow::Owned).collect(), - ), - }); + ctx.emit( + lint, + lints::UnusedImports { + sugg, + test_module_span, + num_snippets: span_snippets.len(), + span_snippets: DiagArgValue::StrListSepByAnd( + span_snippets.into_iter().map(Cow::Owned).collect(), + ), + }, + ); } BuiltinLintDiag::RedundantImport(spans, ident) => { let subs = spans @@ -108,7 +123,7 @@ pub fn decorate_builtin_lint)>( (true, false) => lints::RedundantImportSub::DefinedPrelude { span, ident }, }) .collect(); - callback(lints::RedundantImport { subs, ident }); + ctx.emit(lint, lints::RedundantImport { subs, ident }); } BuiltinLintDiag::DeprecatedMacro { suggestion, @@ -123,46 +138,55 @@ pub fn decorate_builtin_lint)>( suggestion, }); - callback(stability::Deprecated { - sub, - kind: "macro".to_owned(), - path, - note, - since_kind, - }); + ctx.emit( + lint, + stability::Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind }, + ); } BuiltinLintDiag::PatternsInFnsWithoutBody { span: remove_span, ident, is_foreign } => { let sub = lints::PatternsInFnsWithoutBodySub { ident, span: remove_span }; - callback(if is_foreign { - lints::PatternsInFnsWithoutBody::Foreign { sub } - } else { - lints::PatternsInFnsWithoutBody::Bodiless { sub } - }); + ctx.emit( + lint, + if is_foreign { + lints::PatternsInFnsWithoutBody::Foreign { sub } + } else { + lints::PatternsInFnsWithoutBody::Bodiless { sub } + }, + ); } BuiltinLintDiag::ReservedPrefix(label_span, prefix) => { - callback(lints::ReservedPrefix { - label: label_span, - suggestion: label_span.shrink_to_hi(), - prefix, - }); + ctx.emit( + lint, + lints::ReservedPrefix { + label: label_span, + suggestion: label_span.shrink_to_hi(), + prefix, + }, + ); } BuiltinLintDiag::RawPrefix(label_span) => { - callback(lints::RawPrefix { label: label_span, suggestion: label_span.shrink_to_hi() }); + ctx.emit( + lint, + lints::RawPrefix { label: label_span, suggestion: label_span.shrink_to_hi() }, + ); } BuiltinLintDiag::ReservedString { is_string, suggestion } => { if is_string { - callback(lints::ReservedString { suggestion }); + ctx.emit(lint, lints::ReservedString { suggestion }); } else { - callback(lints::ReservedMultihash { suggestion }); + ctx.emit(lint, lints::ReservedMultihash { suggestion }); } } BuiltinLintDiag::BreakWithLabelAndLoop(sugg_span) => { - callback(lints::BreakWithLabelAndLoop { - sub: lints::BreakWithLabelAndLoopSub { - left: sugg_span.shrink_to_lo(), - right: sugg_span.shrink_to_hi(), + ctx.emit( + lint, + lints::BreakWithLabelAndLoop { + sub: lints::BreakWithLabelAndLoopSub { + left: sugg_span.shrink_to_lo(), + right: sugg_span.shrink_to_hi(), + }, }, - }); + ); } BuiltinLintDiag::DeprecatedWhereclauseLocation(left_sp, sugg) => { let suggestion = match sugg { @@ -173,7 +197,7 @@ pub fn decorate_builtin_lint)>( }, None => lints::DeprecatedWhereClauseLocationSugg::RemoveWhere { span: left_sp }, }; - callback(lints::DeprecatedWhereClauseLocation { suggestion }); + ctx.emit(lint, lints::DeprecatedWhereClauseLocation { suggestion }); } BuiltinLintDiag::SingleUseLifetime { param_span, @@ -200,10 +224,10 @@ pub fn decorate_builtin_lint)>( None }; - callback(lints::SingleUseLifetime { suggestion, param_span, use_span, ident }); + ctx.emit(lint, lints::SingleUseLifetime { suggestion, param_span, use_span, ident }); } BuiltinLintDiag::SingleUseLifetime { use_span: None, deletion_span, ident, .. } => { - callback(lints::UnusedLifetime { deletion_span, ident }); + ctx.emit(lint, lints::UnusedLifetime { deletion_span, ident }); } BuiltinLintDiag::NamedArgumentUsedPositionally { position_sp_to_replace, @@ -231,13 +255,16 @@ pub fn decorate_builtin_lint)>( (None, String::new()) }; - callback(lints::NamedArgumentUsedPositionally { - named_arg_sp, - position_label_sp: position_sp_for_msg, - suggestion, - name, - named_arg_name, - }); + ctx.emit( + lint, + lints::NamedArgumentUsedPositionally { + named_arg_sp, + position_label_sp: position_sp_for_msg, + suggestion, + name, + named_arg_name, + }, + ); } BuiltinLintDiag::AmbiguousGlobReexports { name, @@ -245,12 +272,15 @@ pub fn decorate_builtin_lint)>( first_reexport_span, duplicate_reexport_span, } => { - callback(lints::AmbiguousGlobReexports { - first_reexport: first_reexport_span, - duplicate_reexport: duplicate_reexport_span, - name, - namespace, - }); + ctx.emit( + lint, + lints::AmbiguousGlobReexports { + first_reexport: first_reexport_span, + duplicate_reexport: duplicate_reexport_span, + name, + namespace, + }, + ); } BuiltinLintDiag::HiddenGlobReexports { name, @@ -258,16 +288,19 @@ pub fn decorate_builtin_lint)>( glob_reexport_span, private_item_span, } => { - callback(lints::HiddenGlobReexports { - glob_reexport: glob_reexport_span, - private_item: private_item_span, + ctx.emit( + lint, + lints::HiddenGlobReexports { + glob_reexport: glob_reexport_span, + private_item: private_item_span, - name, - namespace, - }); + name, + namespace, + }, + ); } BuiltinLintDiag::UnusedQualifications { removal_span } => { - callback(lints::UnusedQualifications { removal_span }); + ctx.emit(lint, lints::UnusedQualifications { removal_span }); } BuiltinLintDiag::AssociatedConstElidedLifetime { elided, @@ -276,57 +309,67 @@ pub fn decorate_builtin_lint)>( } => { let lt_span = if elided { lt_span.shrink_to_hi() } else { lt_span }; let code = if elided { "'static " } else { "'static" }; - callback(lints::AssociatedConstElidedLifetime { - span: lt_span, - code, - elided, - lifetimes_in_scope, - }); + ctx.emit( + lint, + lints::AssociatedConstElidedLifetime { + span: lt_span, + code, + elided, + lifetimes_in_scope, + }, + ); } BuiltinLintDiag::UnreachableCfg { span, wildcard_span } => match wildcard_span { Some(wildcard_span) => { - callback(lints::UnreachableCfgSelectPredicateWildcard { span, wildcard_span }) + ctx.emit(lint, lints::UnreachableCfgSelectPredicateWildcard { span, wildcard_span }) } - None => callback(lints::UnreachableCfgSelectPredicate { span }), + None => ctx.emit(lint, lints::UnreachableCfgSelectPredicate { span }), }, BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => { - callback(lints::UnusedCrateDependency { extern_crate, local_crate }) + ctx.emit(lint, lints::UnusedCrateDependency { extern_crate, local_crate }) + } + BuiltinLintDiag::UnusedVisibility(span) => ctx.emit(lint, lints::UnusedVisibility { span }), + BuiltinLintDiag::AttributeLint(kind) => { + decorate_attribute_lint(ctx, sess, tcx, &kind, lint) } - BuiltinLintDiag::UnusedVisibility(span) => callback(lints::UnusedVisibility { span }), - BuiltinLintDiag::AttributeLint(kind) => decorate_attribute_lint(sess, tcx, &kind, callback), } } -pub fn decorate_attribute_lint)>( +pub fn decorate_attribute_lint( + ctx: &D, sess: &Session, tcx: Option>, kind: &AttributeLintKind, - callback: F, + lint: &'static Lint, ) { match kind { &AttributeLintKind::UnusedDuplicate { this, other, warning } => { - callback(lints::UnusedDuplicate { this, other, warning }) + ctx.emit(lint, lints::UnusedDuplicate { this, other, warning }) } - AttributeLintKind::IllFormedAttributeInput { suggestions, docs } => { - callback(lints::IllFormedAttributeInput { + AttributeLintKind::IllFormedAttributeInput { suggestions, docs } => ctx.emit( + lint, + lints::IllFormedAttributeInput { num_suggestions: suggestions.len(), suggestions: DiagArgValue::StrListSepByAnd( suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(), ), has_docs: docs.is_some(), docs: docs.unwrap_or(""), - }) - } - AttributeLintKind::EmptyAttribute { first_span, attr_path, valid_without_list } => { - callback(lints::EmptyAttributeList { - attr_span: *first_span, - attr_path: attr_path.clone(), - valid_without_list: *valid_without_list, - }) - } - AttributeLintKind::InvalidTarget { name, target, applied, only, attr_span } => { - callback(lints::InvalidTargetLint { + }, + ), + AttributeLintKind::EmptyAttribute { first_span, attr_path, valid_without_list } => ctx + .emit( + lint, + lints::EmptyAttributeList { + attr_span: *first_span, + attr_path: attr_path.clone(), + valid_without_list: *valid_without_list, + }, + ), + AttributeLintKind::InvalidTarget { name, target, applied, only, attr_span } => ctx.emit( + lint, + lints::InvalidTargetLint { name: name.clone(), target, applied: DiagArgValue::StrListSepByAnd( @@ -334,119 +377,124 @@ pub fn decorate_attribute_lint)>( ), only, attr_span: *attr_span, - }) - } - &AttributeLintKind::InvalidStyle { ref name, is_used_as_inner, target, target_span } => { - callback(lints::InvalidAttrStyle { - name: name.clone(), - is_used_as_inner, - target_span: (!is_used_as_inner).then_some(target_span), - target, - }) - } - &AttributeLintKind::UnsafeAttrOutsideUnsafe { attribute_name_span, sugg_spans } => { - callback(lints::UnsafeAttrOutsideUnsafeLint { - span: attribute_name_span, - suggestion: sugg_spans - .map(|(left, right)| lints::UnsafeAttrOutsideUnsafeSuggestion { left, right }), - }) - } + }, + ), + &AttributeLintKind::InvalidStyle { ref name, is_used_as_inner, target, target_span } => ctx + .emit( + lint, + lints::InvalidAttrStyle { + name: name.clone(), + is_used_as_inner, + target_span: (!is_used_as_inner).then_some(target_span), + target, + }, + ), + &AttributeLintKind::UnsafeAttrOutsideUnsafe { attribute_name_span, sugg_spans } => ctx + .emit( + lint, + lints::UnsafeAttrOutsideUnsafeLint { + span: attribute_name_span, + suggestion: sugg_spans.map(|(left, right)| { + lints::UnsafeAttrOutsideUnsafeSuggestion { left, right } + }), + }, + ), &AttributeLintKind::UnexpectedCfgName(name, value) => { - callback(check_cfg::unexpected_cfg_name(sess, tcx, name, value)) + ctx.emit(lint, check_cfg::unexpected_cfg_name(sess, tcx, name, value)) } &AttributeLintKind::UnexpectedCfgValue(name, value) => { - callback(check_cfg::unexpected_cfg_value(sess, tcx, name, value)) + ctx.emit(lint, check_cfg::unexpected_cfg_value(sess, tcx, name, value)) } &AttributeLintKind::DuplicateDocAlias { first_definition } => { - callback(lints::DocAliasDuplicated { first_defn: first_definition }) + ctx.emit(lint, lints::DocAliasDuplicated { first_defn: first_definition }) } &AttributeLintKind::DocAutoCfgExpectsHideOrShow => { - callback(lints::DocAutoCfgExpectsHideOrShow) + ctx.emit(lint, lints::DocAutoCfgExpectsHideOrShow) } - &AttributeLintKind::AmbiguousDeriveHelpers => callback(lints::AmbiguousDeriveHelpers), + &AttributeLintKind::AmbiguousDeriveHelpers => ctx.emit(lint, lints::AmbiguousDeriveHelpers), &AttributeLintKind::DocAutoCfgHideShowUnexpectedItem { attr_name } => { - callback(lints::DocAutoCfgHideShowUnexpectedItem { attr_name }) + ctx.emit(lint, lints::DocAutoCfgHideShowUnexpectedItem { attr_name }) } &AttributeLintKind::DocAutoCfgHideShowExpectsList { attr_name } => { - callback(lints::DocAutoCfgHideShowExpectsList { attr_name }) + ctx.emit(lint, lints::DocAutoCfgHideShowExpectsList { attr_name }) } - &AttributeLintKind::DocInvalid => callback(lints::DocInvalid), + &AttributeLintKind::DocInvalid => ctx.emit(lint, lints::DocInvalid), - &AttributeLintKind::DocUnknownInclude { span, inner, value } => { - callback(lints::DocUnknownInclude { - inner, - value, - sugg: (span, Applicability::MaybeIncorrect), - }) - } + &AttributeLintKind::DocUnknownInclude { span, inner, value } => ctx.emit( + lint, + lints::DocUnknownInclude { inner, value, sugg: (span, Applicability::MaybeIncorrect) }, + ), &AttributeLintKind::DocUnknownSpotlight { span } => { - callback(lints::DocUnknownSpotlight { sugg_span: span }) + ctx.emit(lint, lints::DocUnknownSpotlight { sugg_span: span }) } &AttributeLintKind::DocUnknownPasses { name, span } => { - callback(lints::DocUnknownPasses { name, note_span: span }) + ctx.emit(lint, lints::DocUnknownPasses { name, note_span: span }) } &AttributeLintKind::DocUnknownPlugins { span } => { - callback(lints::DocUnknownPlugins { label_span: span }) + ctx.emit(lint, lints::DocUnknownPlugins { label_span: span }) } - &AttributeLintKind::DocUnknownAny { name } => callback(lints::DocUnknownAny { name }), + &AttributeLintKind::DocUnknownAny { name } => ctx.emit(lint, lints::DocUnknownAny { name }), - &AttributeLintKind::DocAutoCfgWrongLiteral => callback(lints::DocAutoCfgWrongLiteral), + &AttributeLintKind::DocAutoCfgWrongLiteral => ctx.emit(lint, lints::DocAutoCfgWrongLiteral), - &AttributeLintKind::DocTestTakesList => callback(lints::DocTestTakesList), + &AttributeLintKind::DocTestTakesList => ctx.emit(lint, lints::DocTestTakesList), - &AttributeLintKind::DocTestUnknown { name } => callback(lints::DocTestUnknown { name }), + &AttributeLintKind::DocTestUnknown { name } => { + ctx.emit(lint, lints::DocTestUnknown { name }) + } - &AttributeLintKind::DocTestLiteral => callback(lints::DocTestLiteral), + &AttributeLintKind::DocTestLiteral => ctx.emit(lint, lints::DocTestLiteral), - &AttributeLintKind::AttrCrateLevelOnly => callback(lints::AttrCrateLevelOnly), + &AttributeLintKind::AttrCrateLevelOnly => ctx.emit(lint, lints::AttrCrateLevelOnly), &AttributeLintKind::DoNotRecommendDoesNotExpectArgs => { - callback(lints::DoNotRecommendDoesNotExpectArgs) + ctx.emit(lint, lints::DoNotRecommendDoesNotExpectArgs) } - &AttributeLintKind::CrateTypeUnknown { span, suggested } => { - callback(lints::UnknownCrateTypes { + &AttributeLintKind::CrateTypeUnknown { span, suggested } => ctx.emit( + lint, + lints::UnknownCrateTypes { sugg: suggested.map(|s| lints::UnknownCrateTypesSuggestion { span, snippet: s }), - }) - } + }, + ), - &AttributeLintKind::MalformedDoc => callback(lints::MalformedDoc), + &AttributeLintKind::MalformedDoc => ctx.emit(lint, lints::MalformedDoc), - &AttributeLintKind::ExpectedNoArgs => callback(lints::ExpectedNoArgs), + &AttributeLintKind::ExpectedNoArgs => ctx.emit(lint, lints::ExpectedNoArgs), - &AttributeLintKind::ExpectedNameValue => callback(lints::ExpectedNameValue), + &AttributeLintKind::ExpectedNameValue => ctx.emit(lint, lints::ExpectedNameValue), &AttributeLintKind::MalformedOnUnimplementedAttr { span } => { - callback(lints::MalformedOnUnimplementedAttrLint { span }) + ctx.emit(lint, lints::MalformedOnUnimplementedAttrLint { span }) } &AttributeLintKind::MalformedOnConstAttr { span } => { - callback(lints::MalformedOnConstAttrLint { span }) + ctx.emit(lint, lints::MalformedOnConstAttrLint { span }) } AttributeLintKind::MalformedDiagnosticFormat { warning } => match warning { FormatWarning::PositionalArgument { .. } => { - callback(lints::DisallowedPositionalArgument) + ctx.emit(lint, lints::DisallowedPositionalArgument) } - FormatWarning::InvalidSpecifier { .. } => callback(lints::InvalidFormatSpecifier), + FormatWarning::InvalidSpecifier { .. } => ctx.emit(lint, lints::InvalidFormatSpecifier), }, AttributeLintKind::DiagnosticWrappedParserError { description, label, span } => { - callback(lints::WrappedParserError { description, label, span: *span }) + ctx.emit(lint, lints::WrappedParserError { description, label, span: *span }) } &AttributeLintKind::IgnoredDiagnosticOption { option_name, first_span, later_span } => { - callback(lints::IgnoredDiagnosticOption { option_name, first_span, later_span }) + ctx.emit(lint, lints::IgnoredDiagnosticOption { option_name, first_span, later_span }) } &AttributeLintKind::MissingOptionsForOnUnimplemented => { - callback(lints::MissingOptionsForOnUnimplementedAttr) + ctx.emit(lint, lints::MissingOptionsForOnUnimplementedAttr) } &AttributeLintKind::MissingOptionsForOnConst => { - callback(lints::MissingOptionsForOnConstAttr) + ctx.emit(lint, lints::MissingOptionsForOnConstAttr) } } } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 34276eb76cf3..e524a66910d9 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -132,7 +132,7 @@ pub use builtin::{MissingDoc, SoftLints}; pub use context::{CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore}; pub use early::diagnostics::{decorate_attribute_lint, decorate_builtin_lint}; -pub use early::{EarlyCheckNode, check_ast_node}; +pub use early::{EarlyCheckNode, EmitDiag, check_ast_node}; pub use late::{check_crate, late_lint_mod, unerased_lint_store}; pub use levels::LintLevelsBuilder; pub use passes::{EarlyLintPass, LateLintPass}; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 541ab3d1c295..4b659ff8f4f4 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -772,6 +772,22 @@ fn run_merge_finalize(opt: config::RenderOptions) -> Result<(), error::Error> { Ok(()) } +struct DiagEmitter<'tcx> { + hir_id: rustc_hir::HirId, + tcx: TyCtxt<'tcx>, + span: rustc_span::Span, +} + +impl rustc_lint::EmitDiag for DiagEmitter<'_> { + fn emit( + &self, + lint: &'static rustc_lint::Lint, + diag: impl for<'a> rustc_errors::Diagnostic<'a, ()>, + ) { + self.tcx.emit_node_span_lint(lint, self.hir_id, self.span, diag); + } +} + fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { // Throw away the first argument, the name of the binary. // In case of at_args being empty, as might be the case by @@ -912,18 +928,16 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { for lint in &delayed_lints.lints { match lint { DelayedLint::AttributeParsing(attribute_lint) => { - tcx.node_span_lint( - attribute_lint.lint_id.lint, - attribute_lint.id, - attribute_lint.span, - |diag| { - rustc_lint::decorate_attribute_lint( - tcx.sess, - Some(tcx), - &attribute_lint.kind, - diag, - ); + rustc_lint::decorate_attribute_lint( + &DiagEmitter { + hir_id: attribute_lint.id, + tcx, + span: attribute_lint.span, }, + tcx.sess, + Some(tcx), + &attribute_lint.kind, + attribute_lint.lint_id.lint, ); } } diff --git a/tests/ui/consts/assoc-const-elided-lifetime.stderr b/tests/ui/consts/assoc-const-elided-lifetime.stderr index 958215268357..6277b079bdac 100644 --- a/tests/ui/consts/assoc-const-elided-lifetime.stderr +++ b/tests/ui/consts/assoc-const-elided-lifetime.stderr @@ -4,13 +4,13 @@ error: `'_` cannot be used here LL | const FOO: Foo<'_> = Foo { x: PhantomData::<&()> }; | ^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #115010 note: cannot automatically infer `'static` because of other lifetimes in scope --> $DIR/assoc-const-elided-lifetime.rs:9:6 | LL | impl<'a> Foo<'a> { | ^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #115010 note: the lint level is defined here --> $DIR/assoc-const-elided-lifetime.rs:1:9 | @@ -28,13 +28,13 @@ error: `&` without an explicit lifetime name cannot be used here LL | const BAR: &() = &(); | ^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #115010 note: cannot automatically infer `'static` because of other lifetimes in scope --> $DIR/assoc-const-elided-lifetime.rs:9:6 | LL | impl<'a> Foo<'a> { | ^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #115010 help: use the `'static` lifetime | LL | const BAR: &'static () = &(); diff --git a/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr b/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr index ae4a48e4e932..370e6655d860 100644 --- a/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr +++ b/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr @@ -4,13 +4,13 @@ error: `&` without an explicit lifetime name cannot be used here LL | const STATIC: &str = ""; | ^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #115010 note: cannot automatically infer `'static` because of other lifetimes in scope --> $DIR/elided-lifetime.rs:5:10 | LL | impl Foo<'_> { | ^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #115010 note: the lint level is defined here --> $DIR/elided-lifetime.rs:1:9 | @@ -27,13 +27,13 @@ error: `&` without an explicit lifetime name cannot be used here LL | const STATIC: &str = ""; | ^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #115010 note: cannot automatically infer `'static` because of other lifetimes in scope --> $DIR/elided-lifetime.rs:15:18 | LL | impl Bar for Foo<'_> { | ^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #115010 help: use the `'static` lifetime | LL | const STATIC: &'static str = ""; diff --git a/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr b/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr index 2ecab3442a96..3680ef61e0c4 100644 --- a/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr +++ b/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr @@ -24,13 +24,13 @@ error: `&` without an explicit lifetime name cannot be used here LL | const GAC_LIFETIME<'a>: &str = ""; | ^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #115010 note: cannot automatically infer `'static` because of other lifetimes in scope --> $DIR/generic-associated-const.rs:8:24 | LL | const GAC_LIFETIME<'a>: &str = ""; | ^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #115010 note: the lint level is defined here --> $DIR/generic-associated-const.rs:1:9 | diff --git a/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr b/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr index 2bc271dccad9..ab8251516201 100644 --- a/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr +++ b/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr @@ -4,13 +4,13 @@ error: `&` without an explicit lifetime name cannot be used here LL | const STATIC: &str = ""; | ^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #115010 note: cannot automatically infer `'static` because of other lifetimes in scope --> $DIR/static-trait-impl.rs:8:10 | LL | impl Bar<'_> for A { | ^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #115010 note: the lint level is defined here --> $DIR/static-trait-impl.rs:1:9 |