@@ -600,6 +600,29 @@ impl<'a> LoweringContext<'a> {
600
600
( params, res)
601
601
}
602
602
603
+ /// When there is a reference to some lifetime `'a`, and in-band
604
+ /// lifetimes are enabled, then we want to push that lifetime into
605
+ /// the vector of names to define later. In that case, it will get
606
+ /// added to the appropriate generics.
607
+ fn maybe_collect_in_band_lifetime ( & mut self , span : Span , name : Name ) {
608
+ if !self . is_collecting_in_band_lifetimes {
609
+ return ;
610
+ }
611
+
612
+ if self . in_scope_lifetimes . contains ( & name) {
613
+ return ;
614
+ }
615
+
616
+ if self . lifetimes_to_define
617
+ . iter ( )
618
+ . any ( |( _, lt_name) | * lt_name == name)
619
+ {
620
+ return ;
621
+ }
622
+
623
+ self . lifetimes_to_define . push ( ( span, name) ) ;
624
+ }
625
+
603
626
// Evaluates `f` with the lifetimes in `lt_defs` in-scope.
604
627
// This is used to track which lifetimes have already been defined, and
605
628
// which are new in-band lifetimes that need to have a definition created
@@ -1726,15 +1749,7 @@ impl<'a> LoweringContext<'a> {
1726
1749
x if x == "'_" => hir:: LifetimeName :: Underscore ,
1727
1750
x if x == "'static" => hir:: LifetimeName :: Static ,
1728
1751
name => {
1729
- if self . is_collecting_in_band_lifetimes && !self . in_scope_lifetimes . contains ( & name)
1730
- && self . lifetimes_to_define
1731
- . iter ( )
1732
- . find ( |& & ( _, lt_name) | lt_name == name)
1733
- . is_none ( )
1734
- {
1735
- self . lifetimes_to_define . push ( ( l. span , name) ) ;
1736
- }
1737
-
1752
+ self . maybe_collect_in_band_lifetime ( l. span , name) ;
1738
1753
hir:: LifetimeName :: Name ( name)
1739
1754
}
1740
1755
} ;
@@ -2132,26 +2147,40 @@ impl<'a> LoweringContext<'a> {
2132
2147
polarity,
2133
2148
defaultness,
2134
2149
ref ast_generics,
2135
- ref ifce ,
2150
+ ref trait_ref ,
2136
2151
ref ty,
2137
2152
ref impl_items,
2138
2153
) => {
2139
2154
let def_id = self . resolver . definitions ( ) . local_def_id ( id) ;
2140
- let ( generics, ( ifce, lowered_ty) ) =
2155
+
2156
+ // Lower the "impl header" first. This ordering is important
2157
+ // for in-band lifetimes! Consider `'a` here:
2158
+ //
2159
+ // impl Foo<'a> for u32 {
2160
+ // fn method(&'a self) { .. }
2161
+ // }
2162
+ //
2163
+ // Because we start by lowering the `Foo<'a> for u32`
2164
+ // part, we will add `'a` to the list of generics on
2165
+ // the impl. When we then encounter it later in the
2166
+ // method, it will not be considered an in-band
2167
+ // lifetime to be added, but rather a reference to a
2168
+ // parent lifetime.
2169
+ let ( generics, ( trait_ref, lowered_ty) ) =
2141
2170
self . add_in_band_defs ( ast_generics, def_id, |this| {
2142
- let ifce = ifce . as_ref ( ) . map ( |trait_ref| {
2171
+ let trait_ref = trait_ref . as_ref ( ) . map ( |trait_ref| {
2143
2172
this. lower_trait_ref ( trait_ref, ImplTraitContext :: Disallowed )
2144
2173
} ) ;
2145
2174
2146
- if let Some ( ref trait_ref) = ifce {
2175
+ if let Some ( ref trait_ref) = trait_ref {
2147
2176
if let Def :: Trait ( def_id) = trait_ref. path . def {
2148
2177
this. trait_impls . entry ( def_id) . or_insert ( vec ! [ ] ) . push ( id) ;
2149
2178
}
2150
2179
}
2151
2180
2152
2181
let lowered_ty = this. lower_ty ( ty, ImplTraitContext :: Disallowed ) ;
2153
2182
2154
- ( ifce , lowered_ty)
2183
+ ( trait_ref , lowered_ty)
2155
2184
} ) ;
2156
2185
2157
2186
let new_impl_items = self . with_in_scope_lifetime_defs (
@@ -2172,7 +2201,7 @@ impl<'a> LoweringContext<'a> {
2172
2201
self . lower_impl_polarity ( polarity) ,
2173
2202
self . lower_defaultness ( defaultness, true /* [1] */ ) ,
2174
2203
generics,
2175
- ifce ,
2204
+ trait_ref ,
2176
2205
lowered_ty,
2177
2206
new_impl_items,
2178
2207
)
0 commit comments