Change:
Another regresssion of with a different failure path: It should be fixed by ignoring non-captured lifetimes in: cc label regression-from-stable-to-stable C-bug T-compiler T-types A-impl-trait
Note that fixing this issue is necessary for , but might not be sufficient. I'll investigate more...
WG-prioritization assigning priority (). label -I-prioritize +P-high

Discussion:
// through and constrain Pi. let mut subcomponents = smallvec![]; let mut subvisited = SsoHashSet::new(); <del> compute_components_recursive(tcx, ty.into(), &mut subcomponents, &mut subvisited); </del> <ins> compute_alias_components_recursive(tcx, ty, &mut subcomponents, &mut subvisited); </ins> out.push(Component::EscapingAlias(subcomponents.into_iter().collect())); } }

/// /// This should not be used to get the components of `parent` itself. /// Use [push_outlives_components] instead. <del> pub(super) fn compute_components_recursive<'tcx>( </del> <ins> pub(super) fn compute_alias_components_recursive<'tcx>( tcx: TyCtxt<'tcx>, alias_ty: Ty<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>, visited: &mut SsoHashSet<GenericArg<'tcx>>, ) { let ty::Alias(kind, alias_ty) = alias_ty.kind() else { bug!() }; let opt_variances = if *kind == ty::Opaque { tcx.variances_of(alias_ty.def_id) } else { &[] }; for (index, child) in alias_ty.substs.iter().enumerate() { if opt_variances.get(index) == Some(&ty::Bivariant) { continue; } if !visited.insert(child) { continue; } match child.unpack() { GenericArgKind::Type(ty) => { compute_components(tcx, ty, out, visited); } GenericArgKind::Lifetime(lt) => { // Ignore late-bound regions. if !lt.is_late_bound() { out.push(Component::Region(lt)); } } GenericArgKind::Const(_) => { compute_components_recursive(tcx, child, out, visited); } } } } /// 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. fn compute_components_recursive<'tcx>( </ins> tcx: TyCtxt<'tcx>, parent: GenericArg<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>,

// the problem is to add `T: 'r`, which isn't true. So, if there are no // inference variables, we use a verify constraint instead of adding // edges, which winds up enforcing the same condition. <ins> let is_opaque = alias_ty.kind(self.tcx) == ty::Opaque; </ins> if approx_env_bounds.is_empty() && trait_bounds.is_empty() <del> && (alias_ty.needs_infer() || alias_ty.kind(self.tcx) == ty::Opaque) </del> <ins> && (alias_ty.needs_infer() || is_opaque) </ins> { debug!("no declared bounds"); <del> self.substs_must_outlive(alias_ty.substs, origin, region); </del> <ins> let opt_variances = is_opaque.then(|| self.tcx.variances_of(alias_ty.def_id)); self.substs_must_outlive(alias_ty.substs, origin, region, opt_variances); </ins> return; }

self.delegate.push_verify(origin, GenericKind::Alias(alias_ty), region, verify_bound); } <ins> #[instrument(level = "debug", skip(self))] </ins> fn substs_must_outlive( &mut self, substs: SubstsRef<'tcx>, origin: infer::SubregionOrigin<'tcx>, region: ty::Region<'tcx>, <ins> opt_variances: Option<&[ty::Variance]>, </ins> ) { let constraint = origin.to_constraint_category(); <del> for k in substs { </del> <ins> for (index, k) in substs.iter().enumerate() { </ins> match k.unpack() { GenericArgKind::Lifetime(lt) => { <del> self.delegate.push_sub_region_constraint( origin.clone(), region, lt, constraint, ); </del> <ins> let variance = if let Some(variances) = opt_variances { variances[index] } else { ty::Invariant }; if variance == ty::Invariant { self.delegate.push_sub_region_constraint( origin.clone(), region, lt, constraint, ); } </ins> } GenericArgKind::Type(ty) => { self.type_must_outlive(origin.clone(), ty, region, constraint);

<del> use crate::infer::outlives::components::{compute_components_recursive, Component}; </del> <ins> use crate::infer::outlives::components::{compute_alias_components_recursive, Component}; </ins> use crate::infer::outlives::env::RegionBoundPairs; use crate::infer::region_constraints::VerifyIfEq; use crate::infer::VerifyBound;

// see the extensive comment in projection_must_outlive let recursive_bound = { let mut components = smallvec![]; <del> compute_components_recursive(self.tcx, alias_ty_as_ty.into(), &mut components, visited); </del> <ins> compute_alias_components_recursive( self.tcx, alias_ty_as_ty.into(), &mut components, visited, ); </ins> self.bound_from_components(&components, visited) };

<ins> // check-pass #![feature(type_alias_impl_trait)] struct MyTy<'a>(Vec<u8>, &'a ()); impl MyTy<'_> { fn one(&mut self) -> &mut impl Sized { &mut self.0 } fn two(&mut self) -> &mut (impl Sized + 'static) { self.one() } } type Opaque<'a> = impl Sized; fn define<'a>() -> Opaque<'a> {} fn test<'a>() { None::<&'static Opaque<'a>>; } fn one<'a, 'b: 'b>() -> &'a impl Sized { &() } fn two<'a, 'b>() { one::<'a, 'b>(); } fn main() {} </ins>

<ins> // check-pass #![feature(type_alias_impl_trait)] fn opaque<'a: 'a>() -> impl Sized {} fn assert_static<T: 'static>(_: T) {} fn test_closure() { let closure = |_| { assert_static(opaque()); }; closure(&opaque()); } type Opaque<'a> = impl Sized; fn define<'a>() -> Opaque<'a> {} fn test_tait(_: &Opaque<'_>) { None::<&'static Opaque<'_>>; } fn main() {} </ins>