diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index 75824670d249..dbf96a1c4049 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -8,7 +8,6 @@ use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::lint::BuiltinLintDiag; -use tracing::debug; use crate::lints; @@ -87,36 +86,6 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { } .into_diag(dcx, level) } - BuiltinLintDiag::SingleUseLifetime { - param_span, - use_span, - elidable, - deletion_span, - ident, - } => { - debug!(?param_span, ?use_span, ?deletion_span); - let suggestion = if let Some(deletion_span) = deletion_span { - let (use_span, replace_lt) = if elidable { - let use_span = - self.sess.source_map().span_extend_while_whitespace(use_span); - (use_span, String::new()) - } else { - (use_span, "'_".to_owned()) - }; - debug!(?deletion_span, ?use_span); - - // issue 107998 for the case such as a wrong function pointer type - // `deletion_span` is empty and there is no need to report lifetime uses here - let deletion_span = - if deletion_span.is_empty() { None } else { Some(deletion_span) }; - Some(lints::SingleUseLifetimeSugg { deletion_span, use_span, replace_lt }) - } else { - None - }; - - lints::SingleUseLifetime { suggestion, param_span, use_span, ident } - .into_diag(dcx, level) - } BuiltinLintDiag::NamedArgumentUsedPositionally { position_sp_to_replace, position_sp_for_msg, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index b77225db4f0e..14dfcca0c466 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -3081,30 +3081,6 @@ pub(crate) enum UnusedImportsSugg { }, } -#[derive(Diagnostic)] -#[diag("lifetime parameter `{$ident}` only used once")] -pub(crate) struct SingleUseLifetime { - #[label("this lifetime...")] - pub param_span: Span, - #[label("...is used only here")] - pub use_span: Span, - #[subdiagnostic] - pub suggestion: Option, - - pub ident: Ident, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion("elide the single-use lifetime", applicability = "machine-applicable")] -pub(crate) struct SingleUseLifetimeSugg { - #[suggestion_part(code = "")] - pub deletion_span: Option, - #[suggestion_part(code = "{replace_lt}")] - pub use_span: Span, - - pub replace_lt: String, -} - #[derive(Diagnostic)] #[diag("named argument `{$named_arg_name}` is not used by name")] pub(crate) struct NamedArgumentUsedPositionally { diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 71b507f67e8f..32e88976f589 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -665,18 +665,6 @@ pub enum BuiltinLintDiag { test_module_span: Option, span_snippets: Vec, }, - SingleUseLifetime { - /// Span of the parameter which declares this lifetime. - param_span: Span, - /// Span of the code that should be removed when eliding this lifetime. - /// This span should include leading or trailing comma. - deletion_span: Option, - /// Span of the single use, or None if the lifetime is never used. - /// If true, the lifetime will be fully elided. - use_span: Span, - elidable: bool, - ident: Ident, - }, NamedArgumentUsedPositionally { /// Span where the named argument is used by position and will be replaced with the named /// argument name diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 43b006d72e50..5f3079cdba0d 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -1697,3 +1697,27 @@ pub(crate) struct AssociatedConstElidedLifetime { #[note("cannot automatically infer `'static` because of other lifetimes in scope")] pub lifetimes_in_scope: MultiSpan, } + +#[derive(Diagnostic)] +#[diag("lifetime parameter `{$ident}` only used once")] +pub(crate) struct SingleUseLifetime { + #[label("this lifetime...")] + pub param_span: Span, + #[label("...is used only here")] + pub use_span: Span, + #[subdiagnostic] + pub suggestion: Option, + + pub ident: Ident, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("elide the single-use lifetime", applicability = "machine-applicable")] +pub(crate) struct SingleUseLifetimeSugg { + #[suggestion_part(code = "")] + pub deletion_span: Option, + #[suggestion_part(code = "{replace_lt}")] + pub use_span: Span, + + pub replace_lt: String, +} diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 7539e3c4f499..3128e67724ca 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -14,7 +14,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::{ - Applicability, Diag, ErrorGuaranteed, MultiSpan, SuggestionStyle, pluralize, + Applicability, Diag, Diagnostic, ErrorGuaranteed, MultiSpan, SuggestionStyle, pluralize, struct_span_code_err, }; use rustc_hir as hir; @@ -3647,16 +3647,47 @@ pub(crate) fn maybe_report_lifetime_uses( let deletion_span = if param.bounds.is_empty() { deletion_span() } else { None }; - self.r.lint_buffer.buffer_lint( + let tcx = self.r.tcx; + let param_ident = param.ident; + let sugg_data = deletion_span.map(|deletion_span| { + if elidable { + let use_span = + tcx.sess.source_map().span_extend_while_whitespace(use_span); + (deletion_span, use_span, String::new()) + } else { + (deletion_span, use_span, "'_".to_owned()) + } + }); + self.r.lint_buffer.dyn_buffer_lint( lint::builtin::SINGLE_USE_LIFETIMES, param.id, param.ident.span, - lint::BuiltinLintDiag::SingleUseLifetime { - param_span: param.ident.span, - use_span, - elidable, - deletion_span, - ident: param.ident, + move |dcx, level| { + let suggestion = + sugg_data.map(|(deletion_span, use_span, replace_lt)| { + // issue 107998 for the case such as a wrong function pointer type + // `deletion_span` is empty and there is no need to report lifetime uses here + let deletion_span = if deletion_span.is_empty() { + None + } else { + Some(deletion_span) + }; + errors::SingleUseLifetimeSugg { + deletion_span, + use_span, + replace_lt, + } + }); + let param_span = param_ident.span; + debug!(?param_span, ?use_span, ?deletion_span); + + errors::SingleUseLifetime { + suggestion, + param_span, + use_span, + ident: param_ident, + } + .into_diag(dcx, level) }, ); }