Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: Both asserts don't pass. Adding bound on makes it compile. We are requiring all the for closures and generators to outlive here: This is wrong and inconsistent with the logic in <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --Build using the Nightly version: 1.63.0-nightly (2022-05-24 ) <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<p</p</details label T-compiler A-lifetimes A-closures A-generators claim <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Error: Parsing assign command in failed: ...'bot assign' ''... Please let know if you're having trouble with this bot.

Discussion:
} } <del> fn compute_components_recursive<'tcx>( </del> <ins> /// Collect [Component]s for *all* the substs of `parent`. /// /// This should not be used to get the components of `parent` itself. /// Use [push_outlives_components] instead. pub(super) fn compute_components_recursive<'tcx>( </ins> tcx: TyCtxt<'tcx>, parent: GenericArg<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>,

<ins> use crate::infer::outlives::components::{compute_components_recursive, Component}; </ins> use crate::infer::outlives::env::RegionBoundPairs; use crate::infer::region_constraints::VerifyIfEq; use crate::infer::{GenericKind, VerifyBound}; use rustc_data_structures::captures::Captures; use rustc_data_structures::sso::SsoHashSet; use rustc_hir::def_id::DefId; <del> use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst}; </del> <ins> use rustc_middle::ty::subst::{GenericArg, Subst}; </ins> use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt}; <ins> use smallvec::smallvec; </ins> /// The `TypeOutlives` struct has the job of "lowering" a `T: 'a` /// obligation into a series of `'a: 'b` constraints and "verifys", as /// described on the module comment. The final constraints are emitted

} } <del> fn type_bound( &self, ty: Ty<'tcx>, visited: &mut SsoHashSet<GenericArg<'tcx>>, ) -> VerifyBound<'tcx> { match *ty.kind() { ty::Param(p) => self.param_bound(p), ty::Projection(data) => self.projection_bound(data, visited), ty::FnDef(_, substs) => { // HACK(eddyb) ignore lifetimes found shallowly in `substs`. // This is inconsistent with `ty::Adt` (including all substs), // but consistent with previous (accidental) behavior. // See https://github.com/rust-lang/rust/issues/70917 // for further background and discussion. let mut bounds = substs .iter() .filter_map(|child| match child.unpack() { GenericArgKind::Type(ty) => Some(self.type_bound(ty, visited)), GenericArgKind::Lifetime(_) => None, GenericArgKind::Const(_) => Some(self.recursive_bound(child, visited)), }) .filter(|bound| { // Remove bounds that must hold, since they are not interesting. !bound.must_hold() }); match (bounds.next(), bounds.next()) { (Some(first), None) => first, (first, second) => VerifyBound::AllBounds( first.into_iter().chain(second).chain(bounds).collect(), ), } } _ => self.recursive_bound(ty.into(), visited), } } </del> fn param_bound(&self, param_ty: ty::ParamTy) -> VerifyBound<'tcx> { debug!("param_bound(param_ty={:?})", param_ty);

.map(|r| VerifyBound::OutlivedBy(r)); // see the extensive comment in projection_must_outlive <del> let ty = self.tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs); let recursive_bound = self.recursive_bound(ty.into(), visited); </del> <ins> let recursive_bound = { let mut components = smallvec![]; let ty = self.tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs); compute_components_recursive(self.tcx, ty.into(), &mut components, visited); self.bound_from_components(&components, visited) }; </ins> VerifyBound::AnyBound(env_bounds.chain(trait_bounds).collect()).or(recursive_bound) } <del> fn recursive_bound( </del> <ins> fn bound_from_components( </ins> &self, <del> parent: GenericArg<'tcx>, </del> <ins> components: &[Component<'tcx>], </ins> visited: &mut SsoHashSet<GenericArg<'tcx>>, ) -> VerifyBound<'tcx> { <del> let mut bounds = parent .walk_shallow(visited) .filter_map(|child| match child.unpack() { GenericArgKind::Type(ty) => Some(self.type_bound(ty, visited)), GenericArgKind::Lifetime(lt) => { // Ignore late-bound regions. if !lt.is_late_bound() { Some(VerifyBound::OutlivedBy(lt)) } else { None } } GenericArgKind::Const(_) => Some(self.recursive_bound(child, visited)), }) </del> <ins> let mut bounds = components .iter() .map(|component| self.bound_from_single_component(component, visited)) </ins> .filter(|bound| { // Remove bounds that must hold, since they are not interesting. !bound.must_hold()

} } <ins> fn bound_from_single_component( &self, component: &Component<'tcx>, visited: &mut SsoHashSet<GenericArg<'tcx>>, ) -> VerifyBound<'tcx> { match *component { Component::Region(lt) => VerifyBound::OutlivedBy(lt), Component::Param(param_ty) => self.param_bound(param_ty), Component::Projection(projection_ty) => self.projection_bound(projection_ty, visited), Component::EscapingProjection(ref components) => { self.bound_from_components(components, visited) } Component::UnresolvedInferenceVariable(v) => { // ignore this, we presume it will yield an error // later, since if a type variable is not resolved by // this point it never will be self.tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, &format!("unresolved inference variable in outlives: {:?}", v), ); // add a bound that never holds VerifyBound::AnyBound(vec![]) } } } </ins> /// Searches the environment for where-clauses like `G: 'a` where /// `G` is either some type parameter `T` or a projection like /// `T::Item`. Returns a vector of the `'a` bounds it can find.

<ins> // Regression test for #97405. // In `good_generic_fn` the param `T` ends up in the substs of closures/generators, // but we should be able to prove `<Gen<T> as Iterator>::Item: 'static` without // requiring `T: 'static` // edition:2018 // check-fail fn opaque<F>(_: F) -> impl Iterator { b"".iter() } fn assert_static<T: 'static>(_: T) {} fn good_generic_fn<T>() { // Previously, proving `<OpaqueTy<type_of(async {})> as Iterator>::Item: 'static` // used to require `T: 'static`. assert_static(opaque(async {}).next()); assert_static(opaque(|| {}).next()); assert_static(opaque(opaque(async {}).next()).next()); } // This should fail because `T` ends up in the upvars of the closure. fn bad_generic_fn<T: Copy>(t: T) { assert_static(opaque(async move { t; }).next()); //~^ ERROR the associated type `<impl Iterator as Iterator>::Item` may not live long enough assert_static(opaque(move || { t; }).next()); //~^ ERROR the associated type `<impl Iterator as Iterator>::Item` may not live long enough assert_static(opaque(opaque(async move { t; }).next()).next()); //~^ ERROR the associated type `<impl Iterator as Iterator>::Item` may not live long enough } fn main() {} </ins>

<ins> error[E0310]: the associated type `<impl Iterator as Iterator>::Item` may not live long enough --> $DIR/closure-in-projection-issue-97405.rs:24:5 | LL |     assert_static(opaque(async move { t; }).next()); |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `<impl Iterator as Iterator>::Item: 'static`... = note: ...so that the type `<impl Iterator as Iterator>::Item` will meet its required lifetime bounds error[E0310]: the associated type `<impl Iterator as Iterator>::Item` may not live long enough --> $DIR/closure-in-projection-issue-97405.rs:26:5 | LL |     assert_static(opaque(move || { t; }).next()); |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `<impl Iterator as Iterator>::Item: 'static`... = note: ...so that the type `<impl Iterator as Iterator>::Item` will meet its required lifetime bounds error[E0310]: the associated type `<impl Iterator as Iterator>::Item` may not live long enough --> $DIR/closure-in-projection-issue-97405.rs:28:5 | LL |     assert_static(opaque(opaque(async move { t; }).next()).next()); |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `<impl Iterator as Iterator>::Item: 'static`... = note: ...so that the type `<impl Iterator as Iterator>::Item` will meet its required lifetime bounds error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0310`. </ins>