mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Rollup merge of #117914 - estebank:issue-85843, r=wesleywiser
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:
commit
ffdb471872
@ -8,7 +8,7 @@ use crate::{PathResult, PathSource, Segment};
|
||||
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,
|
||||
@ -2830,6 +2830,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
||||
.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();
|
||||
@ -2868,10 +2869,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
||||
|
||||
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",
|
||||
);
|
||||
if in_scope_lifetimes.is_empty() {
|
||||
maybe_static = true;
|
||||
in_scope_lifetimes = vec![(
|
||||
Ident::with_dummy_span(kw::StaticLifetime),
|
||||
(DUMMY_NODE_ID, LifetimeRes::Static),
|
||||
@ -2879,11 +2881,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
||||
}
|
||||
} 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",
|
||||
);
|
||||
if in_scope_lifetimes.is_empty() {
|
||||
maybe_static = true;
|
||||
in_scope_lifetimes = vec![(
|
||||
Ident::with_dummy_span(kw::StaticLifetime),
|
||||
(DUMMY_NODE_ID, LifetimeRes::Static),
|
||||
@ -2891,13 +2893,13 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
||||
}
|
||||
} 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}",
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -2962,11 +2964,238 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
||||
);
|
||||
}
|
||||
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
|
||||
|| lt.kind == MissingLifetimeKind::Underscore)
|
||||
{
|
||||
let pre = if lt.kind == MissingLifetimeKind::Ampersand
|
||||
&& 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 if let TyKind::ImplTrait(..) = ¶m.ty.kind {
|
||||
// We handle these in the next `else if` branch.
|
||||
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, you might want"
|
||||
} else if (lt.kind == MissingLifetimeKind::Ampersand
|
||||
|| lt.kind == MissingLifetimeKind::Underscore)
|
||||
&& let Some((kind, _span)) = self.diagnostic_metadata.current_function
|
||||
&& let FnKind::Fn(_, _, sig, _, _, _) = kind
|
||||
&& let ast::FnRetTy::Ty(ret_ty) = &sig.decl.output
|
||||
&& !sig.decl.inputs.is_empty()
|
||||
&& let arg_refs = sig
|
||||
.decl
|
||||
.inputs
|
||||
.iter()
|
||||
.filter_map(|param| match ¶m.ty.kind {
|
||||
TyKind::ImplTrait(_, bounds) => Some(bounds),
|
||||
_ => None,
|
||||
})
|
||||
.flat_map(|bounds| bounds.into_iter())
|
||||
.collect::<Vec<_>>()
|
||||
&& !arg_refs.is_empty()
|
||||
{
|
||||
// We have a situation like
|
||||
// fn g(mut x: impl Iterator<Item = &()>) -> Option<&()>
|
||||
// So we look at every ref in the trait bound. If there's any, we
|
||||
// suggest
|
||||
// fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()>
|
||||
let mut lt_finder =
|
||||
LifetimeFinder { lifetime: lt.span, found: None, seen: vec![] };
|
||||
for bound in arg_refs {
|
||||
if let ast::GenericBound::Trait(trait_ref, _) = bound {
|
||||
lt_finder.visit_trait_ref(&trait_ref.trait_ref);
|
||||
}
|
||||
}
|
||||
lt_finder.visit_ty(ret_ty);
|
||||
let spans_suggs: Vec<_> = lt_finder
|
||||
.seen
|
||||
.iter()
|
||||
.filter_map(|ty| match &ty.kind {
|
||||
TyKind::Ref(_, mut_ty) => {
|
||||
let span = ty.span.with_hi(mut_ty.ty.span.lo());
|
||||
Some((span, "&'a ".to_string()))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
self.suggest_introducing_lifetime(
|
||||
err,
|
||||
None,
|
||||
|err, higher_ranked, span, message, intro_sugg| {
|
||||
err.multipart_suggestion_verbose(
|
||||
message,
|
||||
std::iter::once((span, intro_sugg))
|
||||
.chain(spans_suggs.iter().cloned())
|
||||
.collect(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
higher_ranked
|
||||
},
|
||||
);
|
||||
"alternatively, you might want"
|
||||
} else {
|
||||
"instead, you are more likely to want"
|
||||
};
|
||||
let mut owned_sugg = lt.kind == MissingLifetimeKind::Ampersand;
|
||||
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, seen: vec![] };
|
||||
lt_finder.visit_ty(&ty);
|
||||
|
||||
if let [Ty { span, kind: TyKind::Ref(_, mut_ty), .. }] =
|
||||
<_finder.seen[..]
|
||||
{
|
||||
// We might have a situation like
|
||||
// fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()>
|
||||
// but `lt.span` only points at `'_`, so to suggest `-> Option<()>`
|
||||
// we need to find a more accurate span to end up with
|
||||
// fn g<'a>(mut x: impl Iterator<Item = &'_ ()>) -> Option<()>
|
||||
sugg = vec![(span.with_hi(mut_ty.ty.span.lo()), String::new())];
|
||||
owned_sugg = true;
|
||||
}
|
||||
if let Some(ty) = lt_finder.found {
|
||||
if let TyKind::Path(None, path) = &ty.kind {
|
||||
// Check if the path being borrowed is likely to be owned.
|
||||
let path: Vec<_> = Segment::from_path(path);
|
||||
match self.resolve_path(&path, Some(TypeNS), None) {
|
||||
PathResult::Module(ModuleOrUniformRoot::Module(module)) => {
|
||||
match module.res() {
|
||||
Some(Res::PrimTy(PrimTy::Str)) => {
|
||||
// Don't suggest `-> str`, suggest `-> String`.
|
||||
sugg = vec![(
|
||||
lt.span.with_hi(ty.span.hi()),
|
||||
"String".to_string(),
|
||||
)];
|
||||
}
|
||||
Some(Res::PrimTy(..)) => {}
|
||||
Some(Res::Def(
|
||||
DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::Enum
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::AssocTy
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::TyParam,
|
||||
_,
|
||||
)) => {}
|
||||
_ => {
|
||||
// Do not suggest in all other cases.
|
||||
owned_sugg = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
PathResult::NonModule(res) => {
|
||||
match res.base_res() {
|
||||
Res::PrimTy(PrimTy::Str) => {
|
||||
// Don't suggest `-> str`, suggest `-> String`.
|
||||
sugg = vec![(
|
||||
lt.span.with_hi(ty.span.hi()),
|
||||
"String".to_string(),
|
||||
)];
|
||||
}
|
||||
Res::PrimTy(..) => {}
|
||||
Res::Def(
|
||||
DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::Enum
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::AssocTy
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::TyParam,
|
||||
_,
|
||||
) => {}
|
||||
_ => {
|
||||
// Do not suggest in all other cases.
|
||||
owned_sugg = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// Do not suggest in all other cases.
|
||||
owned_sugg = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
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()),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
if owned_sugg {
|
||||
err.multipart_suggestion_verbose(
|
||||
format!("{pre} to return an owned value"),
|
||||
sugg,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Record as using the suggested resolution.
|
||||
let (_, (_, res)) = in_scope_lifetimes[0];
|
||||
@ -2996,7 +3225,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
||||
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 = {
|
||||
@ -3073,6 +3302,24 @@ pub(super) fn signal_lifetime_shadowing(sess: &Session, orig: Ident, shadower: I
|
||||
err.emit();
|
||||
}
|
||||
|
||||
struct LifetimeFinder<'ast> {
|
||||
lifetime: Span,
|
||||
found: Option<&'ast Ty>,
|
||||
seen: Vec<&'ast Ty>,
|
||||
}
|
||||
|
||||
impl<'ast> Visitor<'ast> for LifetimeFinder<'ast> {
|
||||
fn visit_ty(&mut self, t: &'ast Ty) {
|
||||
if let TyKind::Ref(_, mut_ty) = &t.kind {
|
||||
self.seen.push(t);
|
||||
if t.span.lo() == self.lifetime.lo() {
|
||||
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) {
|
||||
|
@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};
|
||||
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
|
||||
|
@ -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 1 previous error
|
||||
|
||||
|
@ -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 1 previous error
|
||||
|
||||
|
@ -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, you might want to return an owned value
|
||||
|
|
||||
LL - ) -> &usize {
|
||||
LL + ) -> usize {
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -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() {}
|
@ -1,5 +1,3 @@
|
||||
// run-rustfix
|
||||
|
||||
extern "C" {
|
||||
pub fn g(_: &u8) -> &u8; // OK
|
||||
pub fn f() -> &u8; //~ ERROR missing lifetime specifier
|
||||
|
@ -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 1 previous error
|
||||
|
||||
|
@ -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>> {
|
||||
| ~~~~~~~
|
||||
|
@ -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) {
|
||||
| ~~~~~~~
|
||||
|
@ -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 1 previous error
|
||||
|
||||
|
@ -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, you might 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
|
||||
|
@ -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, you might 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, you might 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
|
||||
|
@ -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, you might 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
|
||||
|
@ -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: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() }
|
||||
| ++++ ~~~ ~~~
|
||||
help: alternatively, you might 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: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | async fn i<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() }
|
||||
| ++++ ~~~ ~~~
|
||||
help: alternatively, you might 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,10 +47,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`, or if you will only have owned values
|
||||
|
|
||||
LL | fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
|
||||
| ~~~~~~~
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() }
|
||||
| ++++ ~~~ ~~~
|
||||
help: alternatively, you might 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:37:64
|
||||
@ -41,10 +68,19 @@ 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() }
|
||||
| ~~~~~~~
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | async fn i<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() }
|
||||
| ++++ ~~~ ~~~
|
||||
help: alternatively, you might 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:47:37
|
||||
@ -53,10 +89,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: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | fn g<'a>(mut x: impl Foo) -> Option<&'a ()> { x.next() }
|
||||
| ++++ ~~~
|
||||
help: alternatively, you might 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 +110,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: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | fn g<'a>(mut x: impl Foo<()>) -> Option<&'a ()> { x.next() }
|
||||
| ++++ ~~~
|
||||
help: alternatively, you might 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
|
||||
|
@ -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`, or if you will only have owned values
|
||||
|
|
||||
LL | fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
|
||||
| ~~~~~~~
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() }
|
||||
| ++++ ~~~ ~~~
|
||||
help: alternatively, you might 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.rs:16: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`, or if you will only have owned values
|
||||
|
|
||||
LL | async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
|
||||
| ~~~~~~~
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | async fn i<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() }
|
||||
| ++++ ~~~ ~~~
|
||||
help: alternatively, you might 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: lifetime may not live long enough
|
||||
--> $DIR/impl-trait-missing-lifetime.rs:16:69
|
||||
|
@ -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,7 +113,7 @@ 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());
|
||||
| +++++++
|
||||
|
@ -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, you might 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 {} }
|
||||
| +++++++ +++++++
|
||||
|
@ -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>>
|
||||
| ~~~~~~~
|
||||
|
Loading…
Reference in New Issue
Block a user