&self,
region: Region<'tcx>,
br: &ty::BoundRegion,
- ) -> Option<(&hir::Ty<'_>, &hir::FnDecl<'_>)> {
+ ) -> Option<(&hir::Ty<'tcx>, &hir::FnDecl<'tcx>)> {
if let Some(anon_reg) = self.tcx().is_suitable_region(region) {
let def_id = anon_reg.def_id;
if let Some(def_id) = def_id.as_local() {
//! where one region is named and the other is anonymous.
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
-use rustc_hir::{FnRetTy, TyKind};
+use rustc_hir::intravisit::Visitor;
+use rustc_hir::FnRetTy;
use rustc_middle::ty;
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
}
if let FnRetTy::Return(ty) = &fndecl.output {
- let mut v = ty::TraitObjectVisitor(vec![]);
- rustc_hir::intravisit::walk_ty(&mut v, ty);
+ let mut v = ty::TraitObjectVisitor(vec![], self.tcx().hir());
+ v.visit_ty(ty);
debug!("try_report_named_anon_conflict: ret ty {:?}", ty);
if sub == &ty::ReStatic
- && (matches!(ty.kind, TyKind::OpaqueDef(_, _)) || v.0.len() == 1)
+ && v.0
+ .into_iter()
+ .filter(|t| t.span.desugaring_kind().is_none())
+ .next()
+ .is_some()
{
debug!("try_report_named_anon_conflict: impl Trait + 'static");
// This is an `impl Trait` or `dyn Trait` return that evaluates de need of
);
let anon_reg_sup = self.tcx().is_suitable_region(sup_r)?;
debug!("try_report_static_impl_trait: anon_reg_sup={:?}", anon_reg_sup);
- let fn_return = self.tcx().return_type_impl_or_dyn_trait(anon_reg_sup.def_id)?;
- debug!("try_report_static_impl_trait: fn_return={:?}", fn_return);
+ let fn_returns = self.tcx().return_type_impl_or_dyn_trait(anon_reg_sup.def_id);
+ if fn_returns.is_empty() {
+ return None;
+ }
+ debug!("try_report_static_impl_trait: fn_return={:?}", fn_returns);
if **sub_r == RegionKind::ReStatic {
let sp = var_origin.span();
let return_sp = sub_origin.span();
);
}
- // only apply this suggestion onto functions with
- // explicit non-desugar'able return.
- if fn_return.span.desugaring_kind().is_none() {
- // FIXME: account for the need of parens in `&(dyn Trait + '_)`
-
- let consider = "consider changing the";
- let declare = "to declare that the";
- let arg = match param_info.param.pat.simple_ident() {
- Some(simple_ident) => format!("argument `{}`", simple_ident),
- None => "the argument".to_string(),
- };
- let explicit =
- format!("you can add an explicit `{}` lifetime bound", lifetime_name);
- let explicit_static =
- format!("explicit `'static` bound to the lifetime of {}", arg);
- let captures = format!("captures data from {}", arg);
- let add_static_bound =
- "alternatively, add an explicit `'static` bound to this reference";
- let plus_lt = format!(" + {}", lifetime_name);
+ // FIXME: account for the need of parens in `&(dyn Trait + '_)`
+ let consider = "consider changing the";
+ let declare = "to declare that the";
+ let arg = match param_info.param.pat.simple_ident() {
+ Some(simple_ident) => format!("argument `{}`", simple_ident),
+ None => "the argument".to_string(),
+ };
+ let explicit =
+ format!("you can add an explicit `{}` lifetime bound", lifetime_name);
+ let explicit_static =
+ format!("explicit `'static` bound to the lifetime of {}", arg);
+ let captures = format!("captures data from {}", arg);
+ let add_static_bound =
+ "alternatively, add an explicit `'static` bound to this reference";
+ let plus_lt = format!(" + {}", lifetime_name);
+ for fn_return in fn_returns {
+ if fn_return.span.desugaring_kind().is_some() {
+ // Skip `async` desugaring `impl Future`.
+ continue;
+ }
match fn_return.kind {
TyKind::OpaqueDef(item_id, _) => {
let item = self.tcx().hir().item(item_id.id);
err.span_suggestion_verbose(
span,
&format!("{} `impl Trait`'s {}", consider, explicit_static),
- lifetime_name,
+ lifetime_name.clone(),
Applicability::MaybeIncorrect,
);
err.span_suggestion_verbose(
param_info.param_ty.to_string(),
Applicability::MaybeIncorrect,
);
+ } else if let Some(_) = opaque
+ .bounds
+ .iter()
+ .filter_map(|arg| match arg {
+ GenericBound::Outlives(Lifetime { name, span, .. })
+ if name.ident().to_string() == lifetime_name =>
+ {
+ Some(*span)
+ }
+ _ => None,
+ })
+ .next()
+ {
} else {
err.span_suggestion_verbose(
fn_return.span.shrink_to_hi(),
captures = captures,
explicit = explicit,
),
- plus_lt,
+ plus_lt.clone(),
Applicability::MaybeIncorrect,
);
- };
+ }
}
TyKind::TraitObject(_, lt) => match lt.name {
LifetimeName::ImplicitObjectLifetimeDefault => {
captures = captures,
explicit = explicit,
),
- plus_lt,
+ plus_lt.clone(),
Applicability::MaybeIncorrect,
);
}
- _ => {
+ name if name.ident().to_string() != lifetime_name => {
+ // With this check we avoid suggesting redundant bounds. This
+ // would happen if there are nested impl/dyn traits and only
+ // one of them has the bound we'd suggest already there, like
+ // in `impl Foo<X = dyn Bar> + '_`.
err.span_suggestion_verbose(
lt.span,
&format!("{} trait object's {}", consider, explicit_static),
- lifetime_name,
+ lifetime_name.clone(),
Applicability::MaybeIncorrect,
);
err.span_suggestion_verbose(
Applicability::MaybeIncorrect,
);
}
+ _ => {}
},
_ => {}
}
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::intravisit::Visitor;
use rustc_hir::lang_items::{self, PanicLocationLangItem};
use rustc_hir::{HirId, ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet, Node, TraitCandidate};
use rustc_index::vec::{Idx, IndexVec};
})
}
- pub fn return_type_impl_or_dyn_trait(
- &self,
- scope_def_id: DefId,
- ) -> Option<&'tcx hir::Ty<'tcx>> {
+ pub fn return_type_impl_or_dyn_trait(&self, scope_def_id: DefId) -> Vec<&'tcx hir::Ty<'tcx>> {
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 {
),
..
}) => ty,
- _ => return None,
+ _ => return vec![],
};
- 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();
- if let hir::FnRetTy::Return(ty) = fn_decl.output {
- return Some(ty);
- }
- } 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]);
- }
- }
- None
- }
- _ => None,
- }
+ let mut v = TraitObjectVisitor(vec![], self.hir());
+ v.visit_ty(hir_output);
+ v.0
}
pub fn return_type_impl_trait(&self, scope_def_id: DefId) -> Option<(Ty<'tcx>, Span)> {
}
}
-pub struct TraitObjectVisitor<'tcx>(pub Vec<&'tcx hir::Ty<'tcx>>);
+/// Collect al types that have an implicit `'static` obligation that we could suggest `'_` for.
+pub struct TraitObjectVisitor<'tcx>(pub Vec<&'tcx hir::Ty<'tcx>>, pub crate::hir::map::Map<'tcx>);
+
impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
type Map = rustc_hir::intravisit::ErasedMap<'v>;
}
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
- if let hir::TyKind::TraitObject(
- _,
- hir::Lifetime {
- name: hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static,
- ..
- },
- ) = ty.kind
- {
- self.0.push(ty);
+ match ty.kind {
+ hir::TyKind::TraitObject(
+ _,
+ hir::Lifetime {
+ name:
+ hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static,
+ ..
+ },
+ ) => {
+ self.0.push(ty);
+ }
+ hir::TyKind::OpaqueDef(item_id, _) => {
+ self.0.push(ty);
+ let item = self.1.expect_item(item_id.id);
+ hir::intravisit::walk_item(self, item);
+ }
+ _ => {}
}
+ hir::intravisit::walk_ty(self, ty);
}
}
| help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
error: lifetime may not live long enough
- --> $DIR/must_outlive_least_region_or_bound.rs:33:69
+ --> $DIR/must_outlive_least_region_or_bound.rs:30:24
+ |
+LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
+ | - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
+ | |
+ | let's call the lifetime of this reference `'1`
+
+error: lifetime may not live long enough
+ --> $DIR/must_outlive_least_region_or_bound.rs:37:69
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
| -- lifetime `'a` defined here ^ returning this value requires that `'a` must outlive `'static`
= help: consider replacing `'a` with `'static`
error: lifetime may not live long enough
- --> $DIR/must_outlive_least_region_or_bound.rs:38:61
+ --> $DIR/must_outlive_least_region_or_bound.rs:42:61
|
LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
| -- -- lifetime `'b` defined here ^^^^^^^^^^^^^^^^ opaque type requires that `'b` must outlive `'a`
= help: consider adding the following bound: `'b: 'a`
error[E0310]: the parameter type `T` may not live long enough
- --> $DIR/must_outlive_least_region_or_bound.rs:43:51
+ --> $DIR/must_outlive_least_region_or_bound.rs:47:51
|
LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
| ^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'static`...
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors
Some errors have detailed explanations: E0310, E0621.
For more information about an error, try `rustc --explain E0310`.
fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
//~^ ERROR cannot infer an appropriate lifetime
+fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
+//~^ ERROR cannot infer an appropriate lifetime
+//~| ERROR cannot infer an appropriate lifetime
+
trait LifetimeTrait<'a> {}
impl<'a> LifetimeTrait<'a> for &'a i32 {}
| help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
error[E0759]: cannot infer an appropriate lifetime
- --> $DIR/must_outlive_least_region_or_bound.rs:33:69
+ --> $DIR/must_outlive_least_region_or_bound.rs:30:65
+ |
+LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
+ | ---- this data with an anonymous lifetime `'_`... ^ ...is captured here, requiring it to live as long as `'static`
+ |
+help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound
+ |
+LL | fn elided5(x: &i32) -> (Box<dyn Debug + '_>, impl Debug) { (Box::new(x), x) }
+ | ^^^^
+help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'_` lifetime bound
+ |
+LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug + '_) { (Box::new(x), x) }
+ | ^^^^
+
+error[E0759]: cannot infer an appropriate lifetime
+ --> $DIR/must_outlive_least_region_or_bound.rs:30:69
+ |
+LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
+ | ---- this data with an anonymous lifetime `'_`... ^ ...is captured here...
+ |
+note: ...and is required to live as long as `'static` here
+ --> $DIR/must_outlive_least_region_or_bound.rs:30:41
+ |
+LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
+ | ^^^^^^^^^^
+help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound
+ |
+LL | fn elided5(x: &i32) -> (Box<dyn Debug + '_>, impl Debug) { (Box::new(x), x) }
+ | ^^^^
+help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'_` lifetime bound
+ |
+LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug + '_) { (Box::new(x), x) }
+ | ^^^^
+
+error[E0759]: cannot infer an appropriate lifetime
+ --> $DIR/must_outlive_least_region_or_bound.rs:37:69
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
| ------- this data with lifetime `'a`... ^ ...is captured here...
|
note: ...and is required to live as long as `'static` here
- --> $DIR/must_outlive_least_region_or_bound.rs:33:34
+ --> $DIR/must_outlive_least_region_or_bound.rs:37:34
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^
error[E0623]: lifetime mismatch
- --> $DIR/must_outlive_least_region_or_bound.rs:38:61
+ --> $DIR/must_outlive_least_region_or_bound.rs:42:61
|
LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
| ------- ^^^^^^^^^^^^^^^^
| this parameter and the return type are declared with different lifetimes...
error[E0310]: the parameter type `T` may not live long enough
- --> $DIR/must_outlive_least_region_or_bound.rs:43:51
+ --> $DIR/must_outlive_least_region_or_bound.rs:47:51
|
LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
| -- ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
LL | fn explicit4<'a>(x: &'static i32) -> Box<dyn Debug + 'static> { Box::new(x) }
| ^^^^^^^^^^^^
-error: aborting due to 12 previous errors
+error: aborting due to 14 previous errors
Some errors have detailed explanations: E0310, E0621, E0623, E0759.
For more information about an error, try `rustc --explain E0310`.
| | |
| | this data with an anonymous lifetime `'_`...
| ...is captured here...
+ |
+help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound
+ |
+LL | async fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
+ | ^^^^
error: aborting due to previous error
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/trait-object-nested-in-impl-trait.rs:27:23
+ |
+LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> {
+ | - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
+ | |
+ | let's call the lifetime of this reference `'1`
+ |
+help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
+ |
+LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: lifetime may not live long enough
+ --> $DIR/trait-object-nested-in-impl-trait.rs:39:9
+ |
+LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
+ | - let's call the lifetime of this reference `'1`
+LL | / Iter {
+LL | | current: None,
+LL | | remaining: self.0.iter(),
+LL | | }
+ | |_________^ returning this value requires that `'1` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/trait-object-nested-in-impl-trait.rs:50:9
+ |
+LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
+ | -- lifetime `'a` defined here
+LL | / Iter {
+LL | | current: None,
+LL | | remaining: self.0.iter(),
+LL | | }
+ | |_________^ returning this value requires that `'a` must outlive `'static`
+ |
+ = help: consider replacing `'a` with `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/trait-object-nested-in-impl-trait.rs:60:30
+ |
+LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
+ | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'a` must outlive `'static`
+ | |
+ | lifetime `'a` defined here
+ |
+ = help: consider replacing `'a` with `'static`
+help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound
+ |
+LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
--- /dev/null
+trait Foo {}
+impl<'a, T: Foo> Foo for &'a T {}
+impl<T: Foo + ?Sized> Foo for Box<T> {}
+
+struct Iter<'a, T> {
+ current: Option<Box<dyn Foo + 'a>>,
+ remaining: T,
+}
+
+impl<'a, T> Iterator for Iter<'a, T>
+where
+ T: Iterator,
+ T::Item: Foo + 'a,
+{
+ type Item = Box<dyn Foo + 'a>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let result = self.current.take();
+ self.current = Box::new(self.remaining.next()).map(|f| Box::new(f) as _);
+ result
+ }
+}
+
+struct Bar(Vec<Box<dyn Foo>>);
+
+impl Bar {
+ fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> {
+ Iter {
+ current: None,
+ remaining: self.0.iter(), //~ ERROR cannot infer an appropriate lifetime
+ }
+ }
+}
+
+struct Baz(Vec<Box<dyn Foo>>);
+
+impl Baz {
+ fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
+ Iter {
+ current: None,
+ remaining: self.0.iter(), //~ ERROR cannot infer an appropriate lifetime
+ }
+ }
+}
+
+struct Bat(Vec<Box<dyn Foo>>);
+
+impl Bat {
+ fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
+ Iter {
+ current: None,
+ remaining: self.0.iter(), //~ ERROR cannot infer an appropriate lifetime
+ }
+ }
+}
+
+struct Ban(Vec<Box<dyn Foo>>);
+
+impl Ban {
+ fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
+ Iter {
+ current: None,
+ remaining: self.0.iter(), //~ ERROR cannot infer an appropriate lifetime
+ }
+ }
+}
+
+fn main() {}
--- /dev/null
+error[E0759]: cannot infer an appropriate lifetime
+ --> $DIR/trait-object-nested-in-impl-trait.rs:30:31
+ |
+LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> {
+ | ----- this data with an anonymous lifetime `'_`...
+...
+LL | remaining: self.0.iter(),
+ | ------ ^^^^
+ | |
+ | ...is captured here...
+ |
+note: ...and is required to live as long as `'static` here
+ --> $DIR/trait-object-nested-in-impl-trait.rs:27:23
+ |
+LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound
+ |
+LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
+ | ^^^^
+help: to declare that the trait object captures data from argument `self`, you can add an explicit `'_` lifetime bound
+ |
+LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo + '_>> {
+ | ^^^^
+
+error[E0759]: cannot infer an appropriate lifetime
+ --> $DIR/trait-object-nested-in-impl-trait.rs:41:31
+ |
+LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
+ | ----- this data with an anonymous lifetime `'_`...
+...
+LL | remaining: self.0.iter(),
+ | ------ ^^^^
+ | |
+ | ...is captured here...
+ |
+note: ...and is required to live as long as `'static` here
+ --> $DIR/trait-object-nested-in-impl-trait.rs:38:23
+ |
+LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: to declare that the trait object captures data from argument `self`, you can add an explicit `'_` lifetime bound
+ |
+LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo + '_>> + '_ {
+ | ^^^^
+
+error[E0759]: cannot infer an appropriate lifetime
+ --> $DIR/trait-object-nested-in-impl-trait.rs:52:31
+ |
+LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
+ | -------- this data with lifetime `'a`...
+...
+LL | remaining: self.0.iter(),
+ | ------ ^^^^
+ | |
+ | ...is captured here...
+ |
+note: ...and is required to live as long as `'static` here
+ --> $DIR/trait-object-nested-in-impl-trait.rs:49:30
+ |
+LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: to declare that the trait object captures data from argument `self`, you can add an explicit `'a` lifetime bound
+ |
+LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo + 'a>> + 'a {
+ | ^^^^
+
+error[E0759]: cannot infer an appropriate lifetime
+ --> $DIR/trait-object-nested-in-impl-trait.rs:63:31
+ |
+LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
+ | -------- this data with lifetime `'a`...
+...
+LL | remaining: self.0.iter(),
+ | ------ ^^^^
+ | |
+ | ...is captured here...
+ |
+note: ...and is required to live as long as `'static` here
+ --> $DIR/trait-object-nested-in-impl-trait.rs:60:30
+ |
+LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'a` lifetime bound
+ |
+LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
+ | ^^^^
+help: to declare that the trait object captures data from argument `self`, you can add an explicit `'a` lifetime bound
+ |
+LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo + 'a>> {
+ | ^^^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0759`.