about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2020-01-27 12:41:49 -0800
committerEsteban Küber <esteban@kuber.com.ar>2020-02-05 10:32:01 -0800
commit7e1464336a627ecb962f4eb38173fbfbfdd2ccf0 (patch)
tree1118175cf8ccb8ebe81d2eba85ff64db625938a6 /src
parent70dbf5526d37ad031fca57ddde55bf8757bfc326 (diff)
downloadrust-7e1464336a627ecb962f4eb38173fbfbfdd2ccf0.tar.gz
rust-7e1464336a627ecb962f4eb38173fbfbfdd2ccf0.zip
When suggesting lifetimes, propose adding the new lifetime to all arguments
Diffstat (limited to 'src')
-rw-r--r--src/librustc_resolve/diagnostics.rs12
-rw-r--r--src/librustc_resolve/lifetimes.rs9
-rw-r--r--src/test/ui/issues/issue-19707.stderr12
-rw-r--r--src/test/ui/issues/issue-30255.stderr12
-rw-r--r--src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr8
-rw-r--r--src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr4
-rw-r--r--src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr4
7 files changed, 37 insertions, 24 deletions
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index fafceb1f97c..56fb6600405 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -19,7 +19,7 @@ use syntax::ast::{self, Ident, Path};
 use syntax::util::lev_distance::find_best_match_for_name;
 
 use crate::imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver};
-use crate::lifetimes::{HRLTSpanType, MissingLifetimeSpot};
+use crate::lifetimes::{ElisionFailureInfo, HRLTSpanType, MissingLifetimeSpot};
 use crate::path_names_to_string;
 use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind};
 use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot};
@@ -1467,11 +1467,13 @@ crate fn report_missing_lifetime_specifiers(
 
 crate fn add_missing_lifetime_specifiers_label(
     err: &mut DiagnosticBuilder<'_>,
+    source_map: &SourceMap,
     span: Span,
     count: usize,
     lifetime_names: &FxHashSet<ast::Ident>,
     snippet: Option<&str>,
     missing_named_lifetime_spots: &[MissingLifetimeSpot<'_>],
+    params: &[ElisionFailureInfo],
 ) {
     if count > 1 {
         err.span_label(span, format!("expected {} lifetime parameters", count));
@@ -1514,6 +1516,14 @@ crate fn add_missing_lifetime_specifiers_label(
                         (*span, suggestion.to_string())
                     }
                 });
+                for param in params {
+                    if let Ok(snippet) = source_map.span_to_snippet(param.span) {
+                        if snippet.starts_with("&") && !snippet.starts_with("&'") {
+                            introduce_suggestion
+                                .push((param.span, format!("&'lifetime {}", &snippet[1..])));
+                        }
+                    }
+                }
                 introduce_suggestion.push((span, sugg.to_string()));
                 err.multipart_suggestion(msg, introduce_suggestion, Applicability::MaybeIncorrect);
                 if should_break {
diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs
index 022f83af815..97d314c8f65 100644
--- a/src/librustc_resolve/lifetimes.rs
+++ b/src/librustc_resolve/lifetimes.rs
@@ -280,14 +280,14 @@ enum Elide {
 }
 
 #[derive(Clone, Debug)]
-struct ElisionFailureInfo {
+crate struct ElisionFailureInfo {
     /// Where we can find the argument pattern.
     parent: Option<hir::BodyId>,
     /// The index of the argument in the original definition.
     index: usize,
     lifetime_count: usize,
     have_bound_regions: bool,
-    span: Span,
+    crate span: Span,
 }
 
 type ScopeRef<'a> = &'a Scope<'a>;
@@ -2441,11 +2441,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         if add_label {
             add_missing_lifetime_specifiers_label(
                 &mut err,
+                self.tcx.sess.source_map(),
                 span,
                 lifetime_refs.len(),
                 &lifetime_names,
                 self.tcx.sess.source_map().span_to_snippet(span).ok().as_ref().map(|s| s.as_str()),
                 &self.missing_named_lifetime_spots,
+                error.map(|p| &p[..]).unwrap_or(&[]),
             );
         }
 
@@ -2488,7 +2490,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         let mut spans = vec![];
 
         for (i, info) in elided_params.into_iter().enumerate() {
-            let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions, span } = info;
+            let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions, span } =
+                info;
 
             spans.push(span);
             let help_name = if let Some(ident) =
diff --git a/src/test/ui/issues/issue-19707.stderr b/src/test/ui/issues/issue-19707.stderr
index 1be066caa87..f8917b7bdd0 100644
--- a/src/test/ui/issues/issue-19707.stderr
+++ b/src/test/ui/issues/issue-19707.stderr
@@ -11,8 +11,8 @@ LL | type Foo = fn(&u8, &u8) -> &u8;
    |               ^^^  ^^^
 help: consider introducing a named lifetime parameter
    |
-LL | type Foo<'lifetime> = fn(&u8, &u8) -> &'lifetime u8;
-   |         ^^^^^^^^^^^                   ^^^^^^^^^^
+LL | type Foo<'lifetime> = fn(&'lifetime u8, &'lifetime u8) -> &'lifetime u8;
+   |         ^^^^^^^^^^^      ^^^^^^^^^^^^^  ^^^^^^^^^^^^^     ^^^^^^^^^^
 
 error[E0106]: missing lifetime specifier
   --> $DIR/issue-19707.rs:5:27
@@ -28,12 +28,12 @@ LL | fn bar<F: Fn(&u8, &u8) -> &u8>(f: &F) {}
    = note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html
 help: consider introducing a Higher-Ranked lifetime
    |
-LL | fn bar<F: for<'lifetime> Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {}
-   |           ^^^^^^^^^^^^^^                 ^^^^^^^^^^
+LL | fn bar<F: for<'lifetime> Fn(&'lifetime u8, &'lifetime u8) -> &'lifetime u8>(f: &F) {}
+   |           ^^^^^^^^^^^^^^    ^^^^^^^^^^^^^  ^^^^^^^^^^^^^     ^^^^^^^^^^
 help: consider introducing a named lifetime parameter
    |
-LL | fn bar<'lifetime, F: Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {}
-   |        ^^^^^^^^^^                    ^^^^^^^^^^
+LL | fn bar<'lifetime, F: Fn(&'lifetime u8, &'lifetime u8) -> &'lifetime u8>(f: &F) {}
+   |        ^^^^^^^^^^       ^^^^^^^^^^^^^  ^^^^^^^^^^^^^     ^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-30255.stderr b/src/test/ui/issues/issue-30255.stderr
index e2b57a20325..fbe715de932 100644
--- a/src/test/ui/issues/issue-30255.stderr
+++ b/src/test/ui/issues/issue-30255.stderr
@@ -11,8 +11,8 @@ LL | fn f(a: &S, b: i32) -> &i32 {
    |         ^^
 help: consider introducing a named lifetime parameter
    |
-LL | fn f<'lifetime>(a: &S, b: i32) -> &'lifetime i32 {
-   |     ^^^^^^^^^^^                   ^^^^^^^^^^
+LL | fn f<'lifetime>(a: &'lifetime S, b: i32) -> &'lifetime i32 {
+   |     ^^^^^^^^^^^    ^^^^^^^^^^^^             ^^^^^^^^^^
 
 error[E0106]: missing lifetime specifier
   --> $DIR/issue-30255.rs:14:34
@@ -27,8 +27,8 @@ LL | fn g(a: &S, b: bool, c: &i32) -> &i32 {
    |         ^^              ^^^^
 help: consider introducing a named lifetime parameter
    |
-LL | fn g<'lifetime>(a: &S, b: bool, c: &i32) -> &'lifetime i32 {
-   |     ^^^^^^^^^^^                             ^^^^^^^^^^
+LL | fn g<'lifetime>(a: &'lifetime S, b: bool, c: &'lifetime i32) -> &'lifetime i32 {
+   |     ^^^^^^^^^^^    ^^^^^^^^^^^^              ^^^^^^^^^^^^^^     ^^^^^^^^^^
 
 error[E0106]: missing lifetime specifier
   --> $DIR/issue-30255.rs:19:44
@@ -43,8 +43,8 @@ LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 {
    |         ^^^^^              ^^     ^^^^
 help: consider introducing a named lifetime parameter
    |
-LL | fn h<'lifetime>(a: &bool, b: bool, c: &S, d: &i32) -> &'lifetime i32 {
-   |     ^^^^^^^^^^^                                       ^^^^^^^^^^
+LL | fn h<'lifetime>(a: &'lifetime bool, b: bool, c: &'lifetime S, d: &'lifetime i32) -> &'lifetime i32 {
+   |     ^^^^^^^^^^^    ^^^^^^^^^^^^^^^              ^^^^^^^^^^^^     ^^^^^^^^^^^^^^     ^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
index d1b597804cd..01236e3c773 100644
--- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
+++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
@@ -19,8 +19,8 @@ LL | fn g(_x: &isize, _y: &isize) -> &isize {
    |          ^^^^^^      ^^^^^^
 help: consider introducing a named lifetime parameter
    |
-LL | fn g<'lifetime>(_x: &isize, _y: &isize) -> &'lifetime isize {
-   |     ^^^^^^^^^^^                            ^^^^^^^^^^
+LL | fn g<'lifetime>(_x: &'lifetime isize, _y: &'lifetime isize) -> &'lifetime isize {
+   |     ^^^^^^^^^^^     ^^^^^^^^^^^^^^^^      ^^^^^^^^^^^^^^^^     ^^^^^^^^^^
 
 error[E0106]: missing lifetime specifier
   --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:19
@@ -35,8 +35,8 @@ LL | fn h(_x: &Foo) -> &isize {
    |          ^^^^
 help: consider introducing a named lifetime parameter
    |
-LL | fn h<'lifetime>(_x: &Foo) -> &'lifetime isize {
-   |     ^^^^^^^^^^^              ^^^^^^^^^^
+LL | fn h<'lifetime>(_x: &'lifetime Foo) -> &'lifetime isize {
+   |     ^^^^^^^^^^^     ^^^^^^^^^^^^^^     ^^^^^^^^^^
 
 error[E0106]: missing lifetime specifier
   --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:21:20
diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr
index 52a980a61da..bea1a8bf2c1 100644
--- a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr
+++ b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr
@@ -11,8 +11,8 @@ LL | fn foo(x: &i32, y: &i32) -> &i32 {
    |           ^^^^     ^^^^
 help: consider introducing a named lifetime parameter
    |
-LL | fn foo<'lifetime>(x: &i32, y: &i32) -> &'lifetime i32 {
-   |       ^^^^^^^^^^^                      ^^^^^^^^^^
+LL | fn foo<'lifetime>(x: &'lifetime i32, y: &'lifetime i32) -> &'lifetime i32 {
+   |       ^^^^^^^^^^^    ^^^^^^^^^^^^^^     ^^^^^^^^^^^^^^     ^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr
index 801504627c0..97014dae2b9 100644
--- a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr
+++ b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr
@@ -11,8 +11,8 @@ LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } }
    |           ^^^^     ^^^^
 help: consider introducing a named lifetime parameter
    |
-LL | fn foo<'lifetime>(x: &u32, y: &u32) -> &'lifetime u32 { loop { } }
-   |       ^^^^^^^^^^^                       ^^^^^^^^^
+LL | fn foo<'lifetime>(x: &'lifetime u32, y: &'lifetime u32) -> &'lifetime u32 { loop { } }
+   |       ^^^^^^^^^^^    ^^^^^^^^^^^^^^     ^^^^^^^^^^^^^^      ^^^^^^^^^
 
 error: aborting due to previous error