@@ -8,10 +8,11 @@ use super::*;
8
8
use rustc_attr as attr;
9
9
use rustc_errors:: { Applicability , ErrorGuaranteed , MultiSpan } ;
10
10
use rustc_hir as hir;
11
+ use rustc_hir:: def:: { DefKind , Res } ;
11
12
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
12
13
use rustc_hir:: intravisit:: Visitor ;
13
14
use rustc_hir:: lang_items:: LangItem ;
14
- use rustc_hir:: { def :: Res , ItemKind , Node , PathSegment } ;
15
+ use rustc_hir:: { ItemKind , Node , PathSegment } ;
15
16
use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
16
17
use rustc_infer:: infer:: { RegionVariableOrigin , TyCtxtInferExt } ;
17
18
use rustc_infer:: traits:: Obligation ;
@@ -29,7 +30,6 @@ use rustc_trait_selection::traits;
29
30
use rustc_trait_selection:: traits:: error_reporting:: InferCtxtExt as _;
30
31
use rustc_ty_utils:: representability:: { self , Representability } ;
31
32
32
- use rustc_hir:: def:: DefKind ;
33
33
use std:: iter;
34
34
use std:: ops:: ControlFlow ;
35
35
@@ -93,7 +93,6 @@ pub(super) fn check_fn<'a, 'tcx>(
93
93
fcx. return_type_pre_known = return_type_pre_known;
94
94
95
95
let tcx = fcx. tcx ;
96
- let sess = tcx. sess ;
97
96
let hir = tcx. hir ( ) ;
98
97
99
98
let declared_ret_ty = fn_sig. output ( ) ;
@@ -260,85 +259,123 @@ pub(super) fn check_fn<'a, 'tcx>(
260
259
if let Some ( panic_impl_did) = tcx. lang_items ( ) . panic_impl ( )
261
260
&& panic_impl_did == hir. local_def_id ( fn_id) . to_def_id ( )
262
261
{
263
- if let Some ( panic_info_did) = tcx. lang_items ( ) . panic_info ( ) {
264
- if * declared_ret_ty. kind ( ) != ty:: Never {
265
- sess. span_err ( decl. output . span ( ) , "return type should be `!`" ) ;
266
- }
267
-
268
- let inputs = fn_sig. inputs ( ) ;
269
- let span = hir. span ( fn_id) ;
270
- if inputs. len ( ) == 1 {
271
- let arg_is_panic_info = match * inputs[ 0 ] . kind ( ) {
272
- ty:: Ref ( region, ty, mutbl) => match * ty. kind ( ) {
273
- ty:: Adt ( ref adt, _) => {
274
- adt. did ( ) == panic_info_did
275
- && mutbl == hir:: Mutability :: Not
276
- && !region. is_static ( )
277
- }
278
- _ => false ,
279
- } ,
280
- _ => false ,
281
- } ;
282
-
283
- if !arg_is_panic_info {
284
- sess. span_err ( decl. inputs [ 0 ] . span , "argument should be `&PanicInfo`" ) ;
285
- }
286
-
287
- if let Node :: Item ( item) = hir. get ( fn_id)
288
- && let ItemKind :: Fn ( _, ref generics, _) = item. kind
289
- && !generics. params . is_empty ( )
290
- {
291
- sess. span_err ( span, "should have no type parameters" ) ;
292
- }
293
- } else {
294
- let span = sess. source_map ( ) . guess_head_span ( span) ;
295
- sess. span_err ( span, "function should have one argument" ) ;
296
- }
297
- } else {
298
- sess. err ( "language item required, but not found: `panic_info`" ) ;
299
- }
262
+ check_panic_info_fn ( tcx, panic_impl_did. expect_local ( ) , fn_sig, decl, declared_ret_ty) ;
300
263
}
301
264
302
265
// Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
303
266
if let Some ( alloc_error_handler_did) = tcx. lang_items ( ) . oom ( )
304
267
&& alloc_error_handler_did == hir. local_def_id ( fn_id) . to_def_id ( )
305
268
{
306
- if let Some ( alloc_layout_did) = tcx. lang_items ( ) . alloc_layout ( ) {
307
- if * declared_ret_ty. kind ( ) != ty:: Never {
308
- sess. span_err ( decl. output . span ( ) , "return type should be `!`" ) ;
309
- }
269
+ check_alloc_error_fn ( tcx, alloc_error_handler_did. expect_local ( ) , fn_sig, decl, declared_ret_ty) ;
270
+ }
310
271
311
- let inputs = fn_sig. inputs ( ) ;
312
- let span = hir. span ( fn_id) ;
313
- if inputs. len ( ) == 1 {
314
- let arg_is_alloc_layout = match inputs[ 0 ] . kind ( ) {
315
- ty:: Adt ( ref adt, _) => adt. did ( ) == alloc_layout_did,
316
- _ => false ,
317
- } ;
272
+ ( fcx, gen_ty)
273
+ }
318
274
319
- if !arg_is_alloc_layout {
320
- sess. span_err ( decl. inputs [ 0 ] . span , "argument should be `Layout`" ) ;
321
- }
275
+ fn check_panic_info_fn (
276
+ tcx : TyCtxt < ' _ > ,
277
+ fn_id : LocalDefId ,
278
+ fn_sig : ty:: FnSig < ' _ > ,
279
+ decl : & hir:: FnDecl < ' _ > ,
280
+ declared_ret_ty : Ty < ' _ > ,
281
+ ) {
282
+ let Some ( panic_info_did) = tcx. lang_items ( ) . panic_info ( ) else {
283
+ tcx. sess . err ( "language item required, but not found: `panic_info`" ) ;
284
+ return ;
285
+ } ;
322
286
323
- if let Node :: Item ( item) = hir. get ( fn_id)
324
- && let ItemKind :: Fn ( _, ref generics, _) = item. kind
325
- && !generics. params . is_empty ( )
326
- {
327
- sess. span_err (
328
- span,
329
- "`#[alloc_error_handler]` function should have no type parameters" ,
330
- ) ;
331
- }
332
- } else {
333
- let span = sess. source_map ( ) . guess_head_span ( span) ;
334
- sess. span_err ( span, "function should have one argument" ) ;
287
+ if * declared_ret_ty. kind ( ) != ty:: Never {
288
+ tcx. sess . span_err ( decl. output . span ( ) , "return type should be `!`" ) ;
289
+ }
290
+
291
+ let span = tcx. def_span ( fn_id) ;
292
+ let inputs = fn_sig. inputs ( ) ;
293
+ if inputs. len ( ) != 1 {
294
+ let span = tcx. sess . source_map ( ) . guess_head_span ( span) ;
295
+ tcx. sess . span_err ( span, "function should have one argument" ) ;
296
+ return ;
297
+ }
298
+
299
+ let arg_is_panic_info = match * inputs[ 0 ] . kind ( ) {
300
+ ty:: Ref ( region, ty, mutbl) => match * ty. kind ( ) {
301
+ ty:: Adt ( ref adt, _) => {
302
+ adt. did ( ) == panic_info_did && mutbl == hir:: Mutability :: Not && !region. is_static ( )
335
303
}
336
- } else {
337
- sess. err ( "language item required, but not found: `alloc_layout`" ) ;
338
- }
304
+ _ => false ,
305
+ } ,
306
+ _ => false ,
307
+ } ;
308
+
309
+ if !arg_is_panic_info {
310
+ tcx. sess . span_err ( decl. inputs [ 0 ] . span , "argument should be `&PanicInfo`" ) ;
339
311
}
340
312
341
- ( fcx, gen_ty)
313
+ let DefKind :: Fn = tcx. def_kind ( fn_id) else {
314
+ let span = tcx. def_span ( fn_id) ;
315
+ tcx. sess . span_err ( span, "should be a function" ) ;
316
+ return ;
317
+ } ;
318
+
319
+ let generic_counts = tcx. generics_of ( fn_id) . own_counts ( ) ;
320
+ if generic_counts. types != 0 {
321
+ let span = tcx. def_span ( fn_id) ;
322
+ tcx. sess . span_err ( span, "should have no type parameters" ) ;
323
+ }
324
+ if generic_counts. consts != 0 {
325
+ let span = tcx. def_span ( fn_id) ;
326
+ tcx. sess . span_err ( span, "should have no const parameters" ) ;
327
+ }
328
+ }
329
+
330
+ fn check_alloc_error_fn (
331
+ tcx : TyCtxt < ' _ > ,
332
+ fn_id : LocalDefId ,
333
+ fn_sig : ty:: FnSig < ' _ > ,
334
+ decl : & hir:: FnDecl < ' _ > ,
335
+ declared_ret_ty : Ty < ' _ > ,
336
+ ) {
337
+ let Some ( alloc_layout_did) = tcx. lang_items ( ) . alloc_layout ( ) else {
338
+ tcx. sess . err ( "language item required, but not found: `alloc_layout`" ) ;
339
+ return ;
340
+ } ;
341
+
342
+ if * declared_ret_ty. kind ( ) != ty:: Never {
343
+ tcx. sess . span_err ( decl. output . span ( ) , "return type should be `!`" ) ;
344
+ }
345
+
346
+ let inputs = fn_sig. inputs ( ) ;
347
+ if inputs. len ( ) != 1 {
348
+ let span = tcx. def_span ( fn_id) ;
349
+ let span = tcx. sess . source_map ( ) . guess_head_span ( span) ;
350
+ tcx. sess . span_err ( span, "function should have one argument" ) ;
351
+ return ;
352
+ }
353
+
354
+ let arg_is_alloc_layout = match inputs[ 0 ] . kind ( ) {
355
+ ty:: Adt ( ref adt, _) => adt. did ( ) == alloc_layout_did,
356
+ _ => false ,
357
+ } ;
358
+
359
+ if !arg_is_alloc_layout {
360
+ tcx. sess . span_err ( decl. inputs [ 0 ] . span , "argument should be `Layout`" ) ;
361
+ }
362
+
363
+ let DefKind :: Fn = tcx. def_kind ( fn_id) else {
364
+ let span = tcx. def_span ( fn_id) ;
365
+ tcx. sess . span_err ( span, "`#[alloc_error_handler]` should be a function" ) ;
366
+ return ;
367
+ } ;
368
+
369
+ let generic_counts = tcx. generics_of ( fn_id) . own_counts ( ) ;
370
+ if generic_counts. types != 0 {
371
+ let span = tcx. def_span ( fn_id) ;
372
+ tcx. sess . span_err ( span, "`#[alloc_error_handler]` function should have no type parameters" ) ;
373
+ }
374
+ if generic_counts. consts != 0 {
375
+ let span = tcx. def_span ( fn_id) ;
376
+ tcx. sess
377
+ . span_err ( span, "`#[alloc_error_handler]` function should have no const parameters" ) ;
378
+ }
342
379
}
343
380
344
381
fn check_struct ( tcx : TyCtxt < ' _ > , def_id : LocalDefId , span : Span ) {
0 commit comments