@@ -558,6 +558,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
558
558
559
559
fn visit_ty ( & mut self , ty : & ' tcx hir:: Ty ) {
560
560
debug ! ( "visit_ty: id={:?} ty={:?}" , ty. hir_id, ty) ;
561
+ debug ! ( "visit_ty: ty.node={:?}" , ty. node) ;
561
562
match ty. node {
562
563
hir:: TyKind :: BareFn ( ref c) => {
563
564
let next_early_index = self . next_early_index ( ) ;
@@ -1923,6 +1924,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
1923
1924
}
1924
1925
1925
1926
fn visit_segment_args ( & mut self , res : Res , depth : usize , generic_args : & ' tcx hir:: GenericArgs ) {
1927
+ debug ! (
1928
+ "visit_segment_args(res={:?}, depth={:?}, generic_args={:?})" ,
1929
+ res,
1930
+ depth,
1931
+ generic_args,
1932
+ ) ;
1933
+
1926
1934
if generic_args. parenthesized {
1927
1935
let was_in_fn_syntax = self . is_in_fn_syntax ;
1928
1936
self . is_in_fn_syntax = true ;
@@ -1976,6 +1984,23 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
1976
1984
_ => None ,
1977
1985
} ;
1978
1986
1987
+ debug ! ( "visit_segment_args: type_def_id={:?}" , type_def_id) ;
1988
+
1989
+ // Compute a vector of defaults, one for each type parameter,
1990
+ // per the rules given in RFCs 599 and 1156. Example:
1991
+ //
1992
+ // ```rust
1993
+ // struct Foo<'a, T: 'a, U> { }
1994
+ // ```
1995
+ //
1996
+ // If you have `Foo<'x, dyn Bar, dyn Baz>`, we want to default
1997
+ // `dyn Bar` to `dyn Bar + 'x` (because of the `T: 'a` bound)
1998
+ // and `dyn Baz` to `dyn Baz + 'static` (because there is no
1999
+ // such bound).
2000
+ //
2001
+ // Therefore, we would compute `object_lifetime_defaults` to a
2002
+ // vector like `['x, 'static]`. Note that the vector only
2003
+ // includes type parameters.
1979
2004
let object_lifetime_defaults = type_def_id. map_or ( vec ! [ ] , |def_id| {
1980
2005
let in_body = {
1981
2006
let mut scope = self . scope ;
@@ -2015,6 +2040,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2015
2040
. collect ( )
2016
2041
} )
2017
2042
} ;
2043
+ debug ! ( "visit_segment_args: unsubst={:?}" , unsubst) ;
2018
2044
unsubst
2019
2045
. iter ( )
2020
2046
. map ( |set| match * set {
@@ -2035,6 +2061,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2035
2061
. collect ( )
2036
2062
} ) ;
2037
2063
2064
+ debug ! ( "visit_segment_args: object_lifetime_defaults={:?}" , object_lifetime_defaults) ;
2065
+
2038
2066
let mut i = 0 ;
2039
2067
for arg in & generic_args. args {
2040
2068
match arg {
@@ -2057,8 +2085,49 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2057
2085
}
2058
2086
}
2059
2087
2088
+ // Hack: when resolving the type `XX` in binding like `dyn
2089
+ // Foo<'b, Item = XX>`, the current object-lifetime default
2090
+ // would be to examine the trait `Foo` to check whether it has
2091
+ // a lifetime bound declared on `Item`. e.g., if `Foo` is
2092
+ // declared like so, then the default object lifetime bound in
2093
+ // `XX` should be `'b`:
2094
+ //
2095
+ // ```rust
2096
+ // trait Foo<'a> {
2097
+ // type Item: 'a;
2098
+ // }
2099
+ // ```
2100
+ //
2101
+ // but if we just have `type Item;`, then it would be
2102
+ // `'static`. However, we don't get all of this logic correct.
2103
+ //
2104
+ // Instead, we do something hacky: if there are no lifetime parameters
2105
+ // to the trait, then we simply use a default object lifetime
2106
+ // bound of `'static`, because there is no other possibility. On the other hand,
2107
+ // if there ARE lifetime parameters, then we require the user to give an
2108
+ // explicit bound for now.
2109
+ //
2110
+ // This is intended to leave room for us to implement the
2111
+ // correct behavior in the future.
2112
+ let has_lifetime_parameter = generic_args
2113
+ . args
2114
+ . iter ( )
2115
+ . any ( |arg| match arg {
2116
+ GenericArg :: Lifetime ( _) => true ,
2117
+ _ => false ,
2118
+ } ) ;
2119
+
2120
+ // Resolve lifetimes found in the type `XX` from `Item = XX` bindings.
2060
2121
for b in & generic_args. bindings {
2061
- self . visit_assoc_type_binding ( b) ;
2122
+ let scope = Scope :: ObjectLifetimeDefault {
2123
+ lifetime : if has_lifetime_parameter {
2124
+ None
2125
+ } else {
2126
+ Some ( Region :: Static )
2127
+ } ,
2128
+ s : self . scope ,
2129
+ } ;
2130
+ self . with ( scope, |_, this| this. visit_assoc_type_binding ( b) ) ;
2062
2131
}
2063
2132
}
2064
2133
0 commit comments