@@ -31,6 +31,7 @@ use rustc_middle::{bug, span_bug};
3131use rustc_span:: hygiene:: { AstPass , MacroKind } ;
3232use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
3333use rustc_span:: { self , ExpnKind } ;
34+ use rustc_trait_selection:: traits:: wf:: object_region_bounds;
3435
3536use std:: borrow:: Cow ;
3637use std:: collections:: hash_map:: Entry ;
@@ -1760,11 +1761,10 @@ fn normalize<'tcx>(
17601761fn clean_trait_object_lifetime_bound < ' tcx > (
17611762 region : ty:: Region < ' tcx > ,
17621763 container : Option < ContainerTy < ' tcx > > ,
1763- trait_ : DefId ,
1764- substs : ty:: Binder < ' tcx , & ty:: List < ty:: GenericArg < ' tcx > > > ,
1764+ preds : & ' tcx ty:: List < ty:: PolyExistentialPredicate < ' tcx > > ,
17651765 tcx : TyCtxt < ' tcx > ,
17661766) -> Option < Lifetime > {
1767- if can_elide_trait_object_lifetime_bound ( region, container, trait_ , substs , tcx) {
1767+ if can_elide_trait_object_lifetime_bound ( region, container, preds , tcx) {
17681768 return None ;
17691769 }
17701770
@@ -1792,8 +1792,7 @@ fn clean_trait_object_lifetime_bound<'tcx>(
17921792fn can_elide_trait_object_lifetime_bound < ' tcx > (
17931793 region : ty:: Region < ' tcx > ,
17941794 container : Option < ContainerTy < ' tcx > > ,
1795- trait_ : DefId ,
1796- substs : ty:: Binder < ' tcx , & ty:: List < ty:: GenericArg < ' tcx > > > ,
1795+ preds : & ' tcx ty:: List < ty:: PolyExistentialPredicate < ' tcx > > ,
17971796 tcx : TyCtxt < ' tcx > ,
17981797) -> bool {
17991798 // Below we quote extracts from https://doc.rust-lang.org/reference/lifetime-elision.html#default-trait-object-lifetimes
@@ -1817,41 +1816,8 @@ fn can_elide_trait_object_lifetime_bound<'tcx>(
18171816 ObjectLifetimeDefault :: Empty => { }
18181817 }
18191818
1820- // We filter out any escaping regions below, thus it's fine to skip the binder.
1821- let substs = substs. skip_binder ( ) ;
1822-
18231819 // > If neither of those rules apply, then the bounds on the trait are used:
1824- let mut trait_regions: Vec < _ > = tcx
1825- . predicates_of ( trait_)
1826- . predicates
1827- . iter ( )
1828- . filter_map ( |( pred, _) | {
1829- // Look for bounds of the form `Self: 'a` for any region `'a`.
1830- if let ty:: PredicateKind :: Clause ( ty:: Clause :: TypeOutlives ( ty:: OutlivesPredicate ( ty, region) ) ) = pred. kind ( ) . skip_binder ( )
1831- && let ty:: Param ( param) = ty. kind ( )
1832- && param. name == kw:: SelfUpper
1833- {
1834- Some ( ty:: EarlyBinder :: bind ( region) . subst ( tcx, tcx. mk_substs_trait ( ty, substs) ) )
1835- . filter ( |region| !region. has_escaping_bound_vars ( ) )
1836- } else {
1837- None
1838- }
1839- } )
1840- . collect ( ) ;
1841-
1842- // As a result of the substitutions above, we might be left with duplicate regions.
1843- // Consider `<'a, 'b> Self: 'a + 'b` with substitution `<'r, 'r>`. Deduplicate.
1844- trait_regions. dedup ( ) ;
1845-
1846- // > If 'static is used for any lifetime bound then 'static is used.
1847- // If the list contains `'static`, throw out everyhing else as it outlives any of them.
1848- if let Some ( index) = trait_regions. iter ( ) . position ( |region| region. is_static ( ) ) {
1849- let static_ = trait_regions. swap_remove ( index) ;
1850- trait_regions. clear ( ) ;
1851- trait_regions. push ( static_) ;
1852- }
1853-
1854- match * trait_regions {
1820+ match * object_region_bounds ( tcx, preds) {
18551821 // > If the trait has no lifetime bounds, then the lifetime is inferred in expressions
18561822 // > and is 'static outside of expressions.
18571823 // FIXME: If we are in an expression context (i.e. fn bodies and const exprs) then the default is
@@ -1861,9 +1827,10 @@ fn can_elide_trait_object_lifetime_bound<'tcx>(
18611827 // nor show the contents of fn bodies.
18621828 [ ] => * region == ty:: ReStatic ,
18631829 // > If the trait is defined with a single lifetime bound then that bound is used.
1830+ // > If 'static is used for any lifetime bound then 'static is used.
18641831 // FIXME(fmease): Don't compare lexically but respect de Bruijn indices etc. to handle shadowing correctly.
1865- [ trait_region ] => trait_region . get_name ( ) == region. get_name ( ) ,
1866- // There are several distinct trait regions and none are `'static` (thanks to the preprocessing above) .
1832+ [ object_region ] => object_region . get_name ( ) == region. get_name ( ) ,
1833+ // There are several distinct trait regions and none are `'static`.
18671834 // Due to ambiguity there is no default trait-object lifetime and thus elision is impossible.
18681835 // Don't elide the lifetime.
18691836 _ => false ,
@@ -2004,7 +1971,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
20041971
20051972 inline:: record_extern_fqn ( cx, did, ItemType :: Trait ) ;
20061973
2007- let lifetime = clean_trait_object_lifetime_bound ( * reg, container, did , substs , cx. tcx ) ;
1974+ let lifetime = clean_trait_object_lifetime_bound ( * reg, container, obj , cx. tcx ) ;
20081975
20091976 let mut bounds = dids
20101977 . map ( |did| {
0 commit comments