Use spans for input borrowed types unrelated to return type

This commit is contained in:
Esteban Küber 2020-01-27 11:48:52 -08:00
parent 183dfac1f3
commit 70dbf5526d
12 changed files with 104 additions and 25 deletions

View file

@ -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

View file

@ -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

View file

@ -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
|

View file

@ -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() }

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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

View file

@ -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

View file

@ -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>() {

View file

@ -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 { } }

View file

@ -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 }