@@ -33,7 +33,7 @@ use rustc_middle::{bug, span_bug};
3333use rustc_session:: lint;
3434use rustc_span:: def_id:: LocalDefId ;
3535use rustc_span:: hygiene:: DesugaringKind ;
36- use rustc_span:: symbol:: { kw, sym, Ident } ;
36+ use rustc_span:: symbol:: { kw, sym} ;
3737use rustc_span:: Span ;
3838use rustc_target:: abi:: FieldIdx ;
3939use rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt as _;
@@ -866,76 +866,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
866866 )
867867 }
868868
869- /// Given a function `Node`, return its `HirId` and `FnDecl` if it exists. Given a closure
870- /// that is the child of a function, return that function's `HirId` and `FnDecl` instead.
871- /// This may seem confusing at first, but this is used in diagnostics for `async fn`,
872- /// for example, where most of the type checking actually happens within a nested closure,
873- /// but we often want access to the parent function's signature.
874- ///
875- /// Otherwise, return false.
876- pub ( crate ) fn get_node_fn_decl (
877- & self ,
878- node : Node < ' tcx > ,
879- ) -> Option < ( LocalDefId , & ' tcx hir:: FnDecl < ' tcx > , Ident , bool ) > {
880- match node {
881- Node :: Item ( & hir:: Item {
882- ident,
883- kind : hir:: ItemKind :: Fn ( ref sig, ..) ,
884- owner_id,
885- ..
886- } ) => {
887- // This is less than ideal, it will not suggest a return type span on any
888- // method called `main`, regardless of whether it is actually the entry point,
889- // but it will still present it as the reason for the expected type.
890- Some ( ( owner_id. def_id , & sig. decl , ident, ident. name != sym:: main) )
891- }
892- Node :: TraitItem ( & hir:: TraitItem {
893- ident,
894- kind : hir:: TraitItemKind :: Fn ( ref sig, ..) ,
895- owner_id,
896- ..
897- } ) => Some ( ( owner_id. def_id , & sig. decl , ident, true ) ) ,
898- Node :: ImplItem ( & hir:: ImplItem {
899- ident,
900- kind : hir:: ImplItemKind :: Fn ( ref sig, ..) ,
901- owner_id,
902- ..
903- } ) => Some ( ( owner_id. def_id , & sig. decl , ident, false ) ) ,
904- Node :: Expr ( & hir:: Expr {
905- hir_id,
906- kind :
907- hir:: ExprKind :: Closure ( hir:: Closure {
908- kind : hir:: ClosureKind :: Coroutine ( ..) , ..
909- } ) ,
910- ..
911- } ) => {
912- let ( ident, sig, owner_id) = match self . tcx . parent_hir_node ( hir_id) {
913- Node :: Item ( & hir:: Item {
914- ident,
915- kind : hir:: ItemKind :: Fn ( ref sig, ..) ,
916- owner_id,
917- ..
918- } ) => ( ident, sig, owner_id) ,
919- Node :: TraitItem ( & hir:: TraitItem {
920- ident,
921- kind : hir:: TraitItemKind :: Fn ( ref sig, ..) ,
922- owner_id,
923- ..
924- } ) => ( ident, sig, owner_id) ,
925- Node :: ImplItem ( & hir:: ImplItem {
926- ident,
927- kind : hir:: ImplItemKind :: Fn ( ref sig, ..) ,
928- owner_id,
929- ..
930- } ) => ( ident, sig, owner_id) ,
931- _ => return None ,
932- } ;
933- Some ( ( owner_id. def_id , & sig. decl , ident, ident. name != sym:: main) )
934- }
935- _ => None ,
936- }
937- }
938-
939869 /// Given a `HirId`, return the `HirId` of the enclosing function, its `FnDecl`, and whether a
940870 /// suggestion can be made, `None` otherwise.
941871 pub fn get_fn_decl (
@@ -944,10 +874,73 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
944874 ) -> Option < ( LocalDefId , & ' tcx hir:: FnDecl < ' tcx > , bool ) > {
945875 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
946876 // `while` before reaching it, as block tail returns are not available in them.
947- self . tcx . hir ( ) . get_fn_id_for_return_block ( blk_id) . and_then ( |blk_id| {
948- let parent = self . tcx . hir_node ( blk_id) ;
949- self . get_node_fn_decl ( parent)
950- . map ( |( fn_id, fn_decl, _, is_main) | ( fn_id, fn_decl, is_main) )
877+ self . tcx . hir ( ) . get_fn_id_for_return_block ( blk_id) . and_then ( |item_id| {
878+ match self . tcx . hir_node ( item_id) {
879+ Node :: Item ( & hir:: Item {
880+ ident,
881+ kind : hir:: ItemKind :: Fn ( ref sig, ..) ,
882+ owner_id,
883+ ..
884+ } ) => {
885+ // This is less than ideal, it will not suggest a return type span on any
886+ // method called `main`, regardless of whether it is actually the entry point,
887+ // but it will still present it as the reason for the expected type.
888+ Some ( ( owner_id. def_id , sig. decl , ident. name != sym:: main) )
889+ }
890+ Node :: TraitItem ( & hir:: TraitItem {
891+ kind : hir:: TraitItemKind :: Fn ( ref sig, ..) ,
892+ owner_id,
893+ ..
894+ } ) => Some ( ( owner_id. def_id , sig. decl , true ) ) ,
895+ // FIXME: Suggestable if this is not a trait implementation
896+ Node :: ImplItem ( & hir:: ImplItem {
897+ kind : hir:: ImplItemKind :: Fn ( ref sig, ..) ,
898+ owner_id,
899+ ..
900+ } ) => Some ( ( owner_id. def_id , sig. decl , false ) ) ,
901+ Node :: Expr ( & hir:: Expr {
902+ hir_id,
903+ kind : hir:: ExprKind :: Closure ( & hir:: Closure { def_id, kind, fn_decl, .. } ) ,
904+ ..
905+ } ) => {
906+ match kind {
907+ hir:: ClosureKind :: CoroutineClosure ( _) => {
908+ // FIXME(async_closures): Implement this.
909+ return None ;
910+ }
911+ hir:: ClosureKind :: Closure => Some ( ( def_id, fn_decl, true ) ) ,
912+ hir:: ClosureKind :: Coroutine ( hir:: CoroutineKind :: Desugared (
913+ _,
914+ hir:: CoroutineSource :: Fn ,
915+ ) ) => {
916+ let ( ident, sig, owner_id) = match self . tcx . parent_hir_node ( hir_id) {
917+ Node :: Item ( & hir:: Item {
918+ ident,
919+ kind : hir:: ItemKind :: Fn ( ref sig, ..) ,
920+ owner_id,
921+ ..
922+ } ) => ( ident, sig, owner_id) ,
923+ Node :: TraitItem ( & hir:: TraitItem {
924+ ident,
925+ kind : hir:: TraitItemKind :: Fn ( ref sig, ..) ,
926+ owner_id,
927+ ..
928+ } ) => ( ident, sig, owner_id) ,
929+ Node :: ImplItem ( & hir:: ImplItem {
930+ ident,
931+ kind : hir:: ImplItemKind :: Fn ( ref sig, ..) ,
932+ owner_id,
933+ ..
934+ } ) => ( ident, sig, owner_id) ,
935+ _ => return None ,
936+ } ;
937+ Some ( ( owner_id. def_id , sig. decl , ident. name != sym:: main) )
938+ }
939+ _ => None ,
940+ }
941+ }
942+ _ => None ,
943+ }
951944 } )
952945 }
953946
0 commit comments