@@ -83,6 +83,8 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
8383 task_context : None ,
8484 current_item : None ,
8585 captured_lifetimes : None ,
86+ impl_trait_defs : Vec :: new ( ) ,
87+ impl_trait_bounds : Vec :: new ( ) ,
8688 allow_try_trait : Some ( [ sym:: try_trait_v2, sym:: yeet_desugar_details] [ ..] . into ( ) ) ,
8789 allow_gen_future : Some ( [ sym:: gen_future] [ ..] . into ( ) ) ,
8890 allow_into_future : Some ( [ sym:: into_future] [ ..] . into ( ) ) ,
@@ -264,16 +266,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
264266 let body_id =
265267 this. lower_maybe_async_body ( span, & decl, asyncness, body. as_deref ( ) ) ;
266268
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+ } ) ;
277274 let sig = hir:: FnSig {
278275 decl,
279276 header : this. lower_fn_header ( header) ,
@@ -311,57 +308,59 @@ impl<'hir> LoweringContext<'_, 'hir> {
311308 //
312309 // type Foo = Foo1
313310 // opaque type Foo1: Trait
314- let ty = self . lower_ty ( ty, ImplTraitContext :: TypeAliasesOpaqueTy ) ;
315311 let mut generics = generics. clone ( ) ;
316312 add_ty_alias_where_clause ( & mut generics, where_clauses, true ) ;
317- let generics = self . lower_generics (
313+ let ( generics, ty ) = self . lower_generics (
318314 & generics,
315+ id,
319316 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
317+ |this| this. lower_ty ( ty, ImplTraitContext :: TypeAliasesOpaqueTy ) ,
320318 ) ;
321319 hir:: ItemKind :: TyAlias ( ty, generics)
322320 }
323321 ItemKind :: TyAlias ( box TyAlias {
324322 ref generics, ref where_clauses, ty : None , ..
325323 } ) => {
326- let ty = self . arena . alloc ( self . ty ( span, hir:: TyKind :: Err ) ) ;
327324 let mut generics = generics. clone ( ) ;
328325 add_ty_alias_where_clause ( & mut generics, * where_clauses, true ) ;
329- let generics = self . lower_generics (
326+ let ( generics, ty ) = self . lower_generics (
330327 & generics,
328+ id,
331329 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
330+ |this| this. arena . alloc ( this. ty ( span, hir:: TyKind :: Err ) ) ,
332331 ) ;
333332 hir:: ItemKind :: TyAlias ( ty, generics)
334333 }
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 (
342336 generics,
337+ id,
343338 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+ }
346347 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)
355355 }
356356 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)
365364 }
366365 ItemKind :: Impl ( box Impl {
367366 unsafety,
@@ -386,8 +385,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
386385 // method, it will not be considered an in-band
387386 // lifetime to be added, but rather a reference to a
388387 // parent lifetime.
388+ let itctx = ImplTraitContext :: Universal ( self . current_hir_id_owner ) ;
389389 let ( generics, ( trait_ref, lowered_ty) ) =
390- self . add_implicit_generics ( ast_generics, id, |this , _ , _ | {
390+ self . lower_generics ( ast_generics, id, itctx , |this | {
391391 let trait_ref = trait_ref. as_ref ( ) . map ( |trait_ref| {
392392 this. lower_trait_ref (
393393 trait_ref,
@@ -432,34 +432,38 @@ impl<'hir> LoweringContext<'_, 'hir> {
432432 ref bounds,
433433 ref items,
434434 } ) => {
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+ } ,
438450 ) ;
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)
452452 }
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 (
455455 generics,
456+ id,
456457 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+ }
463467 ItemKind :: MacroDef ( MacroDef { ref body, macro_rules } ) => {
464468 let body = P ( self . lower_mac_args ( body) ) ;
465469 let macro_kind = self . resolver . decl_macro_kind ( self . resolver . local_def_id ( id) ) ;
@@ -651,8 +655,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
651655 kind : match i. kind {
652656 ForeignItemKind :: Fn ( box Fn { ref sig, ref generics, .. } ) => {
653657 let fdec = & sig. decl ;
658+ let itctx = ImplTraitContext :: Universal ( self . current_hir_id_owner ) ;
654659 let ( generics, ( fn_dec, fn_args) ) =
655- self . add_implicit_generics ( generics, i. id , |this , _ , _ | {
660+ self . lower_generics ( generics, i. id , itctx , |this | {
656661 (
657662 // Disallow `impl Trait` in foreign items.
658663 this. lower_fn_decl ( fdec, None , FnDeclKind :: ExternFn , None ) ,
@@ -789,24 +794,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
789794 ref ty,
790795 ..
791796 } ) => {
792- let ty = ty. as_ref ( ) . map ( |x| {
793- self . lower_ty ( x, ImplTraitContext :: Disallowed ( ImplTraitPosition :: Type ) )
794- } ) ;
795797 let mut generics = generics. clone ( ) ;
796798 add_ty_alias_where_clause ( & mut generics, where_clauses, false ) ;
797- let generics = self . lower_generics (
799+ self . lower_generics (
798800 & generics,
801+ i. id ,
799802 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+ )
810816 }
811817 AssocItemKind :: MacCall ( ..) => panic ! ( "macro item shouldn't exist at this point" ) ,
812818 } ;
@@ -876,21 +882,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
876882 AssocItemKind :: TyAlias ( box TyAlias { generics, where_clauses, ty, .. } ) => {
877883 let mut generics = generics. clone ( ) ;
878884 add_ty_alias_where_clause ( & mut generics, * where_clauses, false ) ;
879- let generics = self . lower_generics (
885+ self . lower_generics (
880886 & generics,
887+ i. id ,
881888 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+ )
894900 }
895901 AssocItemKind :: MacCall ( ..) => panic ! ( "`TyMac` should have been expanded by now" ) ,
896902 } ;
@@ -1231,8 +1237,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
12311237 is_async : Option < NodeId > ,
12321238 ) -> ( & ' hir hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
12331239 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)
12361243 } ) ;
12371244 ( generics, hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } )
12381245 }
@@ -1289,11 +1296,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
12891296 }
12901297 }
12911298
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 > (
12931302 & mut self ,
12941303 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+
12971311 // Error if `?Trait` bounds in where clauses don't refer directly to type parameters.
12981312 // Note: we used to clone these bounds directly onto the type parameter (and avoid lowering
12991313 // these into hir when we lower thee where clauses), but this makes it quite difficult to
@@ -1341,9 +1355,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
13411355 }
13421356 }
13431357
1344- let mut predicates = SmallVec :: new ( ) ;
1358+ let mut predicates: SmallVec < [ hir :: WherePredicate < ' hir > ; 4 ] > = SmallVec :: new ( ) ;
13451359 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) ;
13471361 self . lower_generic_bound_predicate (
13481362 param. ident ,
13491363 param. id ,
@@ -1360,22 +1374,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
13601374 . map ( |predicate| self . lower_where_predicate ( predicate) ) ,
13611375 ) ;
13621376
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 ) ;
13711382
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)
13791402 }
13801403
13811404 pub ( super ) fn lower_generic_bound_predicate (
@@ -1491,24 +1514,3 @@ impl<'hir> LoweringContext<'_, 'hir> {
14911514 }
14921515 }
14931516}
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