about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2020-01-27 11:48:52 -0800
committerEsteban Küber <esteban@kuber.com.ar>2020-02-05 10:32:01 -0800
commit70dbf5526d37ad031fca57ddde55bf8757bfc326 (patch)
tree75d397c532057a49e0202e26964c65d398fa01cf
parent183dfac1f31cc16975bb1f598779df5689d1e729 (diff)
downloadrust-70dbf5526d37ad031fca57ddde55bf8757bfc326.tar.gz
rust-70dbf5526d37ad031fca57ddde55bf8757bfc326.zip
Use spans for input borrowed types unrelated to return type
-rw-r--r--src/librustc_resolve/lifetimes.rs27
-rw-r--r--src/test/ui/async-await/issues/issue-63388-2.stderr6
-rw-r--r--src/test/ui/issues/issue-19707.stderr12
-rw-r--r--src/test/ui/issues/issue-26638.stderr6
-rw-r--r--src/test/ui/issues/issue-30255.stderr18
-rw-r--r--src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr12
-rw-r--r--src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr6
-rw-r--r--src/test/ui/rfc1623.stderr12
-rw-r--r--src/test/ui/suggestions/return-without-lifetime.stderr12
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr6
-rw-r--r--src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr6
-rw-r--r--src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr6
12 files changed, 104 insertions, 25 deletions
diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs
index a8d6afa0e55..022f83af815 100644
--- a/src/librustc_resolve/lifetimes.rs
+++ b/src/librustc_resolve/lifetimes.rs
@@ -287,6 +287,7 @@ struct ElisionFailureInfo {
     index: usize,
     lifetime_count: usize,
     have_bound_regions: bool,
+    span: Span,
 }
 
 type ScopeRef<'a> = &'a Scope<'a>;
@@ -2273,6 +2274,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                     index: i,
                     lifetime_count: gather.lifetimes.len(),
                     have_bound_regions: gather.have_bound_regions,
+                    span: input.span,
                 }
             })
             .collect();
@@ -2483,11 +2485,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             params.iter().cloned().filter(|info| info.lifetime_count > 0).collect();
 
         let elided_len = elided_params.len();
+        let mut spans = vec![];
 
-        // FIXME: collect spans of the input params when appropriate to use in the diagnostic.
         for (i, info) in elided_params.into_iter().enumerate() {
-            let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions } = info;
+            let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions, span } = info;
 
+            spans.push(span);
             let help_name = if let Some(ident) =
                 parent.and_then(|body| self.tcx.hir().body(body).params[index].pat.simple_ident())
             {
@@ -2518,14 +2521,22 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             }
         }
 
+        let help = |msg| {
+            if spans.is_empty() {
+                db.help(msg);
+            } else {
+                db.span_help(spans, msg);
+            }
+        };
+
         if len == 0 {
             db.help(
                 "this function's return type contains a borrowed value, \
-                but there is no value for it to be borrowed from",
+                 but there is no value for it to be borrowed from",
             );
             self.suggest_lifetime(db, span, "consider giving it a 'static lifetime")
         } else if elided_len == 0 {
-            db.help(
+            help(
                 "this function's return type contains a borrowed value with \
                  an elided lifetime, but the lifetime cannot be derived from \
                  the arguments",
@@ -2533,16 +2544,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             let msg = "consider giving it an explicit bounded or 'static lifetime";
             self.suggest_lifetime(db, span, msg)
         } else if elided_len == 1 {
-            db.help(&format!(
+            help(&format!(
                 "this function's return type contains a borrowed value, \
-                but the signature does not say which {} it is borrowed from",
+                 but the signature does not say which {} it is borrowed from",
                 m
             ));
             true
         } else {
-            db.help(&format!(
+            help(&format!(
                 "this function's return type contains a borrowed value, \
-                but the signature does not say whether it is borrowed from {}",
+                 but the signature does not say whether it is borrowed from {}",
                 m
             ));
             true
diff --git a/src/test/ui/async-await/issues/issue-63388-2.stderr b/src/test/ui/async-await/issues/issue-63388-2.stderr
index 7e45d588c6c..a12c601b936 100644
--- a/src/test/ui/async-await/issues/issue-63388-2.stderr
+++ b/src/test/ui/async-await/issues/issue-63388-2.stderr
@@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier
 LL |     ) -> &dyn Foo
    |          ^ help: consider using the named lifetime: `&'a`
    |
-   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar`
+help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar`
+  --> $DIR/issue-63388-2.rs:11:14
+   |
+LL |         foo: &dyn Foo, bar: &'a dyn Foo
+   |              ^^^^^^^^       ^^^^^^^^^^^
 
 error: cannot infer an appropriate lifetime
   --> $DIR/issue-63388-2.rs:11:9
diff --git a/src/test/ui/issues/issue-19707.stderr b/src/test/ui/issues/issue-19707.stderr
index c5129152aa5..1be066caa87 100644
--- a/src/test/ui/issues/issue-19707.stderr
+++ b/src/test/ui/issues/issue-19707.stderr
@@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier
 LL | type Foo = fn(&u8, &u8) -> &u8;
    |                            ^ expected named lifetime parameter
    |
-   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
+help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
+  --> $DIR/issue-19707.rs:3:15
+   |
+LL | type Foo = fn(&u8, &u8) -> &u8;
+   |               ^^^  ^^^
 help: consider introducing a named lifetime parameter
    |
 LL | type Foo<'lifetime> = fn(&u8, &u8) -> &'lifetime u8;
@@ -16,7 +20,11 @@ error[E0106]: missing lifetime specifier
 LL | fn bar<F: Fn(&u8, &u8) -> &u8>(f: &F) {}
    |                           ^ expected named lifetime parameter
    |
-   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
+help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
+  --> $DIR/issue-19707.rs:5:14
+   |
+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
    |
diff --git a/src/test/ui/issues/issue-26638.stderr b/src/test/ui/issues/issue-26638.stderr
index 85d5d9cc42e..882102799d9 100644
--- a/src/test/ui/issues/issue-26638.stderr
+++ b/src/test/ui/issues/issue-26638.stderr
@@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier
 LL | fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() }
    |                                                              ^ expected named lifetime parameter
    |
-   = help: this function's return type contains a borrowed value, but the signature does not say which one of `iter`'s 2 lifetimes it is borrowed from
+help: this function's return type contains a borrowed value, but the signature does not say which one of `iter`'s 2 lifetimes it is borrowed from
+  --> $DIR/issue-26638.rs:1:21
+   |
+LL | fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() }
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: consider introducing a named lifetime parameter
    |
 LL | fn parse_type<'lifetime>(iter: Box<dyn Iterator<Item=&str>+'static>) -> &'lifetime str { iter.next() }
diff --git a/src/test/ui/issues/issue-30255.stderr b/src/test/ui/issues/issue-30255.stderr
index c9402277640..e2b57a20325 100644
--- a/src/test/ui/issues/issue-30255.stderr
+++ b/src/test/ui/issues/issue-30255.stderr
@@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier
 LL | fn f(a: &S, b: i32) -> &i32 {
    |                        ^ expected named lifetime parameter
    |
-   = help: this function's return type contains a borrowed value, but the signature does not say which one of `a`'s 2 lifetimes it is borrowed from
+help: this function's return type contains a borrowed value, but the signature does not say which one of `a`'s 2 lifetimes it is borrowed from
+  --> $DIR/issue-30255.rs:9:9
+   |
+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 {
@@ -16,7 +20,11 @@ error[E0106]: missing lifetime specifier
 LL | fn g(a: &S, b: bool, c: &i32) -> &i32 {
    |                                  ^ expected named lifetime parameter
    |
-   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `a`'s 2 lifetimes or `c`
+help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `a`'s 2 lifetimes or `c`
+  --> $DIR/issue-30255.rs:14:9
+   |
+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 {
@@ -28,7 +36,11 @@ error[E0106]: missing lifetime specifier
 LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 {
    |                                            ^ expected named lifetime parameter
    |
-   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `a`, one of `c`'s 2 lifetimes, or `d`
+help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `a`, one of `c`'s 2 lifetimes, or `d`
+  --> $DIR/issue-30255.rs:19:9
+   |
+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 {
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 1d5eeac23f9..d1b597804cd 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
@@ -12,7 +12,11 @@ error[E0106]: missing lifetime specifier
 LL | fn g(_x: &isize, _y: &isize) -> &isize {
    |                                 ^ expected named lifetime parameter
    |
-   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_x` or `_y`
+help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_x` or `_y`
+  --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:7:10
+   |
+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 {
@@ -24,7 +28,11 @@ error[E0106]: missing lifetime specifier
 LL | fn h(_x: &Foo) -> &isize {
    |                   ^ expected named lifetime parameter
    |
-   = help: this function's return type contains a borrowed value, but the signature does not say which one of `_x`'s 2 lifetimes it is borrowed from
+help: this function's return type contains a borrowed value, but the signature does not say which one of `_x`'s 2 lifetimes it is borrowed from
+  --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:10
+   |
+LL | fn h(_x: &Foo) -> &isize {
+   |          ^^^^
 help: consider introducing a named lifetime parameter
    |
 LL | fn h<'lifetime>(_x: &Foo) -> &'lifetime isize {
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 2990ab86824..52a980a61da 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
@@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier
 LL | fn foo(x: &i32, y: &i32) -> &i32 {
    |                             ^ expected named lifetime parameter
    |
-   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y`
+help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y`
+  --> $DIR/ex1b-return-no-names-if-else.rs:1:11
+   |
+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 {
diff --git a/src/test/ui/rfc1623.stderr b/src/test/ui/rfc1623.stderr
index 5b665e18141..aabe088d63c 100644
--- a/src/test/ui/rfc1623.stderr
+++ b/src/test/ui/rfc1623.stderr
@@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier
 LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 =
    |                                          ^ expected named lifetime parameter
    |
-   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
+help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
+  --> $DIR/rfc1623.rs:8:29
+   |
+LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 =
+   |                             ^^^  ^^^
 
 error[E0106]: missing lifetime specifier
   --> $DIR/rfc1623.rs:10:39
@@ -12,7 +16,11 @@ error[E0106]: missing lifetime specifier
 LL |     &(non_elidable as fn(&u8, &u8) -> &u8);
    |                                       ^ expected named lifetime parameter
    |
-   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
+help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
+  --> $DIR/rfc1623.rs:10:26
+   |
+LL |     &(non_elidable as fn(&u8, &u8) -> &u8);
+   |                          ^^^  ^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr
index 7f5ff95938e..3b7936c5f44 100644
--- a/src/test/ui/suggestions/return-without-lifetime.stderr
+++ b/src/test/ui/suggestions/return-without-lifetime.stderr
@@ -10,7 +10,11 @@ error[E0106]: missing lifetime specifier
 LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() }
    |                                  ^ help: consider using the named lifetime: `&'a`
    |
-   = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from
+help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from
+  --> $DIR/return-without-lifetime.rs:5:20
+   |
+LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() }
+   |                    ^^^^^^^^^
 
 error[E0106]: missing lifetime specifier
   --> $DIR/return-without-lifetime.rs:7:35
@@ -18,7 +22,11 @@ error[E0106]: missing lifetime specifier
 LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() }
    |                                   ^ help: consider using the named lifetime: `&'a`
    |
-   = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from
+help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from
+  --> $DIR/return-without-lifetime.rs:7:20
+   |
+LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() }
+   |                    ^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr
index 0a028e44919..1e15196f8ec 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr
@@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier
 LL |     let _: dyn Foo(&isize, &usize) -> &usize;
    |                                       ^ expected named lifetime parameter
    |
-   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
+help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
+  --> $DIR/unboxed-closure-sugar-lifetime-elision.rs:26:20
+   |
+LL |     let _: dyn Foo(&isize, &usize) -> &usize;
+   |                    ^^^^^^  ^^^^^^
 help: consider introducing a named lifetime parameter
    |
 LL | fn main<'lifetime>() {
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 cf820249c80..801504627c0 100644
--- a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr
+++ b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr
@@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier
 LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } }
    |                              ^^ expected named lifetime parameter
    |
-   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y`
+help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y`
+  --> $DIR/in-fn-return-illegal.rs:5:11
+   |
+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 { } }
diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr
index 517904ee628..ef3ad18ee88 100644
--- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr
+++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr
@@ -30,7 +30,11 @@ error[E0106]: missing lifetime specifier
 LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y }
    |                                   ^^ expected named lifetime parameter
    |
-   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or `y`
+help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or `y`
+  --> $DIR/underscore-lifetime-binders.rs:16:12
+   |
+LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y }
+   |            ^^^^^^     ^^^^^^
 help: consider introducing a named lifetime parameter
    |
 LL | fn foo2<'lifetime>(_: &'_ u8, y: &'_ u8) -> &'lifetime u8 { y }