@@ -83,6 +83,8 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
83
83
task_context : None ,
84
84
current_item : None ,
85
85
captured_lifetimes : None ,
86
+ impl_trait_defs : Vec :: new ( ) ,
87
+ impl_trait_bounds : Vec :: new ( ) ,
86
88
allow_try_trait : Some ( [ sym:: try_trait_v2, sym:: yeet_desugar_details] [ ..] . into ( ) ) ,
87
89
allow_gen_future : Some ( [ sym:: gen_future] [ ..] . into ( ) ) ,
88
90
allow_into_future : Some ( [ sym:: into_future] [ ..] . into ( ) ) ,
@@ -264,16 +266,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
264
266
let body_id =
265
267
this. lower_maybe_async_body ( span, & decl, asyncness, body. as_deref ( ) ) ;
266
268
267
- let ( generics, decl) =
268
- this. add_implicit_generics ( generics, id, |this, idty, idpb| {
269
- let ret_id = asyncness. opt_return_id ( ) ;
270
- this. lower_fn_decl (
271
- & decl,
272
- Some ( ( id, idty, idpb) ) ,
273
- FnDeclKind :: Fn ,
274
- ret_id,
275
- )
276
- } ) ;
269
+ let itctx = ImplTraitContext :: Universal ( this. current_hir_id_owner ) ;
270
+ let ( generics, decl) = this. lower_generics ( generics, id, itctx, |this| {
271
+ let ret_id = asyncness. opt_return_id ( ) ;
272
+ this. lower_fn_decl ( & decl, Some ( id) , FnDeclKind :: Fn , ret_id)
273
+ } ) ;
277
274
let sig = hir:: FnSig {
278
275
decl,
279
276
header : this. lower_fn_header ( header) ,
@@ -311,57 +308,59 @@ impl<'hir> LoweringContext<'_, 'hir> {
311
308
//
312
309
// type Foo = Foo1
313
310
// opaque type Foo1: Trait
314
- let ty = self . lower_ty ( ty, ImplTraitContext :: TypeAliasesOpaqueTy ) ;
315
311
let mut generics = generics. clone ( ) ;
316
312
add_ty_alias_where_clause ( & mut generics, where_clauses, true ) ;
317
- let generics = self . lower_generics (
313
+ let ( generics, ty ) = self . lower_generics (
318
314
& generics,
315
+ id,
319
316
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
317
+ |this| this. lower_ty ( ty, ImplTraitContext :: TypeAliasesOpaqueTy ) ,
320
318
) ;
321
319
hir:: ItemKind :: TyAlias ( ty, generics)
322
320
}
323
321
ItemKind :: TyAlias ( box TyAlias {
324
322
ref generics, ref where_clauses, ty : None , ..
325
323
} ) => {
326
- let ty = self . arena . alloc ( self . ty ( span, hir:: TyKind :: Err ) ) ;
327
324
let mut generics = generics. clone ( ) ;
328
325
add_ty_alias_where_clause ( & mut generics, * where_clauses, true ) ;
329
- let generics = self . lower_generics (
326
+ let ( generics, ty ) = self . lower_generics (
330
327
& generics,
328
+ id,
331
329
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
330
+ |this| this. arena . alloc ( this. ty ( span, hir:: TyKind :: Err ) ) ,
332
331
) ;
333
332
hir:: ItemKind :: TyAlias ( ty, generics)
334
333
}
335
- ItemKind :: Enum ( ref enum_definition, ref generics) => hir:: ItemKind :: Enum (
336
- hir:: EnumDef {
337
- variants : self . arena . alloc_from_iter (
338
- enum_definition. variants . iter ( ) . map ( |x| self . lower_variant ( x) ) ,
339
- ) ,
340
- } ,
341
- self . lower_generics (
334
+ ItemKind :: Enum ( ref enum_definition, ref generics) => {
335
+ let ( generics, variants) = self . lower_generics (
342
336
generics,
337
+ id,
343
338
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
344
- ) ,
345
- ) ,
339
+ |this| {
340
+ this. arena . alloc_from_iter (
341
+ enum_definition. variants . iter ( ) . map ( |x| this. lower_variant ( x) ) ,
342
+ )
343
+ } ,
344
+ ) ;
345
+ hir:: ItemKind :: Enum ( hir:: EnumDef { variants } , generics)
346
+ }
346
347
ItemKind :: Struct ( ref struct_def, ref generics) => {
347
- let struct_def = self . lower_variant_data ( hir_id, struct_def) ;
348
- hir:: ItemKind :: Struct (
349
- struct_def,
350
- self . lower_generics (
351
- generics,
352
- ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
353
- ) ,
354
- )
348
+ let ( generics, struct_def) = self . lower_generics (
349
+ generics,
350
+ id,
351
+ ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
352
+ |this| this. lower_variant_data ( hir_id, struct_def) ,
353
+ ) ;
354
+ hir:: ItemKind :: Struct ( struct_def, generics)
355
355
}
356
356
ItemKind :: Union ( ref vdata, ref generics) => {
357
- let vdata = self . lower_variant_data ( hir_id, vdata) ;
358
- hir:: ItemKind :: Union (
359
- vdata,
360
- self . lower_generics (
361
- generics,
362
- ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
363
- ) ,
364
- )
357
+ let ( generics, vdata) = self . lower_generics (
358
+ generics,
359
+ id,
360
+ ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
361
+ |this| this. lower_variant_data ( hir_id, vdata) ,
362
+ ) ;
363
+ hir:: ItemKind :: Union ( vdata, generics)
365
364
}
366
365
ItemKind :: Impl ( box Impl {
367
366
unsafety,
@@ -386,8 +385,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
386
385
// method, it will not be considered an in-band
387
386
// lifetime to be added, but rather a reference to a
388
387
// parent lifetime.
388
+ let itctx = ImplTraitContext :: Universal ( self . current_hir_id_owner ) ;
389
389
let ( generics, ( trait_ref, lowered_ty) ) =
390
- self . add_implicit_generics ( ast_generics, id, |this , _ , _ | {
390
+ self . lower_generics ( ast_generics, id, itctx , |this | {
391
391
let trait_ref = trait_ref. as_ref ( ) . map ( |trait_ref| {
392
392
this. lower_trait_ref (
393
393
trait_ref,
@@ -432,34 +432,38 @@ impl<'hir> LoweringContext<'_, 'hir> {
432
432
ref bounds,
433
433
ref items,
434
434
} ) => {
435
- let bounds = self . lower_param_bounds (
436
- bounds,
437
- ImplTraitContext :: Disallowed ( ImplTraitPosition :: Bound ) ,
435
+ let ( generics, ( unsafety, items, bounds) ) = self . lower_generics (
436
+ generics,
437
+ id,
438
+ ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
439
+ |this| {
440
+ let bounds = this. lower_param_bounds (
441
+ bounds,
442
+ ImplTraitContext :: Disallowed ( ImplTraitPosition :: Bound ) ,
443
+ ) ;
444
+ let items = this. arena . alloc_from_iter (
445
+ items. iter ( ) . map ( |item| this. lower_trait_item_ref ( item) ) ,
446
+ ) ;
447
+ let unsafety = this. lower_unsafety ( unsafety) ;
448
+ ( unsafety, items, bounds)
449
+ } ,
438
450
) ;
439
- let items = self
440
- . arena
441
- . alloc_from_iter ( items. iter ( ) . map ( |item| self . lower_trait_item_ref ( item) ) ) ;
442
- hir:: ItemKind :: Trait (
443
- is_auto,
444
- self . lower_unsafety ( unsafety) ,
445
- self . lower_generics (
446
- generics,
447
- ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
448
- ) ,
449
- bounds,
450
- items,
451
- )
451
+ hir:: ItemKind :: Trait ( is_auto, unsafety, generics, bounds, items)
452
452
}
453
- ItemKind :: TraitAlias ( ref generics, ref bounds) => hir :: ItemKind :: TraitAlias (
454
- self . lower_generics (
453
+ ItemKind :: TraitAlias ( ref generics, ref bounds) => {
454
+ let ( generics , bounds ) = self . lower_generics (
455
455
generics,
456
+ id,
456
457
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
457
- ) ,
458
- self . lower_param_bounds (
459
- bounds,
460
- ImplTraitContext :: Disallowed ( ImplTraitPosition :: Bound ) ,
461
- ) ,
462
- ) ,
458
+ |this| {
459
+ this. lower_param_bounds (
460
+ bounds,
461
+ ImplTraitContext :: Disallowed ( ImplTraitPosition :: Bound ) ,
462
+ )
463
+ } ,
464
+ ) ;
465
+ hir:: ItemKind :: TraitAlias ( generics, bounds)
466
+ }
463
467
ItemKind :: MacroDef ( MacroDef { ref body, macro_rules } ) => {
464
468
let body = P ( self . lower_mac_args ( body) ) ;
465
469
let macro_kind = self . resolver . decl_macro_kind ( self . resolver . local_def_id ( id) ) ;
@@ -651,8 +655,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
651
655
kind : match i. kind {
652
656
ForeignItemKind :: Fn ( box Fn { ref sig, ref generics, .. } ) => {
653
657
let fdec = & sig. decl ;
658
+ let itctx = ImplTraitContext :: Universal ( self . current_hir_id_owner ) ;
654
659
let ( generics, ( fn_dec, fn_args) ) =
655
- self . add_implicit_generics ( generics, i. id , |this , _ , _ | {
660
+ self . lower_generics ( generics, i. id , itctx , |this | {
656
661
(
657
662
// Disallow `impl Trait` in foreign items.
658
663
this. lower_fn_decl ( fdec, None , FnDeclKind :: ExternFn , None ) ,
@@ -789,24 +794,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
789
794
ref ty,
790
795
..
791
796
} ) => {
792
- let ty = ty. as_ref ( ) . map ( |x| {
793
- self . lower_ty ( x, ImplTraitContext :: Disallowed ( ImplTraitPosition :: Type ) )
794
- } ) ;
795
797
let mut generics = generics. clone ( ) ;
796
798
add_ty_alias_where_clause ( & mut generics, where_clauses, false ) ;
797
- let generics = self . lower_generics (
799
+ self . lower_generics (
798
800
& generics,
801
+ i. id ,
799
802
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
800
- ) ;
801
- let kind = hir:: TraitItemKind :: Type (
802
- self . lower_param_bounds (
803
- bounds,
804
- ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
805
- ) ,
806
- ty,
807
- ) ;
808
-
809
- ( generics, kind)
803
+ |this| {
804
+ let ty = ty. as_ref ( ) . map ( |x| {
805
+ this. lower_ty ( x, ImplTraitContext :: Disallowed ( ImplTraitPosition :: Type ) )
806
+ } ) ;
807
+ hir:: TraitItemKind :: Type (
808
+ this. lower_param_bounds (
809
+ bounds,
810
+ ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
811
+ ) ,
812
+ ty,
813
+ )
814
+ } ,
815
+ )
810
816
}
811
817
AssocItemKind :: MacCall ( ..) => panic ! ( "macro item shouldn't exist at this point" ) ,
812
818
} ;
@@ -876,21 +882,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
876
882
AssocItemKind :: TyAlias ( box TyAlias { generics, where_clauses, ty, .. } ) => {
877
883
let mut generics = generics. clone ( ) ;
878
884
add_ty_alias_where_clause ( & mut generics, * where_clauses, false ) ;
879
- let generics = self . lower_generics (
885
+ self . lower_generics (
880
886
& generics,
887
+ i. id ,
881
888
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
882
- ) ;
883
- let kind = match ty {
884
- None => {
885
- let ty = self . arena . alloc ( self . ty ( i. span , hir:: TyKind :: Err ) ) ;
886
- hir:: ImplItemKind :: TyAlias ( ty)
887
- }
888
- Some ( ty) => {
889
- let ty = self . lower_ty ( ty, ImplTraitContext :: TypeAliasesOpaqueTy ) ;
890
- hir:: ImplItemKind :: TyAlias ( ty)
891
- }
892
- } ;
893
- ( generics, kind)
889
+ |this| match ty {
890
+ None => {
891
+ let ty = this. arena . alloc ( this. ty ( i. span , hir:: TyKind :: Err ) ) ;
892
+ hir:: ImplItemKind :: TyAlias ( ty)
893
+ }
894
+ Some ( ty) => {
895
+ let ty = this. lower_ty ( ty, ImplTraitContext :: TypeAliasesOpaqueTy ) ;
896
+ hir:: ImplItemKind :: TyAlias ( ty)
897
+ }
898
+ } ,
899
+ )
894
900
}
895
901
AssocItemKind :: MacCall ( ..) => panic ! ( "`TyMac` should have been expanded by now" ) ,
896
902
} ;
@@ -1231,8 +1237,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
1231
1237
is_async : Option < NodeId > ,
1232
1238
) -> ( & ' hir hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
1233
1239
let header = self . lower_fn_header ( sig. header ) ;
1234
- let ( generics, decl) = self . add_implicit_generics ( generics, id, |this, idty, idpb| {
1235
- this. lower_fn_decl ( & sig. decl , Some ( ( id, idty, idpb) ) , kind, is_async)
1240
+ let itctx = ImplTraitContext :: Universal ( self . current_hir_id_owner ) ;
1241
+ let ( generics, decl) = self . lower_generics ( generics, id, itctx, |this| {
1242
+ this. lower_fn_decl ( & sig. decl , Some ( id) , kind, is_async)
1236
1243
} ) ;
1237
1244
( generics, hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } )
1238
1245
}
@@ -1289,11 +1296,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
1289
1296
}
1290
1297
}
1291
1298
1292
- pub ( super ) fn lower_generics_mut (
1299
+ /// Return the pair of the lowered `generics` as `hir::Generics` and the evaluation of `f` with
1300
+ /// the carried impl trait definitions and bounds.
1301
+ fn lower_generics < T > (
1293
1302
& mut self ,
1294
1303
generics : & Generics ,
1295
- mut itctx : ImplTraitContext < ' _ , ' hir > ,
1296
- ) -> GenericsCtor < ' hir > {
1304
+ parent_node_id : NodeId ,
1305
+ itctx : ImplTraitContext ,
1306
+ f : impl FnOnce ( & mut Self ) -> T ,
1307
+ ) -> ( & ' hir hir:: Generics < ' hir > , T ) {
1308
+ debug_assert ! ( self . impl_trait_defs. is_empty( ) ) ;
1309
+ debug_assert ! ( self . impl_trait_bounds. is_empty( ) ) ;
1310
+
1297
1311
// Error if `?Trait` bounds in where clauses don't refer directly to type parameters.
1298
1312
// Note: we used to clone these bounds directly onto the type parameter (and avoid lowering
1299
1313
// these into hir when we lower thee where clauses), but this makes it quite difficult to
@@ -1341,9 +1355,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
1341
1355
}
1342
1356
}
1343
1357
1344
- let mut predicates = SmallVec :: new ( ) ;
1358
+ let mut predicates: SmallVec < [ hir :: WherePredicate < ' hir > ; 4 ] > = SmallVec :: new ( ) ;
1345
1359
predicates. extend ( generics. params . iter ( ) . filter_map ( |param| {
1346
- let bounds = self . lower_param_bounds ( & param. bounds , itctx. reborrow ( ) ) ;
1360
+ let bounds = self . lower_param_bounds ( & param. bounds , itctx) ;
1347
1361
self . lower_generic_bound_predicate (
1348
1362
param. ident ,
1349
1363
param. id ,
@@ -1360,22 +1374,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
1360
1374
. map ( |predicate| self . lower_where_predicate ( predicate) ) ,
1361
1375
) ;
1362
1376
1363
- GenericsCtor {
1364
- params : self . lower_generic_params_mut ( & generics. params ) . collect ( ) ,
1365
- predicates,
1366
- has_where_clause : !generics. where_clause . predicates . is_empty ( ) ,
1367
- where_clause_span : self . lower_span ( generics. where_clause . span ) ,
1368
- span : self . lower_span ( generics. span ) ,
1369
- }
1370
- }
1377
+ let mut params: Vec < _ > = self . lower_generic_params_mut ( & generics. params ) . collect ( ) ;
1378
+ let has_where_clause = !generics. where_clause . predicates . is_empty ( ) ;
1379
+ let where_clause_span = self . lower_span ( generics. where_clause . span ) ;
1380
+ let span = self . lower_span ( generics. span ) ;
1381
+ let res = f ( self ) ;
1371
1382
1372
- pub ( super ) fn lower_generics (
1373
- & mut self ,
1374
- generics : & Generics ,
1375
- itctx : ImplTraitContext < ' _ , ' hir > ,
1376
- ) -> & ' hir hir:: Generics < ' hir > {
1377
- let generics_ctor = self . lower_generics_mut ( generics, itctx) ;
1378
- generics_ctor. into_generics ( self . arena )
1383
+ let extra_lifetimes = self . resolver . take_extra_lifetime_params ( parent_node_id) ;
1384
+ let impl_trait_defs = std:: mem:: take ( & mut self . impl_trait_defs ) ;
1385
+ params. extend ( extra_lifetimes. into_iter ( ) . filter_map ( |( ident, node_id, res) | {
1386
+ self . lifetime_res_to_generic_param ( ident, node_id, res)
1387
+ } ) ) ;
1388
+ params. extend ( impl_trait_defs. into_iter ( ) ) ;
1389
+
1390
+ let impl_trait_bounds = std:: mem:: take ( & mut self . impl_trait_bounds ) ;
1391
+ predicates. extend ( impl_trait_bounds. into_iter ( ) ) ;
1392
+
1393
+ let lowered_generics = self . arena . alloc ( hir:: Generics {
1394
+ params : self . arena . alloc_from_iter ( params) ,
1395
+ predicates : self . arena . alloc_from_iter ( predicates) ,
1396
+ has_where_clause,
1397
+ where_clause_span,
1398
+ span,
1399
+ } ) ;
1400
+
1401
+ ( lowered_generics, res)
1379
1402
}
1380
1403
1381
1404
pub ( super ) fn lower_generic_bound_predicate (
@@ -1491,24 +1514,3 @@ impl<'hir> LoweringContext<'_, 'hir> {
1491
1514
}
1492
1515
}
1493
1516
}
1494
-
1495
- /// Helper struct for delayed construction of Generics.
1496
- pub ( super ) struct GenericsCtor < ' hir > {
1497
- pub ( super ) params : SmallVec < [ hir:: GenericParam < ' hir > ; 4 ] > ,
1498
- pub ( super ) predicates : SmallVec < [ hir:: WherePredicate < ' hir > ; 4 ] > ,
1499
- has_where_clause : bool ,
1500
- where_clause_span : Span ,
1501
- span : Span ,
1502
- }
1503
-
1504
- impl < ' hir > GenericsCtor < ' hir > {
1505
- pub ( super ) fn into_generics ( self , arena : & ' hir Arena < ' hir > ) -> & ' hir hir:: Generics < ' hir > {
1506
- arena. alloc ( hir:: Generics {
1507
- params : arena. alloc_from_iter ( self . params ) ,
1508
- predicates : arena. alloc_from_iter ( self . predicates ) ,
1509
- has_where_clause : self . has_where_clause ,
1510
- where_clause_span : self . where_clause_span ,
1511
- span : self . span ,
1512
- } )
1513
- }
1514
- }
0 commit comments