diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index 06738b9c7337..902f2419c46d 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -10,7 +10,7 @@ use rustc_hir::lints::AttributeLintKind; use rustc_hir::{AttrArgs, AttrItem, AttrPath, Attribute, HashIgnoredAttrId, Target}; use rustc_session::Session; -use rustc_session::lint::{BuiltinLintDiag, LintId}; +use rustc_session::lint::LintId; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym}; use crate::context::{AcceptContext, FinalizeContext, FinalizeFn, SharedContext, Stage}; @@ -124,14 +124,7 @@ pub fn parse_limited_all<'a>( target, OmitDoc::Skip, std::convert::identity, - |lint_id, span, kind| { - sess.psess.buffer_lint( - lint_id.lint, - span, - target_node_id, - BuiltinLintDiag::AttributeLint(kind), - ) - }, + |lint_id, span, kind| sess.psess.buffer_lint(lint_id.lint, span, target_node_id, kind), ) } @@ -230,12 +223,7 @@ pub fn parse_single_args( let mut parser = Self { features, tools: None, parse_only: None, sess, stage: Early { emit_errors } }; let mut emit_lint = |lint_id: LintId, span: Span, kind: AttributeLintKind| { - sess.psess.buffer_lint( - lint_id.lint, - span, - target_node_id, - BuiltinLintDiag::AttributeLint(kind), - ) + sess.psess.buffer_lint(lint_id.lint, span, target_node_id, kind) }; if let Some(safety) = attr_safety { parser.check_attribute_safety(&attr_path, inner_span, safety, &mut emit_lint) diff --git a/compiler/rustc_attr_parsing/src/validate_attr.rs b/compiler/rustc_attr_parsing/src/validate_attr.rs index f047c19a150b..f5ff312f3ade 100644 --- a/compiler/rustc_attr_parsing/src/validate_attr.rs +++ b/compiler/rustc_attr_parsing/src/validate_attr.rs @@ -13,7 +13,6 @@ use rustc_hir::lints::AttributeLintKind; use rustc_parse::parse_in; use rustc_session::errors::report_lit_error; -use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT; use rustc_session::parse::ParseSess; use rustc_span::{Span, Symbol, sym}; @@ -187,11 +186,11 @@ pub fn emit_malformed_attribute( ILL_FORMED_ATTRIBUTE_INPUT, span, ast::CRATE_NODE_ID, - BuiltinLintDiag::AttributeLint(AttributeLintKind::IllFormedAttributeInput { + AttributeLintKind::IllFormedAttributeInput { suggestions: suggestions.clone(), docs: template.docs, help: None, - }), + }, ); } else { suggestions.sort(); diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 171c15eb4b9f..87f1ff960a82 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -1141,3 +1141,22 @@ pub(crate) struct EiiMacroExpectedMaxOneArgument { pub span: Span, pub name: String, } + +#[derive(Diagnostic)] +#[diag("named argument `{$named_arg_name}` is not used by name")] +pub(crate) struct NamedArgumentUsedPositionally { + #[label("this named argument is referred to by position in formatting string")] + pub named_arg_sp: Span, + #[label("this formatting argument uses named argument `{$named_arg_name}` by position")] + pub position_label_sp: Option, + #[suggestion( + "use the named argument by name to avoid ambiguity", + style = "verbose", + code = "{name}", + applicability = "maybe-incorrect" + )] + pub suggestion: Option, + + pub name: String, + pub named_arg_name: String, +} diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index f47dae5eba00..7d01868645a0 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -10,12 +10,12 @@ }; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{ - Applicability, BufferedEarlyLint, Diag, MultiSpan, PResult, SingleLabelManySpans, listify, - pluralize, + Applicability, BufferedEarlyLint, DecorateDiagCompat, Diag, Diagnostic, MultiSpan, PResult, + SingleLabelManySpans, listify, pluralize, }; use rustc_expand::base::*; +use rustc_lint_defs::LintId; use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY; -use rustc_lint_defs::{BuiltinLintDiag, LintId}; use rustc_parse::exp; use rustc_parse_format as parse; use rustc_span::{BytePos, ErrorGuaranteed, Ident, InnerSpan, Span, Symbol}; @@ -611,14 +611,39 @@ enum ArgRef<'a> { span: Some(arg_name.span.into()), node_id: rustc_ast::CRATE_NODE_ID, lint_id: LintId::of(NAMED_ARGUMENTS_USED_POSITIONALLY), - diagnostic: BuiltinLintDiag::NamedArgumentUsedPositionally { - position_sp_to_replace, - position_sp_for_msg, - named_arg_sp: arg_name.span, - named_arg_name: arg_name.name.to_string(), - is_formatting_arg: matches!(used_as, Width | Precision), - } - .into(), + diagnostic: DecorateDiagCompat::Dynamic(Box::new(move |dcx, level, sess| { + let (suggestion, name) = + if let Some(positional_arg_to_replace) = position_sp_to_replace { + let mut name = arg_name.name.to_string(); + let is_formatting_arg = matches!(used_as, Width | Precision); + if is_formatting_arg { + name.push('$') + }; + let span_to_replace = if let Ok(positional_arg_content) = sess + .downcast_ref::() + .expect("expected a `Session`") + .source_map() + .span_to_snippet(positional_arg_to_replace) + && positional_arg_content.starts_with(':') + { + positional_arg_to_replace.shrink_to_lo() + } else { + positional_arg_to_replace + }; + (Some(span_to_replace), name) + } else { + (None, String::new()) + }; + + errors::NamedArgumentUsedPositionally { + named_arg_sp: arg_name.span, + position_label_sp: position_sp_for_msg, + suggestion, + name, + named_arg_name: arg_name.name.to_string(), + } + .into_diag(dcx, level) + })), }); } } diff --git a/compiler/rustc_errors/src/decorate_diag.rs b/compiler/rustc_errors/src/decorate_diag.rs index 321591469889..18c0c571fd1b 100644 --- a/compiler/rustc_errors/src/decorate_diag.rs +++ b/compiler/rustc_errors/src/decorate_diag.rs @@ -5,11 +5,11 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_error_messages::MultiSpan; -use rustc_lint_defs::{BuiltinLintDiag, Lint, LintId}; +use rustc_lint_defs::{AttributeLintKind, Lint, LintId}; use crate::{Diag, DiagCtxtHandle, Diagnostic, Level}; -/// We can't implement `Diagnostic` for `BuiltinLintDiag`, because decorating some of its +/// We can't implement `Diagnostic` for `AttributeLintKind`, because decorating some of its /// variants requires types we don't have yet. So, handle that case separately. pub enum DecorateDiagCompat { /// The third argument of the closure is a `Session`. However, due to the dependency tree, @@ -22,7 +22,7 @@ pub enum DecorateDiagCompat { + 'static, >, ), - Builtin(BuiltinLintDiag), + Builtin(AttributeLintKind), } impl std::fmt::Debug for DecorateDiagCompat { @@ -38,9 +38,9 @@ fn from(d: D) -> Self { } } -impl From for DecorateDiagCompat { +impl From for DecorateDiagCompat { #[inline] - fn from(b: BuiltinLintDiag) -> Self { + fn from(b: AttributeLintKind) -> Self { Self::Builtin(b) } } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 635185be1cb7..e55cfc052ac4 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -17,7 +17,7 @@ use crate::context::{EarlyContext, LintContext, LintStore}; use crate::passes::{EarlyLintPass, EarlyLintPassObject}; -use crate::{DecorateBuiltinLint, DiagAndSess}; +use crate::{DecorateAttrLint, DiagAndSess}; pub(super) mod diagnostics; @@ -42,10 +42,10 @@ fn check_id(&mut self, id: ast::NodeId) { self.context.opt_span_lint( lint_id.lint, span, - DecorateBuiltinLint { + DecorateAttrLint { sess: self.context.sess(), tcx: self.tcx, - diagnostic: b, + diagnostic: &b, }, ); } diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index c1779909e67d..0f27e04babd4 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -2,14 +2,10 @@ use std::borrow::Cow; use rustc_data_structures::sync::DynSend; -use rustc_errors::{ - Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, Level, - elided_lifetime_in_path_suggestion, -}; +use rustc_errors::{Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, Level}; use rustc_hir::lints::{AttributeLintKind, FormatWarning}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; -use rustc_session::lint::BuiltinLintDiag; use crate::lints; @@ -28,101 +24,6 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { } } -/// This is a diagnostic struct that will decorate a `BuiltinLintDiag` -/// Directly creating the lint structs is expensive, using this will only decorate the lint structs when needed. -pub struct DecorateBuiltinLint<'sess, 'tcx> { - pub sess: &'sess Session, - pub tcx: Option>, - pub diagnostic: BuiltinLintDiag, -} - -impl<'a> Diagnostic<'a, ()> for DecorateBuiltinLint<'_, '_> { - fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { - match self.diagnostic { - BuiltinLintDiag::ElidedLifetimesInPaths( - n, - path_span, - incl_angl_brckt, - insertion_span, - ) => lints::ElidedLifetimesInPaths { - subdiag: elided_lifetime_in_path_suggestion( - self.sess.source_map(), - n, - path_span, - incl_angl_brckt, - insertion_span, - ), - } - .into_diag(dcx, level), - BuiltinLintDiag::UnusedImports { - remove_whole_use, - num_to_remove, - remove_spans, - test_module_span, - span_snippets, - } => { - let sugg = if remove_whole_use { - lints::UnusedImportsSugg::RemoveWholeUse { span: remove_spans[0] } - } else { - lints::UnusedImportsSugg::RemoveImports { remove_spans, num_to_remove } - }; - let test_module_span = - test_module_span.map(|span| self.sess.source_map().guess_head_span(span)); - - lints::UnusedImports { - sugg, - test_module_span, - num_snippets: span_snippets.len(), - span_snippets: DiagArgValue::StrListSepByAnd( - span_snippets.into_iter().map(Cow::Owned).collect(), - ), - } - .into_diag(dcx, level) - } - BuiltinLintDiag::NamedArgumentUsedPositionally { - position_sp_to_replace, - position_sp_for_msg, - named_arg_sp, - named_arg_name, - is_formatting_arg, - } => { - let (suggestion, name) = - if let Some(positional_arg_to_replace) = position_sp_to_replace { - let mut name = named_arg_name.clone(); - if is_formatting_arg { - name.push('$') - }; - let span_to_replace = if let Ok(positional_arg_content) = - self.sess.source_map().span_to_snippet(positional_arg_to_replace) - && positional_arg_content.starts_with(':') - { - positional_arg_to_replace.shrink_to_lo() - } else { - positional_arg_to_replace - }; - (Some(span_to_replace), name) - } else { - (None, String::new()) - }; - - lints::NamedArgumentUsedPositionally { - named_arg_sp, - position_label_sp: position_sp_for_msg, - suggestion, - name, - named_arg_name, - } - .into_diag(dcx, level) - } - - BuiltinLintDiag::AttributeLint(kind) => { - DecorateAttrLint { sess: self.sess, tcx: self.tcx, diagnostic: &kind } - .into_diag(dcx, level) - } - } - } -} - /// This is a diagnostic struct that will decorate a `AttributeLintKind` /// Directly creating the lint structs is expensive, using this will only decorate the lint structs when needed. pub struct DecorateAttrLint<'a, 'sess, 'tcx> { diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index c76fafcde2ee..6f6aa0f96e75 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -129,7 +129,7 @@ #[rustfmt::skip] pub use builtin::{MissingDoc, SoftLints}; pub use context::{EarlyContext, LateContext, LintContext, LintStore}; -pub use early::diagnostics::{DecorateAttrLint, DecorateBuiltinLint, DiagAndSess}; +pub use early::diagnostics::{DecorateAttrLint, DiagAndSess}; pub use early::{EarlyCheckNode, check_ast_node}; pub use late::{check_crate, late_lint_mod, unerased_lint_store}; pub use levels::LintLevelsBuilder; diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 107f31260b9e..f52b90382d95 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -7,7 +7,7 @@ use rustc_errors::formatting::DiagMessageAddArg; use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagCtxtHandle, DiagMessage, DiagStyledString, Diagnostic, - ElidedLifetimeInPathSubdiag, EmissionGuarantee, Level, Subdiagnostic, SuggestionStyle, msg, + EmissionGuarantee, Level, Subdiagnostic, SuggestionStyle, msg, }; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -3039,76 +3039,6 @@ pub(crate) struct IllFormedAttributeInputHelp { pub lint: String, } -#[derive(Diagnostic)] -#[diag("hidden lifetime parameters in types are deprecated")] -pub(crate) struct ElidedLifetimesInPaths { - #[subdiagnostic] - pub subdiag: ElidedLifetimeInPathSubdiag, -} - -#[derive(Diagnostic)] -#[diag( - "{$num_snippets -> - [one] unused import: {$span_snippets} - *[other] unused imports: {$span_snippets} - }" -)] -pub(crate) struct UnusedImports { - #[subdiagnostic] - pub sugg: UnusedImportsSugg, - #[help("if this is a test module, consider adding a `#[cfg(test)]` to the containing module")] - pub test_module_span: Option, - - pub span_snippets: DiagArgValue, - pub num_snippets: usize, -} - -#[derive(Subdiagnostic)] -pub(crate) enum UnusedImportsSugg { - #[suggestion( - "remove the whole `use` item", - applicability = "machine-applicable", - code = "", - style = "tool-only" - )] - RemoveWholeUse { - #[primary_span] - span: Span, - }, - #[multipart_suggestion( - "{$num_to_remove -> - [one] remove the unused import - *[other] remove the unused imports - }", - applicability = "machine-applicable", - style = "tool-only" - )] - RemoveImports { - #[suggestion_part(code = "")] - remove_spans: Vec, - num_to_remove: usize, - }, -} - -#[derive(Diagnostic)] -#[diag("named argument `{$named_arg_name}` is not used by name")] -pub(crate) struct NamedArgumentUsedPositionally { - #[label("this named argument is referred to by position in formatting string")] - pub named_arg_sp: Span, - #[label("this formatting argument uses named argument `{$named_arg_name}` by position")] - pub position_label_sp: Option, - #[suggestion( - "use the named argument by name to avoid ambiguity", - style = "verbose", - code = "{name}", - applicability = "maybe-incorrect" - )] - pub suggestion: Option, - - pub name: String, - pub named_arg_name: String, -} - #[derive(Diagnostic)] #[diag("creating a {$shared_label}reference to mutable static")] pub(crate) struct RefOfMutStatic<'a> { diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 2ebbe633ecd1..36070dac276f 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -652,34 +652,6 @@ pub enum DeprecatedSinceKind { InVersion(String), } -// This could be a closure, but then implementing derive trait -// becomes hacky (and it gets allocated). -#[derive(Debug)] -pub enum BuiltinLintDiag { - ElidedLifetimesInPaths(usize, Span, bool, Span), - UnusedImports { - remove_whole_use: bool, - num_to_remove: usize, - remove_spans: Vec, - test_module_span: Option, - span_snippets: Vec, - }, - NamedArgumentUsedPositionally { - /// Span where the named argument is used by position and will be replaced with the named - /// argument name - position_sp_to_replace: Option, - /// Span where the named argument is used by position and is used for lint messages - position_sp_for_msg: Option, - /// Span where the named argument's name is (so we know where to put the warning message) - named_arg_sp: Span, - /// String containing the named arguments name - named_arg_name: String, - /// Indicates if the named argument is used as a width/precision for formatting - is_formatting_arg: bool, - }, - AttributeLint(AttributeLintKind), -} - #[derive(Debug, HashStable_Generic)] pub enum AttributeLintKind { UnusedDuplicate { diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 8e150b7f3a5d..cdd809bdc173 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -23,13 +23,14 @@ // - `check_unused` finally emits the diagnostics based on the data generated // in the last step +use std::borrow::Cow; + use rustc_ast as ast; use rustc_ast::visit::{self, Visitor}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_data_structures::unord::UnordSet; -use rustc_errors::MultiSpan; +use rustc_errors::{DiagArgValue, Diagnostic, MultiSpan}; use rustc_hir::def::{DefKind, Res}; -use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::builtin::{ MACRO_USE_EXTERN_CRATE, UNUSED_EXTERN_CRATES, UNUSED_IMPORTS, UNUSED_QUALIFICATIONS, }; @@ -496,16 +497,32 @@ pub(crate) fn check_unused(&mut self, krate: &ast::Crate) { } }; - visitor.r.lint_buffer.buffer_lint( + visitor.r.lint_buffer.dyn_buffer_lint_any( UNUSED_IMPORTS, unused.use_tree_id, ms, - BuiltinLintDiag::UnusedImports { - remove_whole_use, - num_to_remove, - remove_spans, - test_module_span, - span_snippets, + move |dcx, level, sess| { + let sugg = if remove_whole_use { + errors::UnusedImportsSugg::RemoveWholeUse { span: remove_spans[0] } + } else { + errors::UnusedImportsSugg::RemoveImports { remove_spans, num_to_remove } + }; + let test_module_span = test_module_span.map(|span| { + sess.downcast_ref::() + .expect("expected a `Session`") + .source_map() + .guess_head_span(span) + }); + + errors::UnusedImports { + sugg, + test_module_span, + num_snippets: span_snippets.len(), + span_snippets: DiagArgValue::StrListSepByAnd( + span_snippets.into_iter().map(Cow::Owned).collect(), + ), + } + .into_diag(dcx, level) }, ); } diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 305231a3ea0d..bcc754fd984d 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -1,7 +1,7 @@ use rustc_errors::codes::*; use rustc_errors::formatting::DiagMessageAddArg; use rustc_errors::{ - Applicability, Diag, DiagCtxtHandle, Diagnostic, ElidedLifetimeInPathSubdiag, + Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, ElidedLifetimeInPathSubdiag, EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic, msg, }; use rustc_macros::{Diagnostic, Subdiagnostic}; @@ -1740,3 +1740,54 @@ pub(crate) struct AbsPathWithModuleSugg { pub applicability: Applicability, pub replacement: String, } + +#[derive(Diagnostic)] +#[diag("hidden lifetime parameters in types are deprecated")] +pub(crate) struct ElidedLifetimesInPaths { + #[subdiagnostic] + pub subdiag: rustc_errors::ElidedLifetimeInPathSubdiag, +} + +#[derive(Diagnostic)] +#[diag( + "{$num_snippets -> + [one] unused import: {$span_snippets} + *[other] unused imports: {$span_snippets} + }" +)] +pub(crate) struct UnusedImports { + #[subdiagnostic] + pub sugg: UnusedImportsSugg, + #[help("if this is a test module, consider adding a `#[cfg(test)]` to the containing module")] + pub test_module_span: Option, + + pub span_snippets: DiagArgValue, + pub num_snippets: usize, +} + +#[derive(Subdiagnostic)] +pub(crate) enum UnusedImportsSugg { + #[suggestion( + "remove the whole `use` item", + applicability = "machine-applicable", + code = "", + style = "tool-only" + )] + RemoveWholeUse { + #[primary_span] + span: Span, + }, + #[multipart_suggestion( + "{$num_to_remove -> + [one] remove the unused import + *[other] remove the unused imports + }", + applicability = "machine-applicable", + style = "tool-only" + )] + RemoveImports { + #[suggestion_part(code = "")] + remove_spans: Vec, + num_to_remove: usize, + }, +} diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index b3a6fe95e5fa..29e6d6fadae5 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -21,8 +21,8 @@ use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::codes::*; use rustc_errors::{ - Applicability, Diag, DiagArgValue, ErrorGuaranteed, IntoDiagArg, MultiSpan, StashKey, - Suggestions, pluralize, + Applicability, Diag, DiagArgValue, Diagnostic, ErrorGuaranteed, IntoDiagArg, MultiSpan, + StashKey, Suggestions, elided_lifetime_in_path_suggestion, pluralize, }; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS}; @@ -2248,7 +2248,7 @@ fn resolve_elided_lifetimes_in_path( LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. } | LifetimeRibKind::StaticIfNoLifetimeInScope { .. } => { let sess = self.r.tcx.sess; - let subdiag = rustc_errors::elided_lifetime_in_path_suggestion( + let subdiag = elided_lifetime_in_path_suggestion( sess.source_map(), expected_lifetimes, path_span, @@ -2329,16 +2329,27 @@ fn resolve_elided_lifetimes_in_path( } if should_lint { - self.r.lint_buffer.buffer_lint( + let include_angle_bracket = !segment.has_generic_args; + self.r.lint_buffer.dyn_buffer_lint_any( lint::builtin::ELIDED_LIFETIMES_IN_PATHS, segment_id, elided_lifetime_span, - lint::BuiltinLintDiag::ElidedLifetimesInPaths( - expected_lifetimes, - path_span, - !segment.has_generic_args, - elided_lifetime_span, - ), + move |dcx, level, sess| { + let source_map = sess + .downcast_ref::() + .expect("expected a `Session`") + .source_map(); + errors::ElidedLifetimesInPaths { + subdiag: elided_lifetime_in_path_suggestion( + source_map, + expected_lifetimes, + path_span, + include_angle_bracket, + elided_lifetime_span, + ), + } + .into_diag(dcx, level) + }, ); } }