@@ -898,51 +898,74 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
898898 )
899899 }
900900
901- /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
901+ /// Given a function `Node`, return its `HirId` and `FnDecl` if it exists. Given a closure
902+ /// that is the child of a function, return that function's `HirId` and `FnDecl` instead.
903+ /// This may seem confusing at first, but this is used in diagnostics for `async fn`,
904+ /// for example, where most of the type checking actually happens within a nested closure,
905+ /// but we often want access to the parent function's signature.
906+ ///
907+ /// Otherwise, return false.
902908 pub ( in super :: super ) fn get_node_fn_decl (
903909 & self ,
904910 node : Node < ' tcx > ,
905- ) -> Option < ( & ' tcx hir:: FnDecl < ' tcx > , Ident , bool ) > {
911+ ) -> Option < ( hir :: HirId , & ' tcx hir:: FnDecl < ' tcx > , Ident , bool ) > {
906912 match node {
907- Node :: Item ( & hir:: Item { ident, kind : hir:: ItemKind :: Fn ( ref sig, ..) , .. } ) => {
913+ Node :: Item ( & hir:: Item {
914+ ident,
915+ kind : hir:: ItemKind :: Fn ( ref sig, ..) ,
916+ owner_id,
917+ ..
918+ } ) => {
908919 // This is less than ideal, it will not suggest a return type span on any
909920 // method called `main`, regardless of whether it is actually the entry point,
910921 // but it will still present it as the reason for the expected type.
911- Some ( ( & sig. decl , ident, ident. name != sym:: main) )
922+ Some ( (
923+ hir:: HirId :: make_owner ( owner_id. def_id ) ,
924+ & sig. decl ,
925+ ident,
926+ ident. name != sym:: main,
927+ ) )
912928 }
913929 Node :: TraitItem ( & hir:: TraitItem {
914930 ident,
915931 kind : hir:: TraitItemKind :: Fn ( ref sig, ..) ,
932+ owner_id,
916933 ..
917- } ) => Some ( ( & sig. decl , ident, true ) ) ,
934+ } ) => Some ( ( hir :: HirId :: make_owner ( owner_id . def_id ) , & sig. decl , ident, true ) ) ,
918935 Node :: ImplItem ( & hir:: ImplItem {
919936 ident,
920937 kind : hir:: ImplItemKind :: Fn ( ref sig, ..) ,
938+ owner_id,
921939 ..
922- } ) => Some ( ( & sig. decl , ident, false ) ) ,
923- Node :: Expr ( & hir:: Expr {
924- hir_id,
925- kind : hir:: ExprKind :: Closure ( ..) ,
926- ..
927- } ) if let Some ( Node :: Item ( & hir:: Item {
940+ } ) => Some ( ( hir:: HirId :: make_owner ( owner_id. def_id ) , & sig. decl , ident, false ) ) ,
941+ Node :: Expr ( & hir:: Expr { hir_id, kind : hir:: ExprKind :: Closure ( ..) , .. } )
942+ if let Some ( Node :: Item ( & hir:: Item {
943+ ident,
944+ kind : hir:: ItemKind :: Fn ( ref sig, ..) ,
945+ owner_id,
946+ ..
947+ } ) ) = self . tcx . hir ( ) . find_parent ( hir_id) => Some ( (
948+ hir:: HirId :: make_owner ( owner_id. def_id ) ,
949+ & sig. decl ,
928950 ident,
929- kind : hir:: ItemKind :: Fn ( ref sig, ..) ,
930- ..
931- } ) ) = self . tcx . hir ( ) . find_parent ( hir_id) => {
932- Some ( ( & sig. decl , ident, ident. name != sym:: main) )
933- } ,
951+ ident. name != sym:: main,
952+ ) ) ,
934953 _ => None ,
935954 }
936955 }
937956
938- /// Given a `HirId`, return the `FnDecl ` of the method it is enclosed by and whether a
957+ /// Given a `HirId`, return the `HirId ` of the enclosing function, its `FnDecl`, and whether a
939958 /// suggestion can be made, `None` otherwise.
940- pub fn get_fn_decl ( & self , blk_id : hir:: HirId ) -> Option < ( & ' tcx hir:: FnDecl < ' tcx > , bool ) > {
959+ pub fn get_fn_decl (
960+ & self ,
961+ blk_id : hir:: HirId ,
962+ ) -> Option < ( hir:: HirId , & ' tcx hir:: FnDecl < ' tcx > , bool ) > {
941963 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
942964 // `while` before reaching it, as block tail returns are not available in them.
943965 self . tcx . hir ( ) . get_return_block ( blk_id) . and_then ( |blk_id| {
944966 let parent = self . tcx . hir ( ) . get ( blk_id) ;
945- self . get_node_fn_decl ( parent) . map ( |( fn_decl, _, is_main) | ( fn_decl, is_main) )
967+ self . get_node_fn_decl ( parent)
968+ . map ( |( fn_id, fn_decl, _, is_main) | ( fn_id, fn_decl, is_main) )
946969 } )
947970 }
948971
0 commit comments