mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
When encountering an expected named lifetime and none are present, suggest adding one
This commit is contained in:
parent
6ba08755df
commit
78d3ea5484
@ -2398,6 +2398,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
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,
|
||||
);
|
||||
}
|
||||
|
||||
@ -2908,19 +2909,80 @@ fn add_missing_lifetime_specifiers_label(
|
||||
count: usize,
|
||||
lifetime_names: &FxHashSet<ast::Ident>,
|
||||
snippet: Option<&str>,
|
||||
missing_named_lifetime_spots: &[&hir::Generics<'_>],
|
||||
) {
|
||||
if count > 1 {
|
||||
err.span_label(span, format!("expected {} lifetime parameters", count));
|
||||
} else if let (1, Some(name), Some("&")) =
|
||||
(lifetime_names.len(), lifetime_names.iter().next(), snippet)
|
||||
{
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"consider using the named lifetime",
|
||||
format!("&{} ", name),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else {
|
||||
err.span_label(span, "expected lifetime parameter");
|
||||
let mut introduce_suggestion = vec![];
|
||||
if let Some(generics) = missing_named_lifetime_spots.iter().last() {
|
||||
introduce_suggestion.push(match &generics.params {
|
||||
[] => (generics.span, "<'lifetime>".to_string()),
|
||||
[param, ..] => (param.span.shrink_to_lo(), "'lifetime, ".to_string()),
|
||||
});
|
||||
}
|
||||
|
||||
match (lifetime_names.len(), lifetime_names.iter().next(), snippet) {
|
||||
(1, Some(name), Some("&")) => {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"consider using the named lifetime",
|
||||
format!("&{} ", name),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
(1, Some(name), Some("'_")) => {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"consider using the named lifetime",
|
||||
name.to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
(1, Some(name), Some(snippet)) if !snippet.ends_with(">") => {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"consider using the named lifetime",
|
||||
format!("{}<{}>", snippet, name),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
(0, _, Some("&")) => {
|
||||
err.span_label(span, "expected named lifetime parameter");
|
||||
if !introduce_suggestion.is_empty() {
|
||||
introduce_suggestion.push((span, "&'lifetime ".to_string()));
|
||||
err.multipart_suggestion(
|
||||
"consider introducing a named lifetime",
|
||||
introduce_suggestion,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
(0, _, Some("'_")) => {
|
||||
err.span_label(span, "expected named lifetime parameter");
|
||||
if !introduce_suggestion.is_empty() {
|
||||
introduce_suggestion.push((span, "'lifetime".to_string()));
|
||||
err.multipart_suggestion(
|
||||
"consider introducing a named lifetime",
|
||||
introduce_suggestion,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
(0, _, Some(snippet)) if !snippet.ends_with(">") => {
|
||||
err.span_label(span, "expected named lifetime parameter");
|
||||
if !introduce_suggestion.is_empty() {
|
||||
introduce_suggestion.push((span, format!("{}<'lifetime>", snippet)));
|
||||
err.multipart_suggestion(
|
||||
"consider introducing a named lifetime",
|
||||
introduce_suggestion,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
err.span_label(span, "expected lifetime parameter");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ struct Buzz<'a, 'b>(&'a str, &'b str);
|
||||
struct Quux {
|
||||
baz: Baz,
|
||||
//~^ ERROR E0106
|
||||
//~| expected lifetime parameter
|
||||
//~| expected named lifetime parameter
|
||||
buzz: Buzz,
|
||||
//~^ ERROR E0106
|
||||
//~| expected 2 lifetime parameters
|
||||
|
@ -2,25 +2,49 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/E0106.rs:2:8
|
||||
|
|
||||
LL | x: &bool,
|
||||
| ^ expected lifetime parameter
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime
|
||||
|
|
||||
LL | struct Foo<'lifetime> {
|
||||
LL | x: &'lifetime bool,
|
||||
|
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/E0106.rs:7:7
|
||||
|
|
||||
LL | B(&bool),
|
||||
| ^ expected lifetime parameter
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime
|
||||
|
|
||||
LL | enum Bar<'lifetime> {
|
||||
LL | A(u8),
|
||||
LL | B(&'lifetime bool),
|
||||
|
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/E0106.rs:10:14
|
||||
|
|
||||
LL | type MyStr = &str;
|
||||
| ^ expected lifetime parameter
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime
|
||||
|
|
||||
LL | type MyStr<'lifetime> = &'lifetime str;
|
||||
| ^^^^^^^^^^^ ^^^^^^^^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/E0106.rs:17:10
|
||||
|
|
||||
LL | baz: Baz,
|
||||
| ^^^ expected lifetime parameter
|
||||
| ^^^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime
|
||||
|
|
||||
LL | struct Quux<'lifetime> {
|
||||
LL | baz: Baz<'lifetime>,
|
||||
|
|
||||
|
||||
error[E0106]: missing lifetime specifiers
|
||||
--> $DIR/E0106.rs:20:11
|
||||
|
@ -2,13 +2,23 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/assoc-type.rs:11:19
|
||||
|
|
||||
LL | type Output = &i32;
|
||||
| ^ expected lifetime parameter
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime
|
||||
|
|
||||
LL | type Output<'lifetime> = &'lifetime i32;
|
||||
| ^^^^^^^^^^^ ^^^^^^^^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/assoc-type.rs:16:20
|
||||
|
|
||||
LL | type Output = &'_ i32;
|
||||
| ^^ expected lifetime parameter
|
||||
| ^^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime
|
||||
|
|
||||
LL | type Output<'lifetime> = &'lifetime i32;
|
||||
| ^^^^^^^^^^^ ^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -2,7 +2,12 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/issue-61124-anon-lifetime-in-struct-declaration.rs:8:19
|
||||
|
|
||||
LL | struct Heartbreak(Betrayal);
|
||||
| ^^^^^^^^ expected lifetime parameter
|
||||
| ^^^^^^^^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime
|
||||
|
|
||||
LL | struct Heartbreak<'lifetime>(Betrayal<'lifetime>);
|
||||
| ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,17 +2,25 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/issue-19707.rs:3:28
|
||||
|
|
||||
LL | type Foo = fn(&u8, &u8) -> &u8;
|
||||
| ^ expected lifetime parameter
|
||||
| ^ 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: consider introducing a named lifetime
|
||||
|
|
||||
LL | type Foo<'lifetime> = fn(&u8, &u8) -> &'lifetime u8;
|
||||
| ^^^^^^^^^^^ ^^^^^^^^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/issue-19707.rs:5:27
|
||||
|
|
||||
LL | fn bar<F: Fn(&u8, &u8) -> &u8>(f: &F) {}
|
||||
| ^ expected lifetime parameter
|
||||
| ^ 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: consider introducing a named lifetime
|
||||
|
|
||||
LL | fn bar<'lifetime, F: Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {}
|
||||
| ^^^^^^^^^^ ^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/issue-26638.rs:1:62
|
||||
|
|
||||
LL | fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() }
|
||||
| ^ expected lifetime parameter
|
||||
| ^ 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: consider introducing a named lifetime
|
||||
|
|
||||
LL | fn parse_type<'lifetime>(iter: Box<dyn Iterator<Item=&str>+'static>) -> &'lifetime str { iter.next() }
|
||||
| ^^^^^^^^^^^ ^^^^^^^^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/issue-26638.rs:4:40
|
||||
|
@ -2,25 +2,37 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/issue-30255.rs:9:24
|
||||
|
|
||||
LL | fn f(a: &S, b: i32) -> &i32 {
|
||||
| ^ expected lifetime parameter
|
||||
| ^ 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: consider introducing a named lifetime
|
||||
|
|
||||
LL | fn f<'lifetime>(a: &S, b: i32) -> &'lifetime i32 {
|
||||
| ^^^^^^^^^^^ ^^^^^^^^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/issue-30255.rs:14:34
|
||||
|
|
||||
LL | fn g(a: &S, b: bool, c: &i32) -> &i32 {
|
||||
| ^ expected lifetime parameter
|
||||
| ^ 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: consider introducing a named lifetime
|
||||
|
|
||||
LL | fn g<'lifetime>(a: &S, b: bool, c: &i32) -> &'lifetime i32 {
|
||||
| ^^^^^^^^^^^ ^^^^^^^^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/issue-30255.rs:19:44
|
||||
|
|
||||
LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 {
|
||||
| ^ expected lifetime parameter
|
||||
| ^ 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: consider introducing a named lifetime
|
||||
|
|
||||
LL | fn h<'lifetime>(a: &bool, b: bool, c: &S, d: &i32) -> &'lifetime i32 {
|
||||
| ^^^^^^^^^^^ ^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -10,17 +10,25 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:7:33
|
||||
|
|
||||
LL | fn g(_x: &isize, _y: &isize) -> &isize {
|
||||
| ^ expected lifetime parameter
|
||||
| ^ 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: consider introducing a named lifetime
|
||||
|
|
||||
LL | fn g<'lifetime>(_x: &isize, _y: &isize) -> &'lifetime isize {
|
||||
| ^^^^^^^^^^^ ^^^^^^^^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:19
|
||||
|
|
||||
LL | fn h(_x: &Foo) -> &isize {
|
||||
| ^ expected lifetime parameter
|
||||
| ^ 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: consider introducing a named lifetime
|
||||
|
|
||||
LL | fn h<'lifetime>(_x: &Foo) -> &'lifetime isize {
|
||||
| ^^^^^^^^^^^ ^^^^^^^^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:21:20
|
||||
|
@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/ex1b-return-no-names-if-else.rs:1:29
|
||||
|
|
||||
LL | fn foo(x: &i32, y: &i32) -> &i32 {
|
||||
| ^ expected lifetime parameter
|
||||
| ^ 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: consider introducing a named lifetime
|
||||
|
|
||||
LL | fn foo<'lifetime>(x: &i32, y: &i32) -> &'lifetime i32 {
|
||||
| ^^^^^^^^^^^ ^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,13 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/item-error.rs:10:8
|
||||
|
|
||||
LL | a: &u64
|
||||
| ^ expected lifetime parameter
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime
|
||||
|
|
||||
LL | struct A<'lifetime> {
|
||||
LL | a: &'lifetime u64
|
||||
|
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,13 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/regions-in-enums-anon.rs:4:9
|
||||
|
|
||||
LL | Bar(&isize)
|
||||
| ^ expected lifetime parameter
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime
|
||||
|
|
||||
LL | enum Foo<'lifetime> {
|
||||
LL | Bar(&'lifetime isize)
|
||||
|
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,13 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/regions-in-structs-anon.rs:4:8
|
||||
|
|
||||
LL | x: &isize
|
||||
| ^ expected lifetime parameter
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime
|
||||
|
|
||||
LL | struct Foo<'lifetime> {
|
||||
LL | x: &'lifetime isize
|
||||
|
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,7 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/rfc1623.rs:8:42
|
||||
|
|
||||
LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 =
|
||||
| ^ expected lifetime parameter
|
||||
| ^ 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
|
||||
|
||||
@ -10,7 +10,7 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/rfc1623.rs:10:39
|
||||
|
|
||||
LL | &(non_elidable as fn(&u8, &u8) -> &u8);
|
||||
| ^ expected lifetime parameter
|
||||
| ^ 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
|
||||
|
||||
|
@ -2,9 +2,18 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/unboxed-closure-sugar-lifetime-elision.rs:26:39
|
||||
|
|
||||
LL | let _: dyn Foo(&isize, &usize) -> &usize;
|
||||
| ^ expected lifetime parameter
|
||||
| ^ 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: consider introducing a named lifetime
|
||||
|
|
||||
LL | fn main<'lifetime>() {
|
||||
LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=&'a isize>,
|
||||
LL | dyn Foo(&isize) -> &isize >();
|
||||
LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=(&'a isize, &'a isize)>,
|
||||
LL | dyn Foo(&isize) -> (&isize, &isize) >();
|
||||
LL |
|
||||
...
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,13 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/dyn-trait-underscore-in-struct.rs:9:24
|
||||
|
|
||||
LL | x: Box<dyn Debug + '_>,
|
||||
| ^^ expected lifetime parameter
|
||||
| ^^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime
|
||||
|
|
||||
LL | struct Foo<'lifetime> {
|
||||
LL | x: Box<dyn Debug + 'lifetime>,
|
||||
|
|
||||
|
||||
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
|
||||
--> $DIR/dyn-trait-underscore-in-struct.rs:9:12
|
||||
|
@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/in-fn-return-illegal.rs:5:30
|
||||
|
|
||||
LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } }
|
||||
| ^^ expected lifetime parameter
|
||||
| ^^ 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: consider introducing a named lifetime
|
||||
|
|
||||
LL | fn foo<'lifetime>(x: &u32, y: &u32) -> &'lifetime u32 { loop { } }
|
||||
| ^^^^^^^^^^^ ^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,13 +2,25 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/in-struct.rs:6:9
|
||||
|
|
||||
LL | x: &'_ u32,
|
||||
| ^^ expected lifetime parameter
|
||||
| ^^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime
|
||||
|
|
||||
LL | struct Foo<'lifetime> {
|
||||
LL | x: &'lifetime u32,
|
||||
|
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/in-struct.rs:10:14
|
||||
|
|
||||
LL | Variant(&'_ u32),
|
||||
| ^^ expected lifetime parameter
|
||||
| ^^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime
|
||||
|
|
||||
LL | enum Bar<'lifetime> {
|
||||
LL | Variant(&'lifetime u32),
|
||||
|
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -14,7 +14,7 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/underscore-lifetime-binders.rs:2:17
|
||||
|
|
||||
LL | struct Baz<'a>(&'_ &'a u8);
|
||||
| ^^ expected lifetime parameter
|
||||
| ^^ help: consider using the named lifetime: `'a`
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/underscore-lifetime-binders.rs:10:33
|
||||
@ -28,9 +28,13 @@ error[E0106]: missing lifetime specifier
|
||||
--> $DIR/underscore-lifetime-binders.rs:16:35
|
||||
|
|
||||
LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y }
|
||||
| ^^ expected lifetime parameter
|
||||
| ^^ 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: consider introducing a named lifetime
|
||||
|
|
||||
LL | fn foo2<'lifetime>(_: &'_ u8, y: &'_ u8) -> &'lifetime u8 { y }
|
||||
| ^^^^^^^^^^^ ^^^^^^^^^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user