@@ -96,7 +96,7 @@ use rustc::middle::region;
9696use rustc:: mir:: interpret:: { GlobalId } ;
9797use rustc:: ty:: subst:: { UnpackedKind , Subst , Substs } ;
9898use rustc:: traits:: { self , ObligationCause , ObligationCauseCode , TraitEngine } ;
99- use rustc:: ty:: { self , Ty , TyCtxt , GenericParamDefKind , Visibility , ToPredicate } ;
99+ use rustc:: ty:: { self , Ty , TyCtxt , GenericParamDefKind , Visibility , ToPredicate , RegionKind } ;
100100use rustc:: ty:: adjustment:: { Adjust , Adjustment , AllowTwoPhase , AutoBorrow , AutoBorrowMutability } ;
101101use rustc:: ty:: fold:: TypeFoldable ;
102102use rustc:: ty:: maps:: Providers ;
@@ -130,7 +130,7 @@ use syntax_pos::{self, BytePos, Span, MultiSpan};
130130use rustc:: hir:: intravisit:: { self , Visitor , NestedVisitorMap } ;
131131use rustc:: hir:: itemlikevisit:: ItemLikeVisitor ;
132132use rustc:: hir:: map:: Node ;
133- use rustc:: hir:: { self , PatKind } ;
133+ use rustc:: hir:: { self , PatKind , Item_ } ;
134134use rustc:: middle:: lang_items;
135135
136136mod autoderef;
@@ -1129,6 +1129,60 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
11291129 }
11301130 }
11311131
1132+ // Check that a function marked as `#[panic_implementation]` has signature `fn(&PanicInfo) -> !`
1133+ if let Some ( panic_impl_did) = fcx. tcx . lang_items ( ) . panic_impl ( ) {
1134+ if panic_impl_did == fn_hir_id. owner_def_id ( ) {
1135+ if let Some ( panic_info_did) = fcx. tcx . lang_items ( ) . panic_info ( ) {
1136+ if declared_ret_ty. sty != ty:: TyNever {
1137+ fcx. tcx . sess . span_err (
1138+ decl. output . span ( ) ,
1139+ "return type should be `!`" ,
1140+ ) ;
1141+ }
1142+
1143+ let inputs = fn_sig. inputs ( ) ;
1144+ let span = fcx. tcx . hir . span ( fn_id) ;
1145+ if inputs. len ( ) == 1 {
1146+ let arg_is_panic_info = match inputs[ 0 ] . sty {
1147+ ty:: TyRef ( region, ty, mutbl) => match ty. sty {
1148+ ty:: TyAdt ( ref adt, _) => {
1149+ adt. did == panic_info_did &&
1150+ mutbl == hir:: Mutability :: MutImmutable &&
1151+ * region != RegionKind :: ReStatic
1152+ } ,
1153+ _ => false ,
1154+ } ,
1155+ _ => false ,
1156+ } ;
1157+
1158+ if !arg_is_panic_info {
1159+ fcx. tcx . sess . span_err (
1160+ decl. inputs [ 0 ] . span ,
1161+ "argument should be `&PanicInfo`" ,
1162+ ) ;
1163+ }
1164+
1165+ if let Node :: NodeItem ( item) = fcx. tcx . hir . get ( fn_id) {
1166+ if let Item_ :: ItemFn ( _, _, _, _, ref generics, _) = item. node {
1167+ if !generics. params . is_empty ( ) {
1168+ fcx. tcx . sess . span_err (
1169+ span,
1170+ "`#[panic_implementation]` function should have no type \
1171+ parameters",
1172+ ) ;
1173+ }
1174+ }
1175+ }
1176+ } else {
1177+ fcx. tcx . sess . span_err ( span, "function should have one argument" ) ;
1178+ }
1179+ } else {
1180+ fcx. tcx . sess . err ( "language item required, but not found: `panic_info`" ) ;
1181+ }
1182+ }
1183+
1184+ }
1185+
11321186 ( fcx, gen_ty)
11331187}
11341188
0 commit comments