Account for returned dyn Trait evaluating to 'static lifetime

Provide a suggestion for `dyn Trait + '_` when possible.
This commit is contained in:
Esteban Küber 2020-05-26 13:13:19 -07:00
parent a724d9a4fb
commit 65f492be12
19 changed files with 239 additions and 142 deletions

View file

@ -55,9 +55,9 @@ pub fn try_report(&self) -> Option<ErrorReported> {
diag.emit();
ErrorReported
})
.or_else(|| self.try_report_impl_not_conforming_to_trait())
.or_else(|| self.try_report_anon_anon_conflict())
.or_else(|| self.try_report_static_impl_trait())
.or_else(|| self.try_report_impl_not_conforming_to_trait())
}
pub fn regions(&self) -> Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)> {

View file

@ -21,8 +21,8 @@ pub(super) fn try_report_named_anon_conflict(&self) -> Option<DiagnosticBuilder<
// where the anonymous region appears (there must always be one; we
// only introduced anonymous regions in parameters) as well as a
// version new_ty of its type where the anonymous region is replaced
// with the named one.//scope_def_id
let (named, anon, anon_param_info, region_info) = if self.is_named_region(sub)
// with the named one.
let (named, anon, anon_param_info, region_info) = if sub.has_name()
&& self.tcx().is_suitable_region(sup).is_some()
&& self.find_param_with_region(sup, sub).is_some()
{
@ -32,7 +32,7 @@ pub(super) fn try_report_named_anon_conflict(&self) -> Option<DiagnosticBuilder<
self.find_param_with_region(sup, sub).unwrap(),
self.tcx().is_suitable_region(sup).unwrap(),
)
} else if self.is_named_region(sup)
} else if sup.has_name()
&& self.tcx().is_suitable_region(sub).is_some()
&& self.find_param_with_region(sub, sup).is_some()
{
@ -74,24 +74,21 @@ pub(super) fn try_report_named_anon_conflict(&self) -> Option<DiagnosticBuilder<
}
if let Some((_, fndecl)) = self.find_anon_type(anon, &br) {
let return_type_anon = self.is_return_type_anon(scope_def_id, br, fndecl);
let is_self_anon = self.is_self_anon(is_first, scope_def_id);
debug!(
"try_report_named_anon_conflict: fndecl {:?} {:?} {}",
fndecl, return_type_anon, is_self_anon
);
if is_self_anon {
// We used to check for `return_type_anon.is_some()` here. Removing that improves
// some diagnostics, but we might have to readd the check if there are regressions
// in the wild.
return None;
}
if let FnRetTy::Return(ty) = &fndecl.output {
let mut v = ty::TraitObjectVisitor(vec![]);
rustc_hir::intravisit::walk_ty(&mut v, ty);
debug!("try_report_named_anon_conflict: ret ty {:?}", ty);
if let (TyKind::Def(_, _), ty::ReStatic) = (&ty.kind, sub) {
if sub == &ty::ReStatic && (matches!(ty.kind, TyKind::Def(_, _)) || v.0.len() == 1)
{
debug!("try_report_named_anon_conflict: impl Trait + 'static");
// This is an impl Trait return that evaluates de need of 'static.
// We handle this case better in `static_impl_trait`.
// This is an `impl Trait` or `dyn Trait` return that evaluates de need of
// `'static`. We handle this case better in `static_impl_trait`.
return None;
}
}
@ -123,17 +120,4 @@ pub(super) fn try_report_named_anon_conflict(&self) -> Option<DiagnosticBuilder<
Some(diag)
}
// This method returns whether the given Region is Named
pub(super) fn is_named_region(&self, region: ty::Region<'tcx>) -> bool {
match *region {
ty::ReStatic => true,
ty::ReFree(ref free_region) => match free_region.bound_region {
ty::BrNamed(..) => true,
_ => false,
},
ty::ReEarlyBound(ebr) => ebr.has_name(),
_ => false,
}
}
}

View file

@ -20,16 +20,14 @@ pub(super) fn try_report_static_impl_trait(&self) -> Option<ErrorReported> {
) = error.clone()
{
let anon_reg_sup = self.tcx().is_suitable_region(sup_r)?;
let return_ty = self.tcx().return_type_impl_trait(anon_reg_sup.def_id);
if sub_r == &RegionKind::ReStatic && return_ty.is_some() {
let (fn_return_span, is_dyn) =
self.tcx().return_type_impl_or_dyn_trait(anon_reg_sup.def_id)?;
if sub_r == &RegionKind::ReStatic {
let sp = var_origin.span();
let return_sp = sub_origin.span();
let mut err =
self.tcx().sess.struct_span_err(sp, "cannot infer an appropriate lifetime");
err.span_label(
return_sp,
"this return type evaluates to the `'static` lifetime...",
);
err.span_label(return_sp, "this evaluates to the `'static` lifetime...");
err.span_label(sup_origin.span(), "...but this borrow...");
let (lifetime, lt_sp_opt) = msg_span_from_free_region(self.tcx(), sup_r);
@ -39,24 +37,22 @@ pub(super) fn try_report_static_impl_trait(&self) -> Option<ErrorReported> {
let lifetime_name =
if sup_r.has_name() { sup_r.to_string() } else { "'_".to_owned() };
let fn_return_span = return_ty.unwrap().1;
if let Ok(snippet) =
self.tcx().sess.source_map().span_to_snippet(fn_return_span)
{
// only apply this suggestion onto functions with
// explicit non-desugar'able return.
if fn_return_span.desugaring_kind().is_none() {
err.span_suggestion(
fn_return_span,
&format!(
"you can add a bound to the return type to make it last less \
than `'static` and match {}",
lifetime
),
format!("{} + {}", snippet, lifetime_name),
Applicability::Unspecified,
);
}
// only apply this suggestion onto functions with
// explicit non-desugar'able return.
if fn_return_span.desugaring_kind().is_none() {
let msg = format!(
"you can add a bound to the returned `{} Trait` to make it last less \
than `'static` and match {}",
if is_dyn { "dyn" } else { "impl" },
lifetime
);
// FIXME: account for the need of parens in `&(dyn Trait + '_)`
err.span_suggestion_verbose(
fn_return_span.shrink_to_hi(),
&msg,
format!(" + {}", lifetime_name),
Applicability::MaybeIncorrect,
);
}
err.emit();
return Some(ErrorReported);

View file

@ -1,38 +1,27 @@
//! Type context book-keeping.
use crate::arena::Arena;
use crate::dep_graph::DepGraph;
use crate::dep_graph::{self, DepConstructor};
use crate::dep_graph::{self, DepConstructor, DepGraph};
use crate::hir::exports::Export;
use crate::ich::{NodeIdHashingMode, StableHashingContext};
use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
use crate::lint::LintDiagnosticBuilder;
use crate::lint::{struct_lint_level, LintSource};
use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintSource};
use crate::middle;
use crate::middle::cstore::CrateStoreDyn;
use crate::middle::cstore::EncodedMetadata;
use crate::middle::cstore::{CrateStoreDyn, EncodedMetadata};
use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault};
use crate::middle::stability;
use crate::mir::interpret::{Allocation, ConstValue, Scalar};
use crate::mir::{interpret, Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted};
use crate::mir::interpret::{self, Allocation, ConstValue, Scalar};
use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted};
use crate::traits;
use crate::ty::query;
use crate::ty::steal::Steal;
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
use crate::ty::subst::{GenericArgKind, UserSubsts};
use crate::ty::CanonicalPolyFnSig;
use crate::ty::GenericParamDefKind;
use crate::ty::RegionKind;
use crate::ty::ReprOptions;
use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts};
use crate::ty::TyKind::*;
use crate::ty::{self, DefIdTree, Ty, TypeAndMut};
use crate::ty::{AdtDef, AdtKind, Const, Region};
use crate::ty::{BindingMode, BoundVar};
use crate::ty::{ConstVid, FloatVar, FloatVid, IntVar, IntVid, TyVar, TyVid};
use crate::ty::{ExistentialPredicate, Predicate, PredicateKind};
use crate::ty::{InferConst, ParamConst};
use crate::ty::{InferTy, ParamTy, PolyFnSig, ProjectionTy};
use crate::ty::{List, TyKind, TyS};
use crate::ty::{
self, query, AdtDef, AdtKind, BindingMode, BoundVar, CanonicalPolyFnSig, Const, ConstVid,
DefIdTree, ExistentialPredicate, FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy,
IntVar, IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, ProjectionTy,
Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut,
};
use rustc_ast::ast;
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_attr as attr;
@ -48,10 +37,8 @@
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
use rustc_hir::definitions::{DefPathHash, Definitions};
use rustc_hir::lang_items;
use rustc_hir::lang_items::PanicLocationLangItem;
use rustc_hir::{HirId, Node, TraitCandidate};
use rustc_hir::{ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet};
use rustc_hir::lang_items::{self, PanicLocationLangItem};
use rustc_hir::{HirId, ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet, Node, TraitCandidate};
use rustc_index::vec::{Idx, IndexVec};
use rustc_macros::HashStable;
use rustc_session::config::{BorrowckMode, CrateType, OutputFilenames};
@ -1396,6 +1383,66 @@ pub fn is_suitable_region(&self, region: Region<'tcx>) -> Option<FreeRegionInfo>
})
}
pub fn return_type_impl_or_dyn_trait(&self, scope_def_id: DefId) -> Option<(Span, bool)> {
let hir_id = self.hir().as_local_hir_id(scope_def_id.expect_local());
let hir_output = match self.hir().get(hir_id) {
Node::Item(hir::Item {
kind:
ItemKind::Fn(
hir::FnSig {
decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. },
..
},
..,
),
..
})
| Node::ImplItem(hir::ImplItem {
kind:
hir::ImplItemKind::Fn(
hir::FnSig {
decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. },
..
},
_,
),
..
})
| Node::TraitItem(hir::TraitItem {
kind:
hir::TraitItemKind::Fn(
hir::FnSig {
decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. },
..
},
_,
),
..
}) => ty,
_ => return None,
};
let ret_ty = self.type_of(scope_def_id);
match ret_ty.kind {
ty::FnDef(_, _) => {
let sig = ret_ty.fn_sig(*self);
let output = self.erase_late_bound_regions(&sig.output());
if output.is_impl_trait() {
let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap();
Some((fn_decl.output.span(), false))
} else {
let mut v = TraitObjectVisitor(vec![]);
rustc_hir::intravisit::walk_ty(&mut v, hir_output);
if v.0.len() == 1 {
return Some((v.0[0], true));
}
None
}
}
_ => None,
}
}
pub fn return_type_impl_trait(&self, scope_def_id: DefId) -> Option<(Ty<'tcx>, Span)> {
// HACK: `type_of_def_id()` will fail on these (#55796), so return `None`.
let hir_id = self.hir().as_local_hir_id(scope_def_id.expect_local());

View file

@ -249,3 +249,22 @@ pub fn suggest_constraining_type_param(
true
}
}
pub struct TraitObjectVisitor(pub Vec<rustc_span::Span>);
impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor {
type Map = rustc_hir::intravisit::ErasedMap<'v>;
fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<Self::Map> {
hir::intravisit::NestedVisitorMap::None
}
fn visit_ty(&mut self, ty: &hir::Ty<'_>) {
if let hir::TyKind::TraitObject(
_,
hir::Lifetime { name: hir::LifetimeName::ImplicitObjectLifetimeDefault, .. },
) = ty.kind
{
self.0.push(ty.span);
}
}
}

View file

@ -4,7 +4,7 @@ error: cannot infer an appropriate lifetime
LL | pub async fn run_dummy_fn(&self) {
| ^^^^^ ...but this borrow...
LL | foo(|| self.bar()).await;
| --- this return type evaluates to the `'static` lifetime...
| --- this evaluates to the `'static` lifetime...
|
note: ...can't outlive the lifetime `'_` as defined on the method body at 12:31
--> $DIR/issue-62097.rs:12:31

View file

@ -4,17 +4,17 @@ error: cannot infer an appropriate lifetime
LL | fn elided(x: &i32) -> impl Copy { x }
| --------- ^ ...but this borrow...
| |
| this return type evaluates to the `'static` lifetime...
| this evaluates to the `'static` lifetime...
|
note: ...can't outlive the anonymous lifetime #1 defined on the function body at 3:1
--> $DIR/must_outlive_least_region_or_bound.rs:3:1
|
LL | fn elided(x: &i32) -> impl Copy { x }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: you can add a bound to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the function body at 3:1
help: you can add a bound to the returned `impl Trait` to make it last less than `'static` and match the anonymous lifetime #1 defined on the function body at 3:1
|
LL | fn elided(x: &i32) -> impl Copy + '_ { x }
| ^^^^^^^^^^^^^^
| ^^^^
error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:6:44
@ -22,17 +22,17 @@ error: cannot infer an appropriate lifetime
LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
| --------- ^ ...but this borrow...
| |
| this return type evaluates to the `'static` lifetime...
| this evaluates to the `'static` lifetime...
|
note: ...can't outlive the lifetime `'a` as defined on the function body at 6:13
--> $DIR/must_outlive_least_region_or_bound.rs:6:13
|
LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
| ^^
help: you can add a bound to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 6:13
help: you can add a bound to the returned `impl Trait` to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 6:13
|
LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
| ^^^^^^^^^^^^^^
| ^^^^
error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:12:69
@ -40,17 +40,17 @@ error: cannot infer an appropriate lifetime
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
| -------------------------------- ^ ...but this borrow...
| |
| this return type evaluates to the `'static` lifetime...
| this evaluates to the `'static` lifetime...
|
note: ...can't outlive the lifetime `'a` as defined on the function body at 12:15
--> $DIR/must_outlive_least_region_or_bound.rs:12:15
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
| ^^
help: you can add a bound to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 12:15
help: you can add a bound to the returned `impl Trait` to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 12:15
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static + 'a { x }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^
error[E0623]: lifetime mismatch
--> $DIR/must_outlive_least_region_or_bound.rs:17:61

View file

@ -2,7 +2,7 @@ error: cannot infer an appropriate lifetime
--> $DIR/static-return-lifetime-infered.rs:7:16
|
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
| ----------------------- this return type evaluates to the `'static` lifetime...
| ----------------------- this evaluates to the `'static` lifetime...
LL | self.x.iter().map(|a| a.0)
| ------ ^^^^
| |
@ -15,16 +15,16 @@ LL | / fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
LL | | self.x.iter().map(|a| a.0)
LL | | }
| |_____^
help: you can add a bound to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 6:5
help: you can add a bound to the returned `impl Trait` to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 6:5
|
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^
error: cannot infer an appropriate lifetime
--> $DIR/static-return-lifetime-infered.rs:11:16
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
| ----------------------- this return type evaluates to the `'static` lifetime...
| ----------------------- this evaluates to the `'static` lifetime...
LL | self.x.iter().map(|a| a.0)
| ------ ^^^^
| |
@ -35,10 +35,10 @@ note: ...can't outlive the lifetime `'a` as defined on the method body at 10:20
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
| ^^
help: you can add a bound to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the method body at 10:20
help: you can add a bound to the returned `impl Trait` to make it last less than `'static` and match the lifetime `'a` as defined on the method body at 10:20
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^
error: aborting due to 2 previous errors

View file

@ -2,7 +2,7 @@
fn foo<T: Any>(value: &T) -> Box<dyn Any> {
Box::new(value) as Box<dyn Any>
//~^ ERROR explicit lifetime required in the type of `value` [E0621]
//~^ ERROR cannot infer an appropriate lifetime
}
fn main() {

View file

@ -1,11 +1,24 @@
error[E0621]: explicit lifetime required in the type of `value`
--> $DIR/issue-16922.rs:4:5
error: cannot infer an appropriate lifetime
--> $DIR/issue-16922.rs:4:14
|
LL | fn foo<T: Any>(value: &T) -> Box<dyn Any> {
| -- help: add explicit lifetime `'static` to the type of `value`: `&'static T`
LL | Box::new(value) as Box<dyn Any>
| ^^^^^^^^^^^^^^^ lifetime `'static` required
| ---------^^^^^-
| | |
| | ...but this borrow...
| this evaluates to the `'static` lifetime...
|
note: ...can't outlive the anonymous lifetime #1 defined on the function body at 3:1
--> $DIR/issue-16922.rs:3:1
|
LL | / fn foo<T: Any>(value: &T) -> Box<dyn Any> {
LL | | Box::new(value) as Box<dyn Any>
LL | |
LL | | }
| |_^
help: you can add a bound to the returned `dyn Trait` to make it last less than `'static` and match the anonymous lifetime #1 defined on the function body at 3:1
|
LL | fn foo<T: Any>(value: &T) -> Box<dyn Any + '_> {
| ^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0621`.

View file

@ -15,7 +15,7 @@ fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
// `Box<SomeTrait>` defaults to a `'static` bound, so this return
// is illegal.
ss.r //~ ERROR explicit lifetime required in the type of `ss` [E0621]
ss.r //~ ERROR cannot infer an appropriate lifetime
}
fn store(ss: &mut SomeStruct, b: Box<dyn SomeTrait>) {

View file

@ -1,11 +1,26 @@
error[E0621]: explicit lifetime required in the type of `ss`
error: cannot infer an appropriate lifetime
--> $DIR/object-lifetime-default-from-box-error.rs:18:5
|
LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
| --------------- help: add explicit lifetime `'static` to the type of `ss`: `&mut SomeStruct<'static>`
...
LL | ss.r
| ^^^^ lifetime `'static` required
| ^^^^
| |
| this evaluates to the `'static` lifetime...
| ...but this borrow...
|
note: ...can't outlive the anonymous lifetime #2 defined on the function body at 14:1
--> $DIR/object-lifetime-default-from-box-error.rs:14:1
|
LL | / fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
LL | | // `Box<SomeTrait>` defaults to a `'static` bound, so this return
LL | | // is illegal.
LL | |
LL | | ss.r
LL | | }
| |_^
help: you can add a bound to the returned `dyn Trait` to make it last less than `'static` and match the anonymous lifetime #2 defined on the function body at 14:1
|
LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait + '_> {
| ^^^^
error[E0621]: explicit lifetime required in the type of `ss`
--> $DIR/object-lifetime-default-from-box-error.rs:31:12

View file

@ -11,20 +11,17 @@ fn a(v: &[u8]) -> Box<dyn Foo + 'static> {
}
fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
Box::new(v)
//~^ ERROR explicit lifetime required in the type of `v` [E0621]
Box::new(v) //~ ERROR explicit lifetime required in the type of `v` [E0621]
}
fn c(v: &[u8]) -> Box<dyn Foo> {
// same as previous case due to RFC 599
Box::new(v)
//~^ ERROR explicit lifetime required in the type of `v` [E0621]
Box::new(v) //~ ERROR cannot infer an appropriate lifetime
}
fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
Box::new(v)
//~^ ERROR cannot infer an appropriate lifetime due to conflicting
Box::new(v) //~ ERROR cannot infer an appropriate lifetime due to conflicting
}
fn e<'a:'b,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {

View file

@ -14,40 +14,54 @@ LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
LL | Box::new(v)
| ^^^^^^^^^^^ lifetime `'static` required
error[E0621]: explicit lifetime required in the type of `v`
--> $DIR/region-object-lifetime-in-coercion.rs:21:5
error: cannot infer an appropriate lifetime
--> $DIR/region-object-lifetime-in-coercion.rs:20:14
|
LL | fn c(v: &[u8]) -> Box<dyn Foo> {
| ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
...
LL | Box::new(v)
| ^^^^^^^^^^^ lifetime `'static` required
| ---------^-
| | |
| | ...but this borrow...
| this evaluates to the `'static` lifetime...
|
note: ...can't outlive the anonymous lifetime #1 defined on the function body at 17:1
--> $DIR/region-object-lifetime-in-coercion.rs:17:1
|
LL | / fn c(v: &[u8]) -> Box<dyn Foo> {
LL | | // same as previous case due to RFC 599
LL | |
LL | | Box::new(v)
LL | | }
| |_^
help: you can add a bound to the returned `dyn Trait` to make it last less than `'static` and match the anonymous lifetime #1 defined on the function body at 17:1
|
LL | fn c(v: &[u8]) -> Box<dyn Foo + '_> {
| ^^^^
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> $DIR/region-object-lifetime-in-coercion.rs:26:14
--> $DIR/region-object-lifetime-in-coercion.rs:24:14
|
LL | Box::new(v)
| ^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 25:6...
--> $DIR/region-object-lifetime-in-coercion.rs:25:6
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 23:6...
--> $DIR/region-object-lifetime-in-coercion.rs:23:6
|
LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
| ^^
note: ...so that the expression is assignable
--> $DIR/region-object-lifetime-in-coercion.rs:26:14
--> $DIR/region-object-lifetime-in-coercion.rs:24:14
|
LL | Box::new(v)
| ^
= note: expected `&[u8]`
found `&'a [u8]`
note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 25:9...
--> $DIR/region-object-lifetime-in-coercion.rs:25:9
note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 23:9...
--> $DIR/region-object-lifetime-in-coercion.rs:23:9
|
LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
| ^^
note: ...so that the expression is assignable
--> $DIR/region-object-lifetime-in-coercion.rs:26:5
--> $DIR/region-object-lifetime-in-coercion.rs:24:5
|
LL | Box::new(v)
| ^^^^^^^^^^^

View file

@ -2,7 +2,7 @@ error: cannot infer an appropriate lifetime
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16
|
LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
| ^^^^ ---------- this return type evaluates to the `'static` lifetime...
| ^^^^ ---------- this evaluates to the `'static` lifetime...
| |
| ...but this borrow...
|

View file

@ -4,17 +4,17 @@ error: cannot infer an appropriate lifetime
LL | fn f(self: Pin<&Self>) -> impl Clone { self }
| ---------- ^^^^ ...but this borrow...
| |
| this return type evaluates to the `'static` lifetime...
| this evaluates to the `'static` lifetime...
|
note: ...can't outlive the anonymous lifetime #1 defined on the method body at 6:5
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:5
|
LL | fn f(self: Pin<&Self>) -> impl Clone { self }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: you can add a bound to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 6:5
help: you can add a bound to the returned `impl Trait` to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 6:5
|
LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
| ^^^^^^^^^^^^^^^
| ^^^^
error: aborting due to previous error

View file

@ -10,7 +10,7 @@ error: cannot infer an appropriate lifetime
--> $DIR/missing-lifetimes-in-signature.rs:19:5
|
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
| ------------- this return type evaluates to the `'static` lifetime...
| ------------- this evaluates to the `'static` lifetime...
...
LL | / move || {
LL | | *dest = g.get();
@ -28,10 +28,10 @@ LL | | {
LL | | }
LL | | }
| |_^
help: you can add a bound to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the function body at 15:1
help: you can add a bound to the returned `impl Trait` to make it last less than `'static` and match the anonymous lifetime #1 defined on the function body at 15:1
|
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
| ^^^^^^^^^^^^^^^^^^
| ^^^^
error[E0311]: the parameter type `G` may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:25:37

View file

@ -5,7 +5,7 @@
fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
// ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
Box::new(items.iter()) //~ ERROR explicit lifetime required in the type of `items`
Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
}
fn b<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> {

View file

@ -1,12 +1,24 @@
error[E0621]: explicit lifetime required in the type of `items`
--> $DIR/dyn-trait-underscore.rs:8:5
error: cannot infer an appropriate lifetime
--> $DIR/dyn-trait-underscore.rs:8:20
|
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
| ---- help: add explicit lifetime `'static` to the type of `items`: `&'static [T]`
LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
LL | Box::new(items.iter())
| ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
| ---------------^^^^---
| | |
| | ...but this borrow...
| this evaluates to the `'static` lifetime...
|
note: ...can't outlive the anonymous lifetime #1 defined on the function body at 6:1
--> $DIR/dyn-trait-underscore.rs:6:1
|
LL | / fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
LL | | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
LL | | Box::new(items.iter())
LL | | }
| |_^
help: you can add a bound to the returned `dyn Trait` to make it last less than `'static` and match the anonymous lifetime #1 defined on the function body at 6:1
|
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> {
| ^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0621`.