@@ -31,6 +31,7 @@ use rustc_middle::{bug, span_bug};
31
31
use rustc_span:: hygiene:: { AstPass , MacroKind } ;
32
32
use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
33
33
use rustc_span:: { self , ExpnKind } ;
34
+ use rustc_trait_selection:: traits:: wf:: object_region_bounds;
34
35
35
36
use std:: borrow:: Cow ;
36
37
use std:: collections:: hash_map:: Entry ;
@@ -1760,11 +1761,10 @@ fn normalize<'tcx>(
1760
1761
fn clean_trait_object_lifetime_bound < ' tcx > (
1761
1762
region : ty:: Region < ' tcx > ,
1762
1763
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 > > ,
1765
1765
tcx : TyCtxt < ' tcx > ,
1766
1766
) -> 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) {
1768
1768
return None ;
1769
1769
}
1770
1770
@@ -1792,8 +1792,7 @@ fn clean_trait_object_lifetime_bound<'tcx>(
1792
1792
fn can_elide_trait_object_lifetime_bound < ' tcx > (
1793
1793
region : ty:: Region < ' tcx > ,
1794
1794
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 > > ,
1797
1796
tcx : TyCtxt < ' tcx > ,
1798
1797
) -> bool {
1799
1798
// 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>(
1817
1816
ObjectLifetimeDefault :: Empty => { }
1818
1817
}
1819
1818
1820
- // We filter out any escaping regions below, thus it's fine to skip the binder.
1821
- let substs = substs. skip_binder ( ) ;
1822
-
1823
1819
// > 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) {
1855
1821
// > If the trait has no lifetime bounds, then the lifetime is inferred in expressions
1856
1822
// > and is 'static outside of expressions.
1857
1823
// 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>(
1861
1827
// nor show the contents of fn bodies.
1862
1828
[ ] => * region == ty:: ReStatic ,
1863
1829
// > 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.
1864
1831
// 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`.
1867
1834
// Due to ambiguity there is no default trait-object lifetime and thus elision is impossible.
1868
1835
// Don't elide the lifetime.
1869
1836
_ => false ,
@@ -2004,7 +1971,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
2004
1971
2005
1972
inline:: record_extern_fqn ( cx, did, ItemType :: Trait ) ;
2006
1973
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 ) ;
2008
1975
2009
1976
let mut bounds = dids
2010
1977
. map ( |did| {
0 commit comments