On borrow return type, suggest borrowing from arg or owned return type

When we encounter a function with a return type that has an anonymous
lifetime with no argument to borrow from, besides suggesting the
`'static` lifetime we now also suggest changing the arguments to be
borrows or changing the return type to be an owned type.

```
error[E0106]: missing lifetime specifier
  --> $DIR/variadic-ffi-6.rs:7:6
   |
LL | ) -> &usize {
   |      ^ expected named lifetime parameter
   |
   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
   |
LL | ) -> &'static usize {
   |       +++++++
help: instead, you are more likely to want to change one of the arguments to be borrowed...
   |
LL |     x: &usize,
   |        +
help: ...or alternatively, to want to return an owned value
   |
LL - ) -> &usize {
LL + ) -> usize {
   |
```

Fix #85843.
This commit is contained in:
Esteban Küber 2023-11-14 20:36:49 +00:00
parent 3a85a5cfe7
commit b7a23bc08b
19 changed files with 305 additions and 57 deletions

View file

@ -8,7 +8,7 @@
use rustc_hir::def::Namespace::{self, *};
use rustc_ast::ptr::P;
use rustc_ast::visit::{FnCtxt, FnKind, LifetimeCtxt};
use rustc_ast::visit::{walk_ty, FnCtxt, FnKind, LifetimeCtxt, Visitor};
use rustc_ast::{
self as ast, AssocItemKind, Expr, ExprKind, GenericParam, GenericParamKind, Item, ItemKind,
MethodCall, NodeId, Path, Ty, TyKind, DUMMY_NODE_ID,
@ -2811,6 +2811,7 @@ fn add_missing_lifetime_specifiers_label(
.collect();
debug!(?in_scope_lifetimes);
let mut maybe_static = false;
debug!(?function_param_lifetimes);
if let Some((param_lifetimes, params)) = &function_param_lifetimes {
let elided_len = param_lifetimes.len();
@ -2849,9 +2850,10 @@ fn add_missing_lifetime_specifiers_label(
if num_params == 0 {
err.help(
"this function's return type contains a borrowed value, \
but there is no value for it to be borrowed from",
"this function's return type contains a borrowed value, but there is no value \
for it to be borrowed from",
);
maybe_static = true;
if in_scope_lifetimes.is_empty() {
in_scope_lifetimes = vec![(
Ident::with_dummy_span(kw::StaticLifetime),
@ -2860,10 +2862,10 @@ fn add_missing_lifetime_specifiers_label(
}
} else if elided_len == 0 {
err.help(
"this function's return type contains a borrowed value with \
an elided lifetime, but the lifetime cannot be derived from \
the arguments",
"this function's return type contains a borrowed value with an elided \
lifetime, but the lifetime cannot be derived from the arguments",
);
maybe_static = true;
if in_scope_lifetimes.is_empty() {
in_scope_lifetimes = vec![(
Ident::with_dummy_span(kw::StaticLifetime),
@ -2872,13 +2874,13 @@ fn add_missing_lifetime_specifiers_label(
}
} else if num_params == 1 {
err.help(format!(
"this function's return type contains a borrowed value, \
but the signature does not say which {m} it is borrowed from"
"this function's return type contains a borrowed value, but the signature does \
not say which {m} it is borrowed from",
));
} else {
err.help(format!(
"this function's return type contains a borrowed value, \
but the signature does not say whether it is borrowed from {m}"
"this function's return type contains a borrowed value, but the signature does \
not say whether it is borrowed from {m}",
));
}
}
@ -2943,11 +2945,107 @@ fn add_missing_lifetime_specifiers_label(
);
}
1 => {
let post = if maybe_static {
let owned = if let [lt] = &lifetime_refs[..]
&& lt.kind != MissingLifetimeKind::Ampersand
{
", or if you will only have owned values"
} else {
""
};
format!(
", but this is uncommon unless you're returning a borrowed value from a \
`const` or a `static`{owned}",
)
} else {
String::new()
};
err.multipart_suggestion_verbose(
format!("consider using the `{existing_name}` lifetime"),
format!("consider using the `{existing_name}` lifetime{post}"),
spans_suggs,
Applicability::MaybeIncorrect,
);
if maybe_static {
// FIXME: what follows are general suggestions, but we'd want to perform some
// minimal flow analysis to provide more accurate suggestions. For example, if
// we identified that the return expression references only one argument, we
// would suggest borrowing only that argument, and we'd skip the prior
// "use `'static`" suggestion entirely.
if let [lt] = &lifetime_refs[..] && lt.kind == MissingLifetimeKind::Ampersand {
let pre = if let Some((kind, _span)) =
self.diagnostic_metadata.current_function
&& let FnKind::Fn(_, _, sig, _, _, _) = kind
&& !sig.decl.inputs.is_empty()
&& let sugg = sig
.decl
.inputs
.iter()
.filter_map(|param| {
if param.ty.span.contains(lt.span) {
// We don't want to suggest `fn elision(_: &fn() -> &i32)`
// when we have `fn elision(_: fn() -> &i32)`
None
} else if let TyKind::CVarArgs = param.ty.kind {
// Don't suggest `&...` for ffi fn with varargs
None
} else {
Some((param.ty.span.shrink_to_lo(), "&".to_string()))
}
})
.collect::<Vec<_>>()
&& !sugg.is_empty()
{
let (the, s) = if sig.decl.inputs.len() == 1 {
("the", "")
} else {
("one of the", "s")
};
err.multipart_suggestion_verbose(
format!(
"instead, you are more likely to want to change {the} \
argument{s} to be borrowed...",
),
sugg,
Applicability::MaybeIncorrect,
);
"...or alternatively,"
} else {
"instead, you are more likely"
};
let mut sugg = vec![(lt.span, String::new())];
if let Some((kind, _span)) =
self.diagnostic_metadata.current_function
&& let FnKind::Fn(_, _, sig, _, _, _) = kind
&& let ast::FnRetTy::Ty(ty) = &sig.decl.output
{
let mut lt_finder = LifetimeFinder { lifetime: lt.span, found: None };
lt_finder.visit_ty(&ty);
if let Some(ty) = lt_finder.found {
if let TyKind::Path(None, Path { segments, .. }) = &ty.kind
&& segments.len() == 1
&& segments[0].ident.name == sym::str
{
// Don't suggest `-> str`, suggest `-> String`.
sugg = vec![(lt.span.with_hi(ty.span.hi()), "String".to_string())];
}
if let TyKind::Slice(inner_ty) = &ty.kind {
// Don't suggest `-> [T]`, suggest `-> Vec<T>`.
sugg = vec![
(lt.span.with_hi(inner_ty.span.lo()), "Vec<".to_string()),
(ty.span.with_lo(inner_ty.span.hi()), ">".to_string()),
];
}
}
};
err.multipart_suggestion_verbose(
format!("{pre} to want to return an owned value"),
sugg,
Applicability::MaybeIncorrect,
);
}
}
// Record as using the suggested resolution.
let (_, (_, res)) = in_scope_lifetimes[0];
@ -2977,7 +3075,7 @@ fn add_missing_lifetime_specifiers_label(
fn mk_where_bound_predicate(
path: &Path,
poly_trait_ref: &ast::PolyTraitRef,
ty: &ast::Ty,
ty: &Ty,
) -> Option<ast::WhereBoundPredicate> {
use rustc_span::DUMMY_SP;
let modified_segments = {
@ -3054,6 +3152,22 @@ pub(super) fn signal_lifetime_shadowing(sess: &Session, orig: Ident, shadower: I
err.emit();
}
struct LifetimeFinder<'ast> {
lifetime: Span,
found: Option<&'ast Ty>,
}
impl<'ast> Visitor<'ast> for LifetimeFinder<'ast> {
fn visit_ty(&mut self, t: &'ast Ty) {
if t.span.lo() == self.lifetime.lo()
&& let TyKind::Ref(_, mut_ty) = &t.kind
{
self.found = Some(&mut_ty.ty);
}
walk_ty(self, t)
}
}
/// Shadowing involving a label is only a warning for historical reasons.
//FIXME: make this a proper lint.
pub(super) fn signal_label_shadowing(sess: &Session, orig: Span, shadower: Ident) {

View file

@ -11,7 +11,7 @@
const ENTRY_LIMIT: usize = 900;
// FIXME: The following limits should be reduced eventually.
const ISSUES_ENTRY_LIMIT: usize = 1852;
const ROOT_ENTRY_LIMIT: usize = 867;
const ROOT_ENTRY_LIMIT: usize = 866;
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
"rs", // test source files

View file

@ -5,10 +5,15 @@ LL | fn elision<T: Fn() -> &i32>() {
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | fn elision<T: Fn() -> &'static i32>() {
| +++++++
help: instead, you are more likely to want to return an owned value
|
LL - fn elision<T: Fn() -> &i32>() {
LL + fn elision<T: Fn() -> i32>() {
|
error: aborting due to previous error

View file

@ -5,10 +5,15 @@ LL | fn elision(_: fn() -> &i32) {
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | fn elision(_: fn() -> &'static i32) {
| +++++++
help: instead, you are more likely to want to return an owned value
|
LL - fn elision(_: fn() -> &i32) {
LL + fn elision(_: fn() -> i32) {
|
error: aborting due to previous error

View file

@ -5,10 +5,19 @@ LL | ) -> &usize {
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | ) -> &'static usize {
| +++++++
help: instead, you are more likely to want to change one of the arguments to be borrowed...
|
LL | x: &usize,
| +
help: ...or alternatively, to want to return an owned value
|
LL - ) -> &usize {
LL + ) -> usize {
|
error: aborting due to previous error

View file

@ -1,8 +0,0 @@
// run-rustfix
extern "C" {
pub fn g(_: &u8) -> &u8; // OK
pub fn f() -> &'static u8; //~ ERROR missing lifetime specifier
}
fn main() {}

View file

@ -1,5 +1,3 @@
// run-rustfix
extern "C" {
pub fn g(_: &u8) -> &u8; // OK
pub fn f() -> &u8; //~ ERROR missing lifetime specifier

View file

@ -1,14 +1,19 @@
error[E0106]: missing lifetime specifier
--> $DIR/foreign-fn-return-lifetime.rs:5:19
--> $DIR/foreign-fn-return-lifetime.rs:3:19
|
LL | pub fn f() -> &u8;
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | pub fn f() -> &'static u8;
| +++++++
help: instead, you are more likely to want to return an owned value
|
LL - pub fn f() -> &u8;
LL + pub fn f() -> u8;
|
error: aborting due to previous error

View file

@ -11,7 +11,7 @@ LL | fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'_>> {
| ^^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
|
LL | fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'static>> {
| ~~~~~~~

View file

@ -5,7 +5,7 @@ LL | fn d() -> impl Fn() -> (impl Debug + '_) {
| ^^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
|
LL | fn d() -> impl Fn() -> (impl Debug + 'static) {
| ~~~~~~~

View file

@ -5,10 +5,14 @@ LL | &str
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | &'static str
| +++++++
help: instead, you are more likely to want to return an owned value
|
LL | String
| ~~~~~~
error: aborting due to previous error

View file

@ -17,10 +17,18 @@ LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &'static str { iter() }
| +++++++
help: instead, you are more likely to want to change the argument to be borrowed...
|
LL | fn parse_type_2(iter: &fn(&u8)->&u8) -> &str { iter() }
| +
help: ...or alternatively, to want to return an owned value
|
LL | fn parse_type_2(iter: fn(&u8)->&u8) -> String { iter() }
| ~~~~~~
error[E0106]: missing lifetime specifier
--> $DIR/issue-26638.rs:10:22
@ -29,10 +37,14 @@ LL | fn parse_type_3() -> &str { unimplemented!() }
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | fn parse_type_3() -> &'static str { unimplemented!() }
| +++++++
help: instead, you are more likely to want to return an owned value
|
LL | fn parse_type_3() -> String { unimplemented!() }
| ~~~~~~
error[E0308]: mismatched types
--> $DIR/issue-26638.rs:1:69

View file

@ -5,10 +5,15 @@ LL | fn f() -> &isize {
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | fn f() -> &'static isize {
| +++++++
help: instead, you are more likely to want to return an owned value
|
LL - fn f() -> &isize {
LL + fn f() -> isize {
|
error[E0106]: missing lifetime specifier
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:7:33
@ -41,10 +46,19 @@ LL | fn i(_x: isize) -> &isize {
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | fn i(_x: isize) -> &'static isize {
| +++++++
help: instead, you are more likely to want to change the argument to be borrowed...
|
LL | fn i(_x: &isize) -> &isize {
| +
help: ...or alternatively, to want to return an owned value
|
LL - fn i(_x: isize) -> &isize {
LL + fn i(_x: isize) -> isize {
|
error[E0106]: missing lifetime specifier
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:34:24
@ -53,10 +67,19 @@ LL | fn j(_x: StaticStr) -> &isize {
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | fn j(_x: StaticStr) -> &'static isize {
| +++++++
help: instead, you are more likely to want to change the argument to be borrowed...
|
LL | fn j(_x: &StaticStr) -> &isize {
| +
help: ...or alternatively, to want to return an owned value
|
LL - fn j(_x: StaticStr) -> &isize {
LL + fn j(_x: StaticStr) -> isize {
|
error[E0106]: missing lifetime specifier
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:40:49
@ -65,10 +88,19 @@ LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &isize {
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'a` lifetime
help: consider using the `'a` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &'a isize {
| ++
help: instead, you are more likely to want to change the argument to be borrowed...
|
LL | fn k<'a, T: WithLifetime<'a>>(_x: &T::Output) -> &isize {
| +
help: ...or alternatively, to want to return an owned value
|
LL - fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &isize {
LL + fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> isize {
|
error[E0106]: missing lifetime specifier
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:45:37
@ -77,10 +109,18 @@ LL | fn l<'a>(_: &'a str, _: &'a str) -> &str { "" }
| ------- ------- ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
help: consider using the `'a` lifetime
help: consider using the `'a` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | fn l<'a>(_: &'a str, _: &'a str) -> &'a str { "" }
| ++
help: instead, you are more likely to want to change one of the arguments to be borrowed...
|
LL | fn l<'a>(_: &&'a str, _: &&'a str) -> &str { "" }
| + +
help: ...or alternatively, to want to return an owned value
|
LL | fn l<'a>(_: &'a str, _: &'a str) -> String { "" }
| ~~~~~~
error: aborting due to 7 previous errors

View file

@ -21,10 +21,19 @@ LL | fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() {
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &'static () {
| +++++++
help: instead, you are more likely to want to change the argument to be borrowed...
|
LL | fn wrap(self: &Wrap<{ fn bar(&self) {} }>) -> &() {
| +
help: ...or alternatively, to want to return an owned value
|
LL - fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() {
LL + fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> () {
|
error[E0412]: cannot find type `Wrap` in this scope
--> $DIR/nested-item.rs:5:15

View file

@ -5,10 +5,19 @@ LL | fn g(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | fn g(mut x: impl Iterator<Item = &()>) -> Option<&'static ()> { x.next() }
| +++++++
help: instead, you are more likely to want to change the argument to be borrowed...
|
LL | fn g(mut x: &impl Iterator<Item = &()>) -> Option<&()> { x.next() }
| +
help: ...or alternatively, to want to return an owned value
|
LL - fn g(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
LL + fn g(mut x: impl Iterator<Item = &()>) -> Option<()> { x.next() }
|
error[E0106]: missing lifetime specifier
--> $DIR/impl-trait-missing-lifetime-gated.rs:19:60
@ -17,10 +26,19 @@ LL | async fn i(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next()
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | async fn i(mut x: impl Iterator<Item = &()>) -> Option<&'static ()> { x.next() }
| +++++++
help: instead, you are more likely to want to change the argument to be borrowed...
|
LL | async fn i(mut x: &impl Iterator<Item = &()>) -> Option<&()> { x.next() }
| +
help: ...or alternatively, to want to return an owned value
|
LL - async fn i(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
LL + async fn i(mut x: impl Iterator<Item = &()>) -> Option<()> { x.next() }
|
error[E0106]: missing lifetime specifier
--> $DIR/impl-trait-missing-lifetime-gated.rs:27:58
@ -29,7 +47,7 @@ LL | fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next()
| ^^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
|
LL | fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
| ~~~~~~~
@ -41,7 +59,7 @@ LL | async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.n
| ^^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
|
LL | async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
| ~~~~~~~
@ -53,10 +71,19 @@ LL | fn g(mut x: impl Foo) -> Option<&()> { x.next() }
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | fn g(mut x: impl Foo) -> Option<&'static ()> { x.next() }
| +++++++
help: instead, you are more likely to want to change the argument to be borrowed...
|
LL | fn g(mut x: &impl Foo) -> Option<&()> { x.next() }
| +
help: ...or alternatively, to want to return an owned value
|
LL - fn g(mut x: impl Foo) -> Option<&()> { x.next() }
LL + fn g(mut x: impl Foo) -> Option<()> { x.next() }
|
error[E0106]: missing lifetime specifier
--> $DIR/impl-trait-missing-lifetime-gated.rs:58:41
@ -65,10 +92,19 @@ LL | fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() }
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | fn g(mut x: impl Foo<()>) -> Option<&'static ()> { x.next() }
| +++++++
help: instead, you are more likely to want to change the argument to be borrowed...
|
LL | fn g(mut x: &impl Foo<()>) -> Option<&()> { x.next() }
| +
help: ...or alternatively, to want to return an owned value
|
LL - fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() }
LL + fn g(mut x: impl Foo<()>) -> Option<()> { x.next() }
|
error[E0658]: anonymous lifetimes in `impl Trait` are unstable
--> $DIR/impl-trait-missing-lifetime-gated.rs:6:35

View file

@ -5,7 +5,7 @@ LL | fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
| ^^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
|
LL | fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
| ~~~~~~~
@ -17,7 +17,7 @@ LL | async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next(
| ^^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
|
LL | async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
| ~~~~~~~

View file

@ -5,7 +5,7 @@ LL | static a: RefCell<HashMap<i32, Vec<Vec<Foo>>>> = RefCell::new(HashMap::
| ^^^ expected 2 lifetime parameters
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
|
LL | static a: RefCell<HashMap<i32, Vec<Vec<Foo<'static, 'static>>>>> = RefCell::new(HashMap::new());
| ++++++++++++++++++
@ -32,7 +32,7 @@ LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap:
| expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | static b: RefCell<HashMap<i32, Vec<Vec<&'static Bar<'static, 'static>>>>> = RefCell::new(HashMap::new());
| +++++++ ++++++++++++++++++
@ -59,7 +59,7 @@ LL | static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(Hash
| ^ expected 2 lifetime parameters
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
|
LL | static c: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
| +++++++++++++++++
@ -86,7 +86,7 @@ LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(Has
| expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
| +++++++ +++++++++++++++++
@ -113,10 +113,15 @@ LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| +++++++
help: instead, you are more likely to want to return an owned value
|
LL - static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
LL + static f: RefCell<HashMap<i32, Vec<Vec<Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
|
error[E0106]: missing lifetime specifier
--> $DIR/missing-lifetime-specifier.rs:47:44

View file

@ -5,10 +5,15 @@ LL | fn f1() -> &i32 { loop {} }
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | fn f1() -> &'static i32 { loop {} }
| +++++++
help: instead, you are more likely to want to return an owned value
|
LL - fn f1() -> &i32 { loop {} }
LL + fn f1() -> i32 { loop {} }
|
error[E0106]: missing lifetime specifiers
--> $DIR/return-elided-lifetime.rs:8:14
@ -19,7 +24,7 @@ LL | fn f1_() -> (&i32, &i32) { loop {} }
| expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | fn f1_() -> (&'static i32, &'static i32) { loop {} }
| +++++++ +++++++
@ -31,10 +36,19 @@ LL | fn f2(a: i32, b: i32) -> &i32 { loop {} }
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | fn f2(a: i32, b: i32) -> &'static i32 { loop {} }
| +++++++
help: instead, you are more likely to want to change one of the arguments to be borrowed...
|
LL | fn f2(a: &i32, b: &i32) -> &i32 { loop {} }
| + +
help: ...or alternatively, to want to return an owned value
|
LL - fn f2(a: i32, b: i32) -> &i32 { loop {} }
LL + fn f2(a: i32, b: i32) -> i32 { loop {} }
|
error[E0106]: missing lifetime specifiers
--> $DIR/return-elided-lifetime.rs:13:28
@ -45,7 +59,7 @@ LL | fn f2_(a: i32, b: i32) -> (&i32, &i32) { loop {} }
| expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
|
LL | fn f2_(a: i32, b: i32) -> (&'static i32, &'static i32) { loop {} }
| +++++++ +++++++

View file

@ -28,7 +28,7 @@ LL | fn meh() -> Box<dyn for<'_> Meh<'_>>
| ^^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
|
LL | fn meh() -> Box<dyn for<'_> Meh<'static>>
| ~~~~~~~