@@ -746,86 +746,117 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
746
746
self . diagnostic_metadata . current_function = Some ( ( fn_kind, sp) ) ;
747
747
}
748
748
debug ! ( "(resolving function) entering function" ) ;
749
- let declaration = fn_kind. decl ( ) ;
750
749
751
750
// Create a value rib for the function.
752
751
self . with_rib ( ValueNS , rib_kind, |this| {
753
752
// Create a label rib for the function.
754
753
this. with_label_rib ( FnItemRibKind , |this| {
755
- let async_node_id = fn_kind. header ( ) . and_then ( |h| h. asyncness . opt_return_id ( ) ) ;
754
+ match fn_kind {
755
+ FnKind :: Fn ( _, _, sig, _, generics, body) => {
756
+ this. visit_generics ( generics) ;
756
757
757
- if let FnKind :: Fn ( _, _, _, _, generics, _) = fn_kind {
758
- this. visit_generics ( generics) ;
759
- }
758
+ let declaration = & sig. decl ;
759
+ let async_node_id = sig. header . asyncness . opt_return_id ( ) ;
760
760
761
- if let Some ( async_node_id) = async_node_id {
762
- // In `async fn`, argument-position elided lifetimes
763
- // must be transformed into fresh generic parameters so that
764
- // they can be applied to the opaque `impl Trait` return type.
765
- this. with_lifetime_rib (
766
- LifetimeRibKind :: AnonymousCreateParameter ( fn_id) ,
767
- |this| {
761
+ // Argument-position elided lifetimes must be transformed into fresh
762
+ // generic parameters. This is especially useful for `async fn`, where
763
+ // these fresh generic parameters can be applied to the opaque `impl Trait`
764
+ // return type.
765
+ this. with_lifetime_rib (
766
+ if async_node_id. is_some ( ) {
767
+ LifetimeRibKind :: AnonymousCreateParameter ( fn_id)
768
+ } else {
769
+ LifetimeRibKind :: AnonymousPassThrough ( fn_id, false )
770
+ } ,
768
771
// Add each argument to the rib.
769
- this. resolve_params ( & declaration. inputs )
770
- } ,
771
- ) ;
772
-
773
- // Construct the list of in-scope lifetime parameters for async lowering.
774
- // We include all lifetime parameters, either named or "Fresh".
775
- // The order of those parameters does not matter, as long as it is
776
- // deterministic.
777
- let mut extra_lifetime_params =
778
- this. r . extra_lifetime_params_map . get ( & fn_id) . cloned ( ) . unwrap_or_default ( ) ;
779
- for rib in this. lifetime_ribs . iter ( ) . rev ( ) {
780
- extra_lifetime_params. extend (
781
- rib. bindings
782
- . iter ( )
783
- . map ( |( & ident, & ( node_id, res) ) | ( ident, node_id, res) ) ,
772
+ |this| this. resolve_params ( & declaration. inputs ) ,
784
773
) ;
785
- match rib. kind {
786
- LifetimeRibKind :: Item => break ,
787
- LifetimeRibKind :: AnonymousCreateParameter ( id) => {
788
- if let Some ( earlier_fresh) =
789
- this. r . extra_lifetime_params_map . get ( & id)
790
- {
791
- extra_lifetime_params. extend ( earlier_fresh) ;
774
+
775
+ // Construct the list of in-scope lifetime parameters for async lowering.
776
+ // We include all lifetime parameters, either named or "Fresh".
777
+ // The order of those parameters does not matter, as long as it is
778
+ // deterministic.
779
+ if let Some ( async_node_id) = async_node_id {
780
+ let mut extra_lifetime_params = this
781
+ . r
782
+ . extra_lifetime_params_map
783
+ . get ( & fn_id)
784
+ . cloned ( )
785
+ . unwrap_or_default ( ) ;
786
+ for rib in this. lifetime_ribs . iter ( ) . rev ( ) {
787
+ extra_lifetime_params. extend (
788
+ rib. bindings
789
+ . iter ( )
790
+ . map ( |( & ident, & ( node_id, res) ) | ( ident, node_id, res) ) ,
791
+ ) ;
792
+ match rib. kind {
793
+ LifetimeRibKind :: Item => break ,
794
+ LifetimeRibKind :: AnonymousCreateParameter ( binder) => {
795
+ if let Some ( earlier_fresh) =
796
+ this. r . extra_lifetime_params_map . get ( & binder)
797
+ {
798
+ extra_lifetime_params. extend ( earlier_fresh) ;
799
+ }
800
+ }
801
+ _ => { }
792
802
}
793
803
}
794
- _ => { }
804
+ this. r
805
+ . extra_lifetime_params_map
806
+ . insert ( async_node_id, extra_lifetime_params) ;
795
807
}
796
- }
797
- this. r . extra_lifetime_params_map . insert ( async_node_id, extra_lifetime_params) ;
798
808
799
- this. with_lifetime_rib (
800
- LifetimeRibKind :: AnonymousPassThrough ( async_node_id, true ) ,
801
- |this| visit:: walk_fn_ret_ty ( this, & declaration. output ) ,
802
- ) ;
803
- } else {
804
- // Add each argument to the rib.
805
- this. with_lifetime_rib (
806
- LifetimeRibKind :: AnonymousPassThrough ( fn_id, false ) ,
807
- |this| this. resolve_params ( & declaration. inputs ) ,
808
- ) ;
809
- this. with_lifetime_rib (
810
- LifetimeRibKind :: AnonymousPassThrough ( fn_id, true ) ,
811
- |this| visit:: walk_fn_ret_ty ( this, & declaration. output ) ,
812
- ) ;
813
- } ;
809
+ this. with_lifetime_rib (
810
+ LifetimeRibKind :: AnonymousPassThrough (
811
+ // For async fn, the return type appears inside a custom
812
+ // `impl Future` RPIT, so we override the binder's id.
813
+ async_node_id. unwrap_or ( fn_id) ,
814
+ true ,
815
+ ) ,
816
+ |this| visit:: walk_fn_ret_ty ( this, & declaration. output ) ,
817
+ ) ;
814
818
815
- // Ignore errors in function bodies if this is rustdoc
816
- // Be sure not to set this until the function signature has been resolved.
817
- let previous_state = replace ( & mut this. in_func_body , true ) ;
818
- // Resolve the function body, potentially inside the body of an async closure
819
- this. with_lifetime_rib (
820
- LifetimeRibKind :: AnonymousPassThrough ( fn_id, false ) ,
821
- |this| match fn_kind {
822
- FnKind :: Fn ( .., body) => walk_list ! ( this, visit_block, body) ,
823
- FnKind :: Closure ( _, body) => this. visit_expr ( body) ,
824
- } ,
825
- ) ;
819
+ if let Some ( body) = body {
820
+ // Ignore errors in function bodies if this is rustdoc
821
+ // Be sure not to set this until the function signature has been resolved.
822
+ let previous_state = replace ( & mut this. in_func_body , true ) ;
823
+ // Resolve the function body, potentially inside the body of an async closure
824
+ this. with_lifetime_rib (
825
+ LifetimeRibKind :: AnonymousPassThrough ( fn_id, false ) ,
826
+ |this| this. visit_block ( body) ,
827
+ ) ;
826
828
827
- debug ! ( "(resolving function) leaving function" ) ;
828
- this. in_func_body = previous_state;
829
+ debug ! ( "(resolving function) leaving function" ) ;
830
+ this. in_func_body = previous_state;
831
+ }
832
+ }
833
+ FnKind :: Closure ( declaration, body) => {
834
+ // Do not attempt to create generic lifetime parameters.
835
+ // FIXME: Revisit this decision once `for<>` bounds on closures become a
836
+ // thing.
837
+ this. with_lifetime_rib (
838
+ LifetimeRibKind :: AnonymousPassThrough ( fn_id, false ) ,
839
+ // Add each argument to the rib.
840
+ |this| this. resolve_params ( & declaration. inputs ) ,
841
+ ) ;
842
+ this. with_lifetime_rib (
843
+ LifetimeRibKind :: AnonymousPassThrough ( fn_id, true ) ,
844
+ |this| visit:: walk_fn_ret_ty ( this, & declaration. output ) ,
845
+ ) ;
846
+
847
+ // Ignore errors in function bodies if this is rustdoc
848
+ // Be sure not to set this until the function signature has been resolved.
849
+ let previous_state = replace ( & mut this. in_func_body , true ) ;
850
+ // Resolve the function body, potentially inside the body of an async closure
851
+ this. with_lifetime_rib (
852
+ LifetimeRibKind :: AnonymousPassThrough ( fn_id, false ) ,
853
+ |this| this. visit_expr ( body) ,
854
+ ) ;
855
+
856
+ debug ! ( "(resolving function) leaving function" ) ;
857
+ this. in_func_body = previous_state;
858
+ }
859
+ }
829
860
} )
830
861
} ) ;
831
862
self . diagnostic_metadata . current_function = previous_value;
0 commit comments