1
Fork 0

Move "elided lifetime in path" to subdiagnostic struct

This requires nested subdiagnostics.
This commit is contained in:
Xiretza 2024-04-20 13:21:15 +00:00
parent b220b741c6
commit 6974e9cf70
5 changed files with 40 additions and 33 deletions

View file

@ -348,3 +348,11 @@ pub struct IndicateAnonymousLifetime {
pub count: usize, pub count: usize,
pub suggestion: String, pub suggestion: String,
} }
#[derive(Subdiagnostic)]
pub struct ElidedLifetimeInPathSubdiag {
#[subdiagnostic]
pub expected: ExpectedLifetimeParameter,
#[subdiagnostic]
pub indicate: Option<IndicateAnonymousLifetime>,
}

View file

@ -41,8 +41,8 @@ pub use diagnostic::{
SubdiagMessageOp, Subdiagnostic, SubdiagMessageOp, Subdiagnostic,
}; };
pub use diagnostic_impls::{ pub use diagnostic_impls::{
DiagArgFromDisplay, DiagSymbolList, ExpectedLifetimeParameter, IndicateAnonymousLifetime, DiagArgFromDisplay, DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter,
SingleLabelManySpans, IndicateAnonymousLifetime, SingleLabelManySpans,
}; };
pub use emitter::ColorConfig; pub use emitter::ColorConfig;
pub use rustc_error_messages::{ pub use rustc_error_messages::{
@ -1912,27 +1912,24 @@ impl Level {
} }
// FIXME(eddyb) this doesn't belong here AFAICT, should be moved to callsite. // FIXME(eddyb) this doesn't belong here AFAICT, should be moved to callsite.
pub fn add_elided_lifetime_in_path_suggestion<G: EmissionGuarantee>( pub fn elided_lifetime_in_path_suggestion(
source_map: &SourceMap, source_map: &SourceMap,
diag: &mut Diag<'_, G>,
n: usize, n: usize,
path_span: Span, path_span: Span,
incl_angl_brckt: bool, incl_angl_brckt: bool,
insertion_span: Span, insertion_span: Span,
) { ) -> ElidedLifetimeInPathSubdiag {
diag.subdiagnostic(diag.dcx, ExpectedLifetimeParameter { span: path_span, count: n }); let expected = ExpectedLifetimeParameter { span: path_span, count: n };
if !source_map.is_span_accessible(insertion_span) {
// Do not try to suggest anything if generated by a proc-macro. // Do not try to suggest anything if generated by a proc-macro.
return; let indicate = source_map.is_span_accessible(insertion_span).then(|| {
}
let anon_lts = vec!["'_"; n].join(", "); let anon_lts = vec!["'_"; n].join(", ");
let suggestion = let suggestion =
if incl_angl_brckt { format!("<{anon_lts}>") } else { format!("{anon_lts}, ") }; if incl_angl_brckt { format!("<{anon_lts}>") } else { format!("{anon_lts}, ") };
diag.subdiagnostic( IndicateAnonymousLifetime { span: insertion_span.shrink_to_hi(), count: n, suggestion }
diag.dcx, });
IndicateAnonymousLifetime { span: insertion_span.shrink_to_hi(), count: n, suggestion },
); ElidedLifetimeInPathSubdiag { expected, indicate }
} }
pub fn report_ambiguity_error<'a, G: EmissionGuarantee>( pub fn report_ambiguity_error<'a, G: EmissionGuarantee>(

View file

@ -2,7 +2,7 @@
#![allow(rustc::untranslatable_diagnostic)] #![allow(rustc::untranslatable_diagnostic)]
use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
use rustc_errors::{add_elided_lifetime_in_path_suggestion, Diag}; use rustc_errors::{elided_lifetime_in_path_suggestion, Diag};
use rustc_errors::{Applicability, SuggestionStyle}; use rustc_errors::{Applicability, SuggestionStyle};
use rustc_middle::middle::stability; use rustc_middle::middle::stability;
use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::BuiltinLintDiag;
@ -74,13 +74,15 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di
diag.span_note(span_def, "the macro is defined here"); diag.span_note(span_def, "the macro is defined here");
} }
BuiltinLintDiag::ElidedLifetimesInPaths(n, path_span, incl_angl_brckt, insertion_span) => { BuiltinLintDiag::ElidedLifetimesInPaths(n, path_span, incl_angl_brckt, insertion_span) => {
add_elided_lifetime_in_path_suggestion( diag.subdiagnostic(
sess.dcx(),
elided_lifetime_in_path_suggestion(
sess.source_map(), sess.source_map(),
diag,
n, n,
path_span, path_span,
incl_angl_brckt, incl_angl_brckt,
insertion_span, insertion_span,
),
); );
} }
BuiltinLintDiag::UnknownCrateTypes(span, note, sugg) => { BuiltinLintDiag::UnknownCrateTypes(span, note, sugg) => {

View file

@ -1,4 +1,4 @@
use rustc_errors::{codes::*, Applicability, MultiSpan}; use rustc_errors::{codes::*, Applicability, ElidedLifetimeInPathSubdiag, MultiSpan};
use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{ use rustc_span::{
symbol::{Ident, Symbol}, symbol::{Ident, Symbol},
@ -907,6 +907,8 @@ pub(crate) struct ExplicitAnonymousLivetimeReportError {
pub(crate) struct ImplicitElidedLifetimeNotAllowedHere { pub(crate) struct ImplicitElidedLifetimeNotAllowedHere {
#[primary_span] #[primary_span]
pub(crate) span: Span, pub(crate) span: Span,
#[subdiagnostic]
pub(crate) subdiag: ElidedLifetimeInPathSubdiag,
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]

View file

@ -1883,20 +1883,18 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// async fn foo(_: std::cell::Ref<u32>) { ... } // async fn foo(_: std::cell::Ref<u32>) { ... }
LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. } LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. }
| LifetimeRibKind::AnonymousWarn(_) => { | LifetimeRibKind::AnonymousWarn(_) => {
let mut err =
self.r.dcx().create_err(errors::ImplicitElidedLifetimeNotAllowedHere {
span: path_span,
});
let sess = self.r.tcx.sess; let sess = self.r.tcx.sess;
rustc_errors::add_elided_lifetime_in_path_suggestion( let subdiag = rustc_errors::elided_lifetime_in_path_suggestion(
sess.source_map(), sess.source_map(),
&mut err,
expected_lifetimes, expected_lifetimes,
path_span, path_span,
!segment.has_generic_args, !segment.has_generic_args,
elided_lifetime_span, elided_lifetime_span,
); );
err.emit(); self.r.dcx().emit_err(errors::ImplicitElidedLifetimeNotAllowedHere {
span: path_span,
subdiag,
});
should_lint = false; should_lint = false;
for id in node_ids { for id in node_ids {