@@ -155,6 +155,10 @@ struct LoweringContext<'a, 'hir: 'a> {
155
155
/// We always store a `normalize_to_macros_2_0()` version of the param-name in this
156
156
/// vector.
157
157
in_scope_lifetimes : Vec < ParamName > ,
158
+ /// The index of the first lifetime introduced using `for<'lt>`.
159
+ ///
160
+ /// Used to only add lifetimes from binders as generics to anon consts.
161
+ hrtb_start : Option < usize > ,
158
162
159
163
current_module : hir:: HirId ,
160
164
@@ -168,6 +172,12 @@ struct LoweringContext<'a, 'hir: 'a> {
168
172
allow_gen_future : Option < Lrc < [ Symbol ] > > ,
169
173
}
170
174
175
+ #[ derive( Copy , Clone ) ]
176
+ enum LifetimeOrigin {
177
+ Hrtb ,
178
+ Other ,
179
+ }
180
+
171
181
pub trait ResolverAstLowering {
172
182
fn def_key ( & mut self , id : DefId ) -> DefKey ;
173
183
@@ -322,6 +332,7 @@ pub fn lower_crate<'a, 'hir>(
322
332
lifetimes_to_define : Vec :: new ( ) ,
323
333
is_collecting_in_band_lifetimes : false ,
324
334
in_scope_lifetimes : Vec :: new ( ) ,
335
+ hrtb_start : None ,
325
336
allow_try_trait : Some ( [ sym:: try_trait] [ ..] . into ( ) ) ,
326
337
allow_gen_future : Some ( [ sym:: gen_future] [ ..] . into ( ) ) ,
327
338
}
@@ -853,6 +864,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
853
864
// for them.
854
865
fn with_in_scope_lifetime_defs < T > (
855
866
& mut self ,
867
+ origin : LifetimeOrigin ,
856
868
params : & [ GenericParam ] ,
857
869
f : impl FnOnce ( & mut Self ) -> T ,
858
870
) -> T {
@@ -864,9 +876,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
864
876
_ => None ,
865
877
} ) ;
866
878
self . in_scope_lifetimes . extend ( lt_def_names) ;
879
+ let hrtb_start = self . hrtb_start ;
880
+ if matches ! ( origin, LifetimeOrigin :: Hrtb ) && self . hrtb_start . is_none ( ) {
881
+ self . hrtb_start = Some ( old_len) ;
882
+ }
867
883
868
884
let res = f ( self ) ;
869
885
886
+ self . hrtb_start = hrtb_start;
870
887
self . in_scope_lifetimes . truncate ( old_len) ;
871
888
res
872
889
}
@@ -885,7 +902,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
885
902
f : impl FnOnce ( & mut Self , & mut Vec < hir:: GenericParam < ' hir > > ) -> T ,
886
903
) -> ( hir:: Generics < ' hir > , T ) {
887
904
let ( in_band_defs, ( mut lowered_generics, res) ) =
888
- self . with_in_scope_lifetime_defs ( & generics. params , |this| {
905
+ self . with_in_scope_lifetime_defs ( LifetimeOrigin :: Other , & generics. params , |this| {
889
906
this. collect_in_band_defs ( parent_def_id, anonymous_lifetime_mode, |this| {
890
907
let mut params = Vec :: new ( ) ;
891
908
// Note: it is necessary to lower generics *before* calling `f`.
@@ -1225,21 +1242,23 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1225
1242
} ;
1226
1243
hir:: TyKind :: Rptr ( lifetime, self . lower_mt ( mt, itctx) )
1227
1244
}
1228
- TyKind :: BareFn ( ref f) => self . with_in_scope_lifetime_defs ( & f. generic_params , |this| {
1229
- this. with_anonymous_lifetime_mode ( AnonymousLifetimeMode :: PassThrough , |this| {
1230
- hir:: TyKind :: BareFn ( this. arena . alloc ( hir:: BareFnTy {
1231
- generic_params : this. lower_generic_params (
1232
- & f. generic_params ,
1233
- & NodeMap :: default ( ) ,
1234
- ImplTraitContext :: disallowed ( ) ,
1235
- ) ,
1236
- unsafety : this. lower_unsafety ( f. unsafety ) ,
1237
- abi : this. lower_extern ( f. ext ) ,
1238
- decl : this. lower_fn_decl ( & f. decl , None , false , None ) ,
1239
- param_names : this. lower_fn_params_to_names ( & f. decl ) ,
1240
- } ) )
1245
+ TyKind :: BareFn ( ref f) => {
1246
+ self . with_in_scope_lifetime_defs ( LifetimeOrigin :: Hrtb , & f. generic_params , |this| {
1247
+ this. with_anonymous_lifetime_mode ( AnonymousLifetimeMode :: PassThrough , |this| {
1248
+ hir:: TyKind :: BareFn ( this. arena . alloc ( hir:: BareFnTy {
1249
+ generic_params : this. lower_generic_params (
1250
+ & f. generic_params ,
1251
+ & NodeMap :: default ( ) ,
1252
+ ImplTraitContext :: disallowed ( ) ,
1253
+ ) ,
1254
+ unsafety : this. lower_unsafety ( f. unsafety ) ,
1255
+ abi : this. lower_extern ( f. ext ) ,
1256
+ decl : this. lower_fn_decl ( & f. decl , None , false , None ) ,
1257
+ param_names : this. lower_fn_params_to_names ( & f. decl ) ,
1258
+ } ) )
1259
+ } )
1241
1260
} )
1242
- } ) ,
1261
+ }
1243
1262
TyKind :: Never => hir:: TyKind :: Never ,
1244
1263
TyKind :: Tup ( ref tys) => {
1245
1264
hir:: TyKind :: Tup ( self . arena . alloc_from_iter (
@@ -2243,28 +2262,35 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2243
2262
itctx. reborrow ( ) ,
2244
2263
) ;
2245
2264
2246
- let trait_ref = self . with_in_scope_lifetime_defs ( & p. bound_generic_params , |this| {
2247
- // Any impl Trait types defined within this scope can capture
2248
- // lifetimes bound on this predicate.
2249
- let lt_def_names = p. bound_generic_params . iter ( ) . filter_map ( |param| match param. kind {
2250
- GenericParamKind :: Lifetime { .. } => Some ( hir:: LifetimeName :: Param (
2251
- ParamName :: Plain ( param. ident . normalize_to_macros_2_0 ( ) ) ,
2252
- ) ) ,
2253
- _ => None ,
2254
- } ) ;
2255
- if let ImplTraitContext :: OtherOpaqueTy { ref mut capturable_lifetimes, .. } = itctx {
2256
- capturable_lifetimes. extend ( lt_def_names. clone ( ) ) ;
2257
- }
2265
+ let trait_ref = self . with_in_scope_lifetime_defs (
2266
+ LifetimeOrigin :: Hrtb ,
2267
+ & p. bound_generic_params ,
2268
+ |this| {
2269
+ // Any impl Trait types defined within this scope can capture
2270
+ // lifetimes bound on this predicate.
2271
+ let lt_def_names =
2272
+ p. bound_generic_params . iter ( ) . filter_map ( |param| match param. kind {
2273
+ GenericParamKind :: Lifetime { .. } => Some ( hir:: LifetimeName :: Param (
2274
+ ParamName :: Plain ( param. ident . normalize_to_macros_2_0 ( ) ) ,
2275
+ ) ) ,
2276
+ _ => None ,
2277
+ } ) ;
2278
+ if let ImplTraitContext :: OtherOpaqueTy { ref mut capturable_lifetimes, .. } = itctx
2279
+ {
2280
+ capturable_lifetimes. extend ( lt_def_names. clone ( ) ) ;
2281
+ }
2258
2282
2259
- let res = this. lower_trait_ref ( & p. trait_ref , itctx. reborrow ( ) ) ;
2283
+ let res = this. lower_trait_ref ( & p. trait_ref , itctx. reborrow ( ) ) ;
2260
2284
2261
- if let ImplTraitContext :: OtherOpaqueTy { ref mut capturable_lifetimes, .. } = itctx {
2262
- for param in lt_def_names {
2263
- capturable_lifetimes. remove ( & param) ;
2285
+ if let ImplTraitContext :: OtherOpaqueTy { ref mut capturable_lifetimes, .. } = itctx
2286
+ {
2287
+ for param in lt_def_names {
2288
+ capturable_lifetimes. remove ( & param) ;
2289
+ }
2264
2290
}
2265
- }
2266
- res
2267
- } ) ;
2291
+ res
2292
+ } ,
2293
+ ) ;
2268
2294
2269
2295
hir:: PolyTraitRef { bound_generic_params, trait_ref, span : p. span }
2270
2296
}
@@ -2341,20 +2367,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2341
2367
//
2342
2368
// We therefore add these lifetimes as additional generic parameters.
2343
2369
2344
- // FIXME(const_generics): We currently add all lifetimes as generic params,
2345
- // but as we already mention the parent generics this is not actually needed.
2346
- //
2347
- // Consider only adding explicit higher ranked lifetimes here.
2348
-
2349
2370
// We only need `in_scope_lifetimes` because all in-band lifetimes are
2350
2371
// added to the generics of the parent.
2351
- let lifetime_params: Vec < ( Span , ParamName ) > = this
2352
- . in_scope_lifetimes
2353
- . iter ( )
2354
- . cloned ( )
2355
- . map ( |name| ( name. ident ( ) . span , name) )
2356
- . collect ( ) ;
2357
-
2372
+ let lifetime_params: Vec < ( Span , ParamName ) > =
2373
+ if let Some ( hrtb_start) = this. hrtb_start {
2374
+ this. in_scope_lifetimes
2375
+ . iter ( )
2376
+ . skip ( hrtb_start)
2377
+ . cloned ( )
2378
+ . map ( |name| ( name. ident ( ) . span , name) )
2379
+ . collect ( )
2380
+ } else {
2381
+ vec ! [ ]
2382
+ } ;
2358
2383
let generic_params =
2359
2384
this. arena . alloc_from_iter ( lifetime_params. iter ( ) . map ( |& ( span, hir_name) | {
2360
2385
this. lifetime_to_generic_param ( span, hir_name, def_id)
0 commit comments