1
Fork 0

Fix diagnostics spans for missing lifetimes in edge cases

This commit is contained in:
Giacomo Stevanato 2021-05-12 11:36:38 +02:00
parent 338dc1f18c
commit 2cedccbdc8

View file

@ -1821,7 +1821,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
crate fn add_missing_lifetime_specifiers_label( crate fn add_missing_lifetime_specifiers_label(
&self, &self,
err: &mut DiagnosticBuilder<'_>, err: &mut DiagnosticBuilder<'_>,
spans_with_counts: Vec<(Span, usize)>, mut spans_with_counts: Vec<(Span, usize)>,
lifetime_names: &FxHashSet<Symbol>, lifetime_names: &FxHashSet<Symbol>,
lifetime_spans: Vec<Span>, lifetime_spans: Vec<Span>,
params: &[ElisionFailureInfo], params: &[ElisionFailureInfo],
@ -1831,13 +1831,21 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
.map(|(span, _)| self.tcx.sess.source_map().span_to_snippet(*span).ok()) .map(|(span, _)| self.tcx.sess.source_map().span_to_snippet(*span).ok())
.collect(); .collect();
for (span, count) in &spans_with_counts { // Empty generics are marked with a span of "<", but since from now on
// that information is in the snippets it can be removed from the spans.
for ((span, _), snippet) in spans_with_counts.iter_mut().zip(&snippets) {
if snippet.as_deref() == Some("<") {
*span = span.shrink_to_hi();
}
}
for &(span, count) in &spans_with_counts {
err.span_label( err.span_label(
*span, span,
format!( format!(
"expected {} lifetime parameter{}", "expected {} lifetime parameter{}",
if *count == 1 { "named".to_string() } else { count.to_string() }, if count == 1 { "named".to_string() } else { count.to_string() },
pluralize!(*count), pluralize!(count),
), ),
); );
} }
@ -1982,6 +1990,14 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", "), .join(", "),
) )
} else if snippet == "<" || snippet == "(" {
(
span.shrink_to_hi(),
std::iter::repeat("'static")
.take(count)
.collect::<Vec<_>>()
.join(", "),
)
} else { } else {
( (
span.shrink_to_hi(), span.shrink_to_hi(),
@ -1990,7 +2006,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
std::iter::repeat("'static") std::iter::repeat("'static")
.take(count) .take(count)
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", ") .join(", "),
), ),
) )
} }
@ -2045,6 +2061,9 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
Some("&") => Some(Box::new(|name| format!("&{} ", name))), Some("&") => Some(Box::new(|name| format!("&{} ", name))),
Some("'_") => Some(Box::new(|n| n.to_string())), Some("'_") => Some(Box::new(|n| n.to_string())),
Some("") => Some(Box::new(move |n| format!("{}, ", n).repeat(count))), Some("") => Some(Box::new(move |n| format!("{}, ", n).repeat(count))),
Some("<") => Some(Box::new(move |n| {
std::iter::repeat(n).take(count).collect::<Vec<_>>().join(", ")
})),
Some(snippet) if !snippet.ends_with('>') => Some(Box::new(move |name| { Some(snippet) if !snippet.ends_with('>') => Some(Box::new(move |name| {
format!( format!(
"{}<{}>", "{}<{}>",
@ -2071,6 +2090,9 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
Some("") => { Some("") => {
Some(std::iter::repeat("'a, ").take(count).collect::<Vec<_>>().join("")) Some(std::iter::repeat("'a, ").take(count).collect::<Vec<_>>().join(""))
} }
Some("<") => {
Some(std::iter::repeat("'a").take(count).collect::<Vec<_>>().join(", "))
}
Some(snippet) => Some(format!( Some(snippet) => Some(format!(
"{}<{}>", "{}<{}>",
snippet, snippet,