@@ -228,7 +228,7 @@ enum ImplTraitContext<'b, 'a> {
228228 ReturnPositionOpaqueTy {
229229 /// `DefId` for the parent function, used to look up necessary
230230 /// information later.
231- fn_def_id : DefId ,
231+ fn_def_id : LocalDefId ,
232232 /// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
233233 origin : hir:: OpaqueTyOrigin ,
234234 } ,
@@ -646,31 +646,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
646646 /// parameter while `f` is running (and restored afterwards).
647647 fn collect_in_band_defs < T > (
648648 & mut self ,
649- parent_def_id : LocalDefId ,
650- anonymous_lifetime_mode : AnonymousLifetimeMode ,
651- f : impl FnOnce ( & mut Self ) -> ( Vec < hir:: GenericParam < ' hir > > , T ) ,
652- ) -> ( Vec < hir:: GenericParam < ' hir > > , T ) {
653- assert ! ( !self . is_collecting_in_band_lifetimes) ;
654- assert ! ( self . lifetimes_to_define. is_empty( ) ) ;
655- let old_anonymous_lifetime_mode = self . anonymous_lifetime_mode ;
656-
657- self . anonymous_lifetime_mode = anonymous_lifetime_mode;
658- self . is_collecting_in_band_lifetimes = true ;
659-
660- let ( in_band_ty_params, res) = f ( self ) ;
661-
662- self . is_collecting_in_band_lifetimes = false ;
663- self . anonymous_lifetime_mode = old_anonymous_lifetime_mode;
664-
665- let lifetimes_to_define = self . lifetimes_to_define . split_off ( 0 ) ;
649+ f : impl FnOnce ( & mut Self ) -> T ,
650+ ) -> ( Vec < ( Span , ParamName ) > , T ) {
651+ let was_collecting = std:: mem:: replace ( & mut self . is_collecting_in_band_lifetimes , true ) ;
652+ let len = self . lifetimes_to_define . len ( ) ;
666653
667- let params = lifetimes_to_define
668- . into_iter ( )
669- . map ( |( span, hir_name) | self . lifetime_to_generic_param ( span, hir_name, parent_def_id) )
670- . chain ( in_band_ty_params. into_iter ( ) )
671- . collect ( ) ;
654+ let res = f ( self ) ;
672655
673- ( params, res)
656+ let lifetimes_to_define = self . lifetimes_to_define . split_off ( len) ;
657+ self . is_collecting_in_band_lifetimes = was_collecting;
658+ ( lifetimes_to_define, res)
674659 }
675660
676661 /// Converts a lifetime into a new generic parameter.
@@ -785,27 +770,39 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
785770 anonymous_lifetime_mode : AnonymousLifetimeMode ,
786771 f : impl FnOnce ( & mut Self , & mut Vec < hir:: GenericParam < ' hir > > ) -> T ,
787772 ) -> ( hir:: Generics < ' hir > , T ) {
788- let ( in_band_defs, ( mut lowered_generics, res) ) =
789- self . with_in_scope_lifetime_defs ( & generics. params , |this| {
790- this. collect_in_band_defs ( parent_def_id, anonymous_lifetime_mode, |this| {
791- let mut params = Vec :: new ( ) ;
792- // Note: it is necessary to lower generics *before* calling `f`.
793- // When lowering `async fn`, there's a final step when lowering
794- // the return type that assumes that all in-scope lifetimes have
795- // already been added to either `in_scope_lifetimes` or
796- // `lifetimes_to_define`. If we swapped the order of these two,
797- // in-band-lifetimes introduced by generics or where-clauses
798- // wouldn't have been added yet.
799- let generics = this. lower_generics_mut (
800- generics,
801- ImplTraitContext :: Universal ( & mut params, this. current_hir_id_owner ) ,
802- ) ;
803- let res = f ( this, & mut params) ;
804- ( params, ( generics, res) )
773+ let ( lifetimes_to_define, ( mut lowered_generics, impl_trait_defs, res) ) = self
774+ . collect_in_band_defs ( |this| {
775+ this. with_anonymous_lifetime_mode ( anonymous_lifetime_mode, |this| {
776+ this. with_in_scope_lifetime_defs ( & generics. params , |this| {
777+ let mut impl_trait_defs = Vec :: new ( ) ;
778+ // Note: it is necessary to lower generics *before* calling `f`.
779+ // When lowering `async fn`, there's a final step when lowering
780+ // the return type that assumes that all in-scope lifetimes have
781+ // already been added to either `in_scope_lifetimes` or
782+ // `lifetimes_to_define`. If we swapped the order of these two,
783+ // in-band-lifetimes introduced by generics or where-clauses
784+ // wouldn't have been added yet.
785+ let generics = this. lower_generics_mut (
786+ generics,
787+ ImplTraitContext :: Universal (
788+ & mut impl_trait_defs,
789+ this. current_hir_id_owner ,
790+ ) ,
791+ ) ;
792+ let res = f ( this, & mut impl_trait_defs) ;
793+ ( generics, impl_trait_defs, res)
794+ } )
805795 } )
806796 } ) ;
807797
808- lowered_generics. params . extend ( in_band_defs) ;
798+ lowered_generics. params . extend (
799+ lifetimes_to_define
800+ . into_iter ( )
801+ . map ( |( span, hir_name) | {
802+ self . lifetime_to_generic_param ( span, hir_name, parent_def_id)
803+ } )
804+ . chain ( impl_trait_defs) ,
805+ ) ;
809806
810807 let lowered_generics = lowered_generics. into_generics ( self . arena ) ;
811808 ( lowered_generics, res)
@@ -1380,7 +1377,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13801377 fn lower_opaque_impl_trait (
13811378 & mut self ,
13821379 span : Span ,
1383- fn_def_id : Option < DefId > ,
1380+ fn_def_id : Option < LocalDefId > ,
13841381 origin : hir:: OpaqueTyOrigin ,
13851382 opaque_ty_node_id : NodeId ,
13861383 capturable_lifetimes : Option < & FxHashSet < hir:: LifetimeName > > ,
@@ -1452,7 +1449,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
14521449 span : lctx. lower_span ( span) ,
14531450 } ,
14541451 bounds : hir_bounds,
1455- impl_trait_fn : fn_def_id,
14561452 origin,
14571453 } ;
14581454
@@ -1522,7 +1518,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15221518 fn lower_fn_decl (
15231519 & mut self ,
15241520 decl : & FnDecl ,
1525- mut in_band_ty_params : Option < ( DefId , & mut Vec < hir:: GenericParam < ' hir > > ) > ,
1521+ mut in_band_ty_params : Option < ( LocalDefId , & mut Vec < hir:: GenericParam < ' hir > > ) > ,
15261522 impl_trait_return_allow : bool ,
15271523 make_ret_async : Option < NodeId > ,
15281524 ) -> & ' hir hir:: FnDecl < ' hir > {
@@ -1580,7 +1576,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15801576 Some ( ( def_id, _) ) if impl_trait_return_allow => {
15811577 ImplTraitContext :: ReturnPositionOpaqueTy {
15821578 fn_def_id : def_id,
1583- origin : hir:: OpaqueTyOrigin :: FnReturn ,
1579+ origin : hir:: OpaqueTyOrigin :: FnReturn ( def_id ) ,
15841580 }
15851581 }
15861582 _ => ImplTraitContext :: disallowed ( ) ,
@@ -1635,7 +1631,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16351631 fn lower_async_fn_ret_ty (
16361632 & mut self ,
16371633 output : & FnRetTy ,
1638- fn_def_id : DefId ,
1634+ fn_def_id : LocalDefId ,
16391635 opaque_ty_node_id : NodeId ,
16401636 ) -> hir:: FnRetTy < ' hir > {
16411637 debug ! (
@@ -1689,18 +1685,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16891685 // this is because the elided lifetimes from the return type
16901686 // should be figured out using the ordinary elision rules, and
16911687 // this desugaring achieves that.
1688+
1689+ debug ! ( "lower_async_fn_ret_ty: in_scope_lifetimes={:#?}" , self . in_scope_lifetimes) ;
1690+ debug ! ( "lower_async_fn_ret_ty: lifetimes_to_define={:#?}" , self . lifetimes_to_define) ;
1691+
1692+ // Calculate all the lifetimes that should be captured
1693+ // by the opaque type. This should include all in-scope
1694+ // lifetime parameters, including those defined in-band.
16921695 //
1693- // The variable `input_lifetimes_count` tracks the number of
1694- // lifetime parameters to the opaque type *not counting* those
1695- // lifetimes elided in the return type. This includes those
1696- // that are explicitly declared (`in_scope_lifetimes`) and
1697- // those elided lifetimes we found in the arguments (current
1698- // content of `lifetimes_to_define`). Next, we will process
1699- // the return type, which will cause `lifetimes_to_define` to
1700- // grow.
1701- let input_lifetimes_count = self . in_scope_lifetimes . len ( ) + self . lifetimes_to_define . len ( ) ;
1702-
1703- let mut lifetime_params = Vec :: new ( ) ;
1696+ // `lifetime_params` is a vector of tuple (span, parameter name, lifetime name).
1697+
1698+ // Input lifetime like `'a` or `'1`:
1699+ let mut lifetime_params: Vec < _ > = self
1700+ . in_scope_lifetimes
1701+ . iter ( )
1702+ . cloned ( )
1703+ . map ( |name| ( name. ident ( ) . span , name, hir:: LifetimeName :: Param ( name) ) )
1704+ . chain (
1705+ self . lifetimes_to_define
1706+ . iter ( )
1707+ . map ( |& ( span, name) | ( span, name, hir:: LifetimeName :: Param ( name) ) ) ,
1708+ )
1709+ . collect ( ) ;
1710+
17041711 self . with_hir_id_owner ( opaque_ty_node_id, |this| {
17051712 // We have to be careful to get elision right here. The
17061713 // idea is that we create a lifetime parameter for each
@@ -1710,34 +1717,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17101717 //
17111718 // Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
17121719 // hence the elision takes place at the fn site.
1713- let future_bound = this
1714- . with_anonymous_lifetime_mode ( AnonymousLifetimeMode :: CreateParameter , |this| {
1715- this. lower_async_fn_output_type_to_future_bound ( output, fn_def_id, span)
1720+ let ( lifetimes_to_define, future_bound) =
1721+ this. with_anonymous_lifetime_mode ( AnonymousLifetimeMode :: CreateParameter , |this| {
1722+ this. collect_in_band_defs ( |this| {
1723+ this. lower_async_fn_output_type_to_future_bound ( output, fn_def_id, span)
1724+ } )
17161725 } ) ;
1717-
17181726 debug ! ( "lower_async_fn_ret_ty: future_bound={:#?}" , future_bound) ;
1727+ debug ! ( "lower_async_fn_ret_ty: lifetimes_to_define={:#?}" , lifetimes_to_define) ;
17191728
1720- // Calculate all the lifetimes that should be captured
1721- // by the opaque type. This should include all in-scope
1722- // lifetime parameters, including those defined in-band.
1723- //
1724- // Note: this must be done after lowering the output type,
1725- // as the output type may introduce new in-band lifetimes.
1726- lifetime_params = this
1727- . in_scope_lifetimes
1728- . iter ( )
1729- . cloned ( )
1730- . map ( |name| ( name. ident ( ) . span , name) )
1731- . chain ( this. lifetimes_to_define . iter ( ) . cloned ( ) )
1732- . collect ( ) ;
1733-
1734- debug ! ( "lower_async_fn_ret_ty: in_scope_lifetimes={:#?}" , this. in_scope_lifetimes) ;
1735- debug ! ( "lower_async_fn_ret_ty: lifetimes_to_define={:#?}" , this. lifetimes_to_define) ;
1729+ lifetime_params. extend (
1730+ // Output lifetime like `'_`:
1731+ lifetimes_to_define
1732+ . into_iter ( )
1733+ . map ( |( span, name) | ( span, name, hir:: LifetimeName :: Implicit ( false ) ) ) ,
1734+ ) ;
17361735 debug ! ( "lower_async_fn_ret_ty: lifetime_params={:#?}" , lifetime_params) ;
17371736
17381737 let generic_params =
1739- this. arena . alloc_from_iter ( lifetime_params. iter ( ) . map ( |( span, hir_name) | {
1740- this. lifetime_to_generic_param ( * span, * hir_name, opaque_ty_def_id)
1738+ this. arena . alloc_from_iter ( lifetime_params. iter ( ) . map ( |& ( span, hir_name, _ ) | {
1739+ this. lifetime_to_generic_param ( span, hir_name, opaque_ty_def_id)
17411740 } ) ) ;
17421741
17431742 let opaque_ty_item = hir:: OpaqueTy {
@@ -1747,8 +1746,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17471746 span : this. lower_span ( span) ,
17481747 } ,
17491748 bounds : arena_vec ! [ this; future_bound] ,
1750- impl_trait_fn : Some ( fn_def_id) ,
1751- origin : hir:: OpaqueTyOrigin :: AsyncFn ,
1749+ origin : hir:: OpaqueTyOrigin :: AsyncFn ( fn_def_id) ,
17521750 } ;
17531751
17541752 trace ! ( "exist ty from async fn def id: {:#?}" , opaque_ty_def_id) ;
@@ -1771,25 +1769,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17711769 //
17721770 // For the "output" lifetime parameters, we just want to
17731771 // generate `'_`.
1774- let mut generic_args = Vec :: with_capacity ( lifetime_params. len ( ) ) ;
1775- generic_args. extend ( lifetime_params[ ..input_lifetimes_count] . iter ( ) . map (
1776- |& ( span, hir_name) | {
1777- // Input lifetime like `'a` or `'1`:
1772+ let generic_args =
1773+ self . arena . alloc_from_iter ( lifetime_params. into_iter ( ) . map ( |( span, _, name) | {
17781774 GenericArg :: Lifetime ( hir:: Lifetime {
17791775 hir_id : self . next_id ( ) ,
17801776 span : self . lower_span ( span) ,
1781- name : hir :: LifetimeName :: Param ( hir_name ) ,
1777+ name,
17821778 } )
1783- } ,
1784- ) ) ;
1785- generic_args. extend ( lifetime_params[ input_lifetimes_count..] . iter ( ) . map ( |& ( span, _) |
1786- // Output lifetime like `'_`.
1787- GenericArg :: Lifetime ( hir:: Lifetime {
1788- hir_id : self . next_id ( ) ,
1789- span : self . lower_span ( span) ,
1790- name : hir:: LifetimeName :: Implicit ( false ) ,
1791- } ) ) ) ;
1792- let generic_args = self . arena . alloc_from_iter ( generic_args) ;
1779+ } ) ) ;
17931780
17941781 // Create the `Foo<...>` reference itself. Note that the `type
17951782 // Foo = impl Trait` is, internally, created as a child of the
@@ -1805,7 +1792,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
18051792 fn lower_async_fn_output_type_to_future_bound (
18061793 & mut self ,
18071794 output : & FnRetTy ,
1808- fn_def_id : DefId ,
1795+ fn_def_id : LocalDefId ,
18091796 span : Span ,
18101797 ) -> hir:: GenericBound < ' hir > {
18111798 // Compute the `T` in `Future<Output = T>` from the return type.
@@ -1816,7 +1803,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
18161803 // generates.
18171804 let context = ImplTraitContext :: ReturnPositionOpaqueTy {
18181805 fn_def_id,
1819- origin : hir:: OpaqueTyOrigin :: FnReturn ,
1806+ origin : hir:: OpaqueTyOrigin :: FnReturn ( fn_def_id ) ,
18201807 } ;
18211808 self . lower_ty ( ty, context)
18221809 }
@@ -2453,17 +2440,12 @@ impl<'hir> GenericArgsCtor<'hir> {
24532440 }
24542441}
24552442
2443+ #[ tracing:: instrument( level = "debug" ) ]
24562444fn lifetimes_from_impl_trait_bounds (
24572445 opaque_ty_id : NodeId ,
24582446 bounds : hir:: GenericBounds < ' _ > ,
24592447 lifetimes_to_include : Option < & FxHashSet < hir:: LifetimeName > > ,
24602448) -> Vec < ( hir:: LifetimeName , Span ) > {
2461- debug ! (
2462- "lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \
2463- bounds={:#?})",
2464- opaque_ty_id, bounds,
2465- ) ;
2466-
24672449 // This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that
24682450 // appear in the bounds, excluding lifetimes that are created within the bounds.
24692451 // E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`.
0 commit comments