diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 3841439dde341..30efebceea929 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1514,9 +1514,21 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { for missing in &self.missing_named_lifetime_spots { match missing { MissingLifetimeSpot::Generics(generics) => { - let (span, sugg) = match &generics.params { - [] => (generics.span, format!("<{}>", lifetime_ref)), - [param, ..] => (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref)), + let (span, sugg) = if let Some(param) = generics + .params + .iter() + .filter(|p| match p.kind { + hir::GenericParamKind::Type { + synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), + .. + } => false, + _ => true, + }) + .next() + { + (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref)) + } else { + (generics.span, format!("<{}>", lifetime_ref)) }; err.span_suggestion( span, @@ -1587,20 +1599,28 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { Applicability::MaybeIncorrect, ); }; - let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg: &str| { - err.span_label(span, "expected named lifetime parameter"); - - for missing in self.missing_named_lifetime_spots.iter().rev() { - let mut introduce_suggestion = vec![]; - let msg; - let should_break; - introduce_suggestion.push(match missing { + let suggest_new = + |err: &mut DiagnosticBuilder<'_>, sugg: &str| { + err.span_label(span, "expected named lifetime parameter"); + + for missing in self.missing_named_lifetime_spots.iter().rev() { + let mut introduce_suggestion = vec![]; + let msg; + let should_break; + introduce_suggestion.push(match missing { MissingLifetimeSpot::Generics(generics) => { msg = "consider introducing a named lifetime parameter".to_string(); should_break = true; - match &generics.params { - [] => (generics.span, "<'a>".to_string()), - [param, ..] => (param.span.shrink_to_lo(), "'a, ".to_string()), + if let Some(param) = generics.params.iter().filter(|p| match p.kind { + hir::GenericParamKind::Type { + synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), + .. + } => false, + _ => true, + }).next() { + (param.span.shrink_to_lo(), "'a, ".to_string()) + } else { + (generics.span, "<'a>".to_string()) } } MissingLifetimeSpot::HigherRanked { span, span_type } => { @@ -1616,29 +1636,30 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { (*span, span_type.suggestion("'a")) } }); - for param in params { - if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(param.span) - { - if snippet.starts_with("&") && !snippet.starts_with("&'") { - introduce_suggestion - .push((param.span, format!("&'a {}", &snippet[1..]))); - } else if snippet.starts_with("&'_ ") { - introduce_suggestion - .push((param.span, format!("&'a {}", &snippet[4..]))); + for param in params { + if let Ok(snippet) = + self.tcx.sess.source_map().span_to_snippet(param.span) + { + if snippet.starts_with("&") && !snippet.starts_with("&'") { + introduce_suggestion + .push((param.span, format!("&'a {}", &snippet[1..]))); + } else if snippet.starts_with("&'_ ") { + introduce_suggestion + .push((param.span, format!("&'a {}", &snippet[4..]))); + } } } + introduce_suggestion.push((span, sugg.to_string())); + err.multipart_suggestion( + &msg, + introduce_suggestion, + Applicability::MaybeIncorrect, + ); + if should_break { + break; + } } - introduce_suggestion.push((span, sugg.to_string())); - err.multipart_suggestion( - &msg, - introduce_suggestion, - Applicability::MaybeIncorrect, - ); - if should_break { - break; - } - } - }; + }; match ( lifetime_names.len(), diff --git a/src/test/ui/suggestions/impl-trait-missing-lifetime.rs b/src/test/ui/suggestions/impl-trait-missing-lifetime.rs new file mode 100644 index 0000000000000..22dc448c97ff0 --- /dev/null +++ b/src/test/ui/suggestions/impl-trait-missing-lifetime.rs @@ -0,0 +1,2 @@ +fn f(_: impl Iterator) {} //~ ERROR missing lifetime specifier +fn main() {} diff --git a/src/test/ui/suggestions/impl-trait-missing-lifetime.stderr b/src/test/ui/suggestions/impl-trait-missing-lifetime.stderr new file mode 100644 index 0000000000000..e31f25ab60304 --- /dev/null +++ b/src/test/ui/suggestions/impl-trait-missing-lifetime.stderr @@ -0,0 +1,14 @@ +error[E0106]: missing lifetime specifier + --> $DIR/impl-trait-missing-lifetime.rs:1:31 + | +LL | fn f(_: impl Iterator) {} + | ^^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | fn f<'a>(_: impl Iterator) {} + | ^^^^ ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0106`.