about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2020-01-30 11:53:47 -0800
committerEsteban Küber <esteban@kuber.com.ar>2020-02-05 10:32:01 -0800
commit96bbb0d67eee9cbe8565afd8b56d537c5937dd62 (patch)
tree9dd81fb19e6b560dda5c8fe68aac70e72eb29dd2
parent1beac2b774fa7081ad22f9856ebb6bb9d04297fb (diff)
downloadrust-96bbb0d67eee9cbe8565afd8b56d537c5937dd62.tar.gz
rust-96bbb0d67eee9cbe8565afd8b56d537c5937dd62.zip
Account for `impl Trait`
Address #49287
-rw-r--r--src/librustc_resolve/diagnostics.rs89
-rw-r--r--src/test/ui/suggestions/impl-trait-missing-lifetime.rs2
-rw-r--r--src/test/ui/suggestions/impl-trait-missing-lifetime.stderr14
3 files changed, 71 insertions, 34 deletions
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 2732197f361..075dca8f01d 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -1519,9 +1519,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,
@@ -1592,20 +1604,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 } => {
@@ -1621,29 +1641,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 00000000000..22dc448c97f
--- /dev/null
+++ b/src/test/ui/suggestions/impl-trait-missing-lifetime.rs
@@ -0,0 +1,2 @@
+fn f(_: impl Iterator<Item = &'_ ()>) {} //~ 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 00000000000..e31f25ab603
--- /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<Item = &'_ ()>) {}
+   |                               ^^ expected named lifetime parameter
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL | fn f<'a>(_: impl Iterator<Item = &'a ()>) {}
+   |     ^^^^                          ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0106`.