@@ -33,7 +33,7 @@ use rustc_middle::ty::{GenericArgKind, GenericArgsRef, UserArgs, UserSelfTy};
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 _;
@@ -936,76 +936,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
936936 )
937937 }
938938
939- /// Given a function `Node`, return its `HirId` and `FnDecl` if it exists. Given a closure
940- /// that is the child of a function, return that function's `HirId` and `FnDecl` instead.
941- /// This may seem confusing at first, but this is used in diagnostics for `async fn`,
942- /// for example, where most of the type checking actually happens within a nested closure,
943- /// but we often want access to the parent function's signature.
944- ///
945- /// Otherwise, return false.
946- pub ( in super :: super ) fn get_node_fn_decl (
947- & self ,
948- node : Node < ' tcx > ,
949- ) -> Option < ( LocalDefId , & ' tcx hir:: FnDecl < ' tcx > , Ident , bool ) > {
950- match node {
951- Node :: Item ( & hir:: Item {
952- ident,
953- kind : hir:: ItemKind :: Fn ( ref sig, ..) ,
954- owner_id,
955- ..
956- } ) => {
957- // This is less than ideal, it will not suggest a return type span on any
958- // method called `main`, regardless of whether it is actually the entry point,
959- // but it will still present it as the reason for the expected type.
960- Some ( ( owner_id. def_id , & sig. decl , ident, ident. name != sym:: main) )
961- }
962- Node :: TraitItem ( & hir:: TraitItem {
963- ident,
964- kind : hir:: TraitItemKind :: Fn ( ref sig, ..) ,
965- owner_id,
966- ..
967- } ) => Some ( ( owner_id. def_id , & sig. decl , ident, true ) ) ,
968- Node :: ImplItem ( & hir:: ImplItem {
969- ident,
970- kind : hir:: ImplItemKind :: Fn ( ref sig, ..) ,
971- owner_id,
972- ..
973- } ) => Some ( ( owner_id. def_id , & sig. decl , ident, false ) ) ,
974- Node :: Expr ( & hir:: Expr {
975- hir_id,
976- kind :
977- hir:: ExprKind :: Closure ( hir:: Closure {
978- kind : hir:: ClosureKind :: Coroutine ( ..) , ..
979- } ) ,
980- ..
981- } ) => {
982- let ( ident, sig, owner_id) = match self . tcx . parent_hir_node ( hir_id) {
983- Node :: Item ( & hir:: Item {
984- ident,
985- kind : hir:: ItemKind :: Fn ( ref sig, ..) ,
986- owner_id,
987- ..
988- } ) => ( ident, sig, owner_id) ,
989- Node :: TraitItem ( & hir:: TraitItem {
990- ident,
991- kind : hir:: TraitItemKind :: Fn ( ref sig, ..) ,
992- owner_id,
993- ..
994- } ) => ( ident, sig, owner_id) ,
995- Node :: ImplItem ( & hir:: ImplItem {
996- ident,
997- kind : hir:: ImplItemKind :: Fn ( ref sig, ..) ,
998- owner_id,
999- ..
1000- } ) => ( ident, sig, owner_id) ,
1001- _ => return None ,
1002- } ;
1003- Some ( ( owner_id. def_id , & sig. decl , ident, ident. name != sym:: main) )
1004- }
1005- _ => None ,
1006- }
1007- }
1008-
1009939 /// Given a `HirId`, return the `HirId` of the enclosing function, its `FnDecl`, and whether a
1010940 /// suggestion can be made, `None` otherwise.
1011941 pub fn get_fn_decl (
@@ -1014,10 +944,72 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1014944 ) -> Option < ( LocalDefId , & ' tcx hir:: FnDecl < ' tcx > , bool ) > {
1015945 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
1016946 // `while` before reaching it, as block tail returns are not available in them.
1017- self . tcx . hir ( ) . get_fn_id_for_return_block ( blk_id) . and_then ( |blk_id| {
1018- let parent = self . tcx . hir_node ( blk_id) ;
1019- self . get_node_fn_decl ( parent)
1020- . map ( |( fn_id, fn_decl, _, is_main) | ( fn_id, fn_decl, is_main) )
947+ self . tcx . hir ( ) . get_fn_id_for_return_block ( blk_id) . and_then ( |item_id| {
948+ match self . tcx . hir_node ( item_id) {
949+ Node :: Item ( & hir:: Item {
950+ ident,
951+ kind : hir:: ItemKind :: Fn ( ref sig, ..) ,
952+ owner_id,
953+ ..
954+ } ) => {
955+ // This is less than ideal, it will not suggest a return type span on any
956+ // method called `main`, regardless of whether it is actually the entry point,
957+ // but it will still present it as the reason for the expected type.
958+ Some ( ( owner_id. def_id , sig. decl , ident. name != sym:: main) )
959+ }
960+ Node :: TraitItem ( & hir:: TraitItem {
961+ kind : hir:: TraitItemKind :: Fn ( ref sig, ..) ,
962+ owner_id,
963+ ..
964+ } ) => Some ( ( owner_id. def_id , sig. decl , true ) ) ,
965+ // FIXME: Suggestable if this is not a trait implementation
966+ Node :: ImplItem ( & hir:: ImplItem {
967+ kind : hir:: ImplItemKind :: Fn ( ref sig, ..) ,
968+ owner_id,
969+ ..
970+ } ) => Some ( ( owner_id. def_id , sig. decl , false ) ) ,
971+ Node :: Expr ( & hir:: Expr {
972+ hir_id,
973+ kind : hir:: ExprKind :: Closure ( & hir:: Closure { def_id, kind, fn_decl, .. } ) ,
974+ ..
975+ } ) => {
976+ match kind {
977+ hir:: ClosureKind :: CoroutineClosure ( _) => {
978+ // FIXME(async_closures): Implement this.
979+ return None ;
980+ }
981+ hir:: ClosureKind :: Coroutine ( hir:: CoroutineKind :: Desugared (
982+ _,
983+ hir:: CoroutineSource :: Fn ,
984+ ) ) => {
985+ let ( ident, sig, owner_id) = match self . tcx . parent_hir_node ( hir_id) {
986+ Node :: Item ( & hir:: Item {
987+ ident,
988+ kind : hir:: ItemKind :: Fn ( ref sig, ..) ,
989+ owner_id,
990+ ..
991+ } ) => ( ident, sig, owner_id) ,
992+ Node :: TraitItem ( & hir:: TraitItem {
993+ ident,
994+ kind : hir:: TraitItemKind :: Fn ( ref sig, ..) ,
995+ owner_id,
996+ ..
997+ } ) => ( ident, sig, owner_id) ,
998+ Node :: ImplItem ( & hir:: ImplItem {
999+ ident,
1000+ kind : hir:: ImplItemKind :: Fn ( ref sig, ..) ,
1001+ owner_id,
1002+ ..
1003+ } ) => ( ident, sig, owner_id) ,
1004+ _ => return None ,
1005+ } ;
1006+ Some ( ( owner_id. def_id , sig. decl , ident. name != sym:: main) )
1007+ }
1008+ _ => Some ( ( def_id, fn_decl, true ) ) ,
1009+ }
1010+ }
1011+ _ => None ,
1012+ }
10211013 } )
10221014 }
10231015
0 commit comments