@@ -96,7 +96,7 @@ use rustc::middle::region;
96
96
use rustc:: mir:: interpret:: { GlobalId } ;
97
97
use rustc:: ty:: subst:: { UnpackedKind , Subst , Substs } ;
98
98
use 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 } ;
100
100
use rustc:: ty:: adjustment:: { Adjust , Adjustment , AllowTwoPhase , AutoBorrow , AutoBorrowMutability } ;
101
101
use rustc:: ty:: fold:: TypeFoldable ;
102
102
use rustc:: ty:: maps:: Providers ;
@@ -130,7 +130,7 @@ use syntax_pos::{self, BytePos, Span, MultiSpan};
130
130
use rustc:: hir:: intravisit:: { self , Visitor , NestedVisitorMap } ;
131
131
use rustc:: hir:: itemlikevisit:: ItemLikeVisitor ;
132
132
use rustc:: hir:: map:: Node ;
133
- use rustc:: hir:: { self , PatKind } ;
133
+ use rustc:: hir:: { self , PatKind , Item_ } ;
134
134
use rustc:: middle:: lang_items;
135
135
136
136
mod autoderef;
@@ -1129,6 +1129,60 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
1129
1129
}
1130
1130
}
1131
1131
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
+
1132
1186
( fcx, gen_ty)
1133
1187
}
1134
1188
0 commit comments