@@ -55,7 +55,7 @@ use syntax::util::lev_distance::find_best_match_for_name;
5555
5656use syntax:: visit:: { self , FnKind , Visitor } ;
5757use syntax:: attr;
58- use syntax:: ast:: { Arm , BindingMode , Block , Crate , Expr , ExprKind } ;
58+ use syntax:: ast:: { Arm , IsAsync , BindingMode , Block , Crate , Expr , ExprKind , FnHeader } ;
5959use syntax:: ast:: { FnDecl , ForeignItem , ForeignItemKind , GenericParamKind , Generics } ;
6060use syntax:: ast:: { Item , ItemKind , ImplItem , ImplItemKind } ;
6161use syntax:: ast:: { Label , Local , Mutability , Pat , PatKind , Path } ;
@@ -2054,13 +2054,54 @@ impl<'a> Resolver<'a> {
20542054 self . check_proc_macro_attrs ( & item. attrs ) ;
20552055
20562056 match item. node {
2057+ ItemKind :: Fn ( ref declaration,
2058+ FnHeader { asyncness : IsAsync :: Async ( async_closure_id) , .. } ,
2059+ ref generics,
2060+ ref body) => {
2061+ // Async functions are desugared from `async fn foo() { .. }`
2062+ // to `fn foo() { future_from_generator(move || ... ) }`,
2063+ // so we have to visit the body inside the closure scope
2064+ self . with_type_parameter_rib ( HasTypeParameters ( generics, ItemRibKind ) , |this| {
2065+ this. visit_vis ( & item. vis ) ;
2066+ this. visit_ident ( item. ident ) ;
2067+ this. visit_generics ( generics) ;
2068+ let rib_kind = ItemRibKind ;
2069+ this. ribs [ ValueNS ] . push ( Rib :: new ( rib_kind) ) ;
2070+ this. label_ribs . push ( Rib :: new ( rib_kind) ) ;
2071+ let mut bindings_list = FxHashMap ( ) ;
2072+ for argument in & declaration. inputs {
2073+ this. resolve_pattern (
2074+ & argument. pat , PatternSource :: FnParam , & mut bindings_list) ;
2075+ this. visit_ty ( & * argument. ty ) ;
2076+ }
2077+ visit:: walk_fn_ret_ty ( this, & declaration. output ) ;
2078+
2079+ // Now resolve the inner closure
2080+ {
2081+ let rib_kind = ClosureRibKind ( async_closure_id) ;
2082+ this. ribs [ ValueNS ] . push ( Rib :: new ( rib_kind) ) ;
2083+ this. label_ribs . push ( Rib :: new ( rib_kind) ) ;
2084+ // No need to resolve either arguments nor return type,
2085+ // as this closure has neither
2086+
2087+ // Resolve the body
2088+ this. visit_block ( body) ;
2089+ this. label_ribs . pop ( ) ;
2090+ this. ribs [ ValueNS ] . pop ( ) ;
2091+ }
2092+ this. label_ribs . pop ( ) ;
2093+ this. ribs [ ValueNS ] . pop ( ) ;
2094+
2095+ walk_list ! ( this, visit_attribute, & item. attrs) ;
2096+ } )
2097+ }
20572098 ItemKind :: Enum ( _, ref generics) |
20582099 ItemKind :: Ty ( _, ref generics) |
20592100 ItemKind :: Struct ( _, ref generics) |
20602101 ItemKind :: Union ( _, ref generics) |
2061- ItemKind :: Fn ( .. , ref generics, _) => {
2102+ ItemKind :: Fn ( _ , _ , ref generics, _) => {
20622103 self . with_type_parameter_rib ( HasTypeParameters ( generics, ItemRibKind ) ,
2063- |this| visit:: walk_item ( this, item) ) ;
2104+ |this| visit:: walk_item ( this, item) ) ;
20642105 }
20652106
20662107 ItemKind :: Impl ( .., ref generics, ref opt_trait_ref, ref self_type, ref impl_items) =>
@@ -3888,6 +3929,49 @@ impl<'a> Resolver<'a> {
38883929 visit:: walk_expr ( self , expr) ;
38893930 self . current_type_ascription . pop ( ) ;
38903931 }
3932+ // Resolve the body of async exprs inside the async closure to which they desugar
3933+ ExprKind :: Async ( _, async_closure_id, ref block) => {
3934+ let rib_kind = ClosureRibKind ( async_closure_id) ;
3935+ self . ribs [ ValueNS ] . push ( Rib :: new ( rib_kind) ) ;
3936+ self . label_ribs . push ( Rib :: new ( rib_kind) ) ;
3937+ self . visit_block ( & block) ;
3938+ self . label_ribs . pop ( ) ;
3939+ self . ribs [ ValueNS ] . pop ( ) ;
3940+ }
3941+ // `async |x| ...` gets desugared to `|x| future_from_generator(|| ...)`, so we need to
3942+ // resolve the arguments within the proper scopes so that usages of them inside the
3943+ // closure are detected as upvars rather than normal closure arg usages.
3944+ ExprKind :: Closure (
3945+ _, IsAsync :: Async ( inner_closure_id) , _, ref fn_decl, ref body, _span) =>
3946+ {
3947+ let rib_kind = ClosureRibKind ( expr. id ) ;
3948+ self . ribs [ ValueNS ] . push ( Rib :: new ( rib_kind) ) ;
3949+ self . label_ribs . push ( Rib :: new ( rib_kind) ) ;
3950+ // Resolve arguments:
3951+ let mut bindings_list = FxHashMap ( ) ;
3952+ for argument in & fn_decl. inputs {
3953+ self . resolve_pattern ( & argument. pat , PatternSource :: FnParam , & mut bindings_list) ;
3954+ self . visit_ty ( & argument. ty ) ;
3955+ }
3956+ // No need to resolve return type-- the outer closure return type is
3957+ // FunctionRetTy::Default
3958+
3959+ // Now resolve the inner closure
3960+ {
3961+ let rib_kind = ClosureRibKind ( inner_closure_id) ;
3962+ self . ribs [ ValueNS ] . push ( Rib :: new ( rib_kind) ) ;
3963+ self . label_ribs . push ( Rib :: new ( rib_kind) ) ;
3964+ // No need to resolve arguments: the inner closure has none.
3965+ // Resolve the return type:
3966+ visit:: walk_fn_ret_ty ( self , & fn_decl. output ) ;
3967+ // Resolve the body
3968+ self . visit_expr ( body) ;
3969+ self . label_ribs . pop ( ) ;
3970+ self . ribs [ ValueNS ] . pop ( ) ;
3971+ }
3972+ self . label_ribs . pop ( ) ;
3973+ self . ribs [ ValueNS ] . pop ( ) ;
3974+ }
38913975 _ => {
38923976 visit:: walk_expr ( self , expr) ;
38933977 }
0 commit comments