@@ -172,8 +172,7 @@ impl<'tcx> Inliner<'tcx> {
172
172
self . check_codegen_attributes ( callsite, callee_attrs) ?;
173
173
174
174
let terminator = caller_body[ callsite. block ] . terminator . as_ref ( ) . unwrap ( ) ;
175
- let TerminatorKind :: Call { args, destination, .. } = & terminator. kind else { bug ! ( ) } ;
176
- let destination_ty = destination. ty ( & caller_body. local_decls , self . tcx ) . ty ;
175
+ let TerminatorKind :: Call { args, .. } = & terminator. kind else { bug ! ( ) } ;
177
176
for arg in args {
178
177
if !arg. ty ( & caller_body. local_decls , self . tcx ) . is_sized ( self . tcx , self . param_env ) {
179
178
// We do not allow inlining functions with unsized params. Inlining these functions
@@ -200,45 +199,7 @@ impl<'tcx> Inliner<'tcx> {
200
199
return Err ( "failed to normalize callee body" ) ;
201
200
} ;
202
201
203
- // Check call signature compatibility.
204
- // Normally, this shouldn't be required, but trait normalization failure can create a
205
- // validation ICE.
206
- let output_type = callee_body. return_ty ( ) ;
207
- if !util:: is_subtype ( self . tcx , self . param_env , output_type, destination_ty) {
208
- trace ! ( ?output_type, ?destination_ty) ;
209
- return Err ( "failed to normalize return type" ) ;
210
- }
211
- if callsite. fn_sig . abi ( ) == Abi :: RustCall {
212
- let ( arg_tuple, skipped_args) = match & args[ ..] {
213
- [ arg_tuple] => ( arg_tuple, 0 ) ,
214
- [ _, arg_tuple] => ( arg_tuple, 1 ) ,
215
- _ => bug ! ( "Expected `rust-call` to have 1 or 2 args" ) ,
216
- } ;
217
-
218
- let arg_tuple_ty = arg_tuple. ty ( & caller_body. local_decls , self . tcx ) ;
219
- let ty:: Tuple ( arg_tuple_tys) = arg_tuple_ty. kind ( ) else {
220
- bug ! ( "Closure arguments are not passed as a tuple" ) ;
221
- } ;
222
-
223
- for ( arg_ty, input) in
224
- arg_tuple_tys. iter ( ) . zip ( callee_body. args_iter ( ) . skip ( skipped_args) )
225
- {
226
- let input_type = callee_body. local_decls [ input] . ty ;
227
- if !util:: is_subtype ( self . tcx , self . param_env , input_type, arg_ty) {
228
- trace ! ( ?arg_ty, ?input_type) ;
229
- return Err ( "failed to normalize tuple argument type" ) ;
230
- }
231
- }
232
- } else {
233
- for ( arg, input) in args. iter ( ) . zip ( callee_body. args_iter ( ) ) {
234
- let input_type = callee_body. local_decls [ input] . ty ;
235
- let arg_ty = arg. ty ( & caller_body. local_decls , self . tcx ) ;
236
- if !util:: is_subtype ( self . tcx , self . param_env , input_type, arg_ty) {
237
- trace ! ( ?arg_ty, ?input_type) ;
238
- return Err ( "failed to normalize argument type" ) ;
239
- }
240
- }
241
- }
202
+ self . check_subst_body ( caller_body, callsite, & callee_body) ?;
242
203
243
204
let old_blocks = caller_body. basic_blocks . next_index ( ) ;
244
205
self . inline_call ( caller_body, & callsite, callee_body) ;
@@ -492,6 +453,58 @@ impl<'tcx> Inliner<'tcx> {
492
453
}
493
454
}
494
455
456
+ /// Check call signature compatibility.
457
+ /// Normally, this shouldn't be required, but trait normalization failure can create a
458
+ /// validation ICE.
459
+ fn check_subst_body (
460
+ & self ,
461
+ caller_body : & Body < ' tcx > ,
462
+ callsite : & CallSite < ' tcx > ,
463
+ callee_body : & Body < ' tcx > ,
464
+ ) -> Result < ( ) , & ' static str > {
465
+ let terminator = caller_body[ callsite. block ] . terminator . as_ref ( ) . unwrap ( ) ;
466
+ let TerminatorKind :: Call { args, destination, .. } = & terminator. kind else { bug ! ( ) } ;
467
+ let destination_ty = destination. ty ( & caller_body. local_decls , self . tcx ) . ty ;
468
+ let output_type = callee_body. return_ty ( ) ;
469
+ if !util:: is_subtype ( self . tcx , self . param_env , output_type, destination_ty) {
470
+ trace ! ( ?output_type, ?destination_ty) ;
471
+ return Err ( "failed to normalize return type" ) ;
472
+ }
473
+ if callsite. fn_sig . abi ( ) == Abi :: RustCall {
474
+ let ( arg_tuple, skipped_args) = match & args[ ..] {
475
+ [ arg_tuple] => ( arg_tuple, 0 ) ,
476
+ [ _, arg_tuple] => ( arg_tuple, 1 ) ,
477
+ _ => bug ! ( "Expected `rust-call` to have 1 or 2 args" ) ,
478
+ } ;
479
+
480
+ let arg_tuple_ty = arg_tuple. ty ( & caller_body. local_decls , self . tcx ) ;
481
+ let ty:: Tuple ( arg_tuple_tys) = arg_tuple_ty. kind ( ) else {
482
+ bug ! ( "Closure arguments are not passed as a tuple" ) ;
483
+ } ;
484
+
485
+ for ( arg_ty, input) in
486
+ arg_tuple_tys. iter ( ) . zip ( callee_body. args_iter ( ) . skip ( skipped_args) )
487
+ {
488
+ let input_type = callee_body. local_decls [ input] . ty ;
489
+ if !util:: is_subtype ( self . tcx , self . param_env , input_type, arg_ty) {
490
+ trace ! ( ?arg_ty, ?input_type) ;
491
+ return Err ( "failed to normalize tuple argument type" ) ;
492
+ }
493
+ }
494
+ } else {
495
+ for ( arg, input) in args. iter ( ) . zip ( callee_body. args_iter ( ) ) {
496
+ let input_type = callee_body. local_decls [ input] . ty ;
497
+ let arg_ty = arg. ty ( & caller_body. local_decls , self . tcx ) ;
498
+ if !util:: is_subtype ( self . tcx , self . param_env , input_type, arg_ty) {
499
+ trace ! ( ?arg_ty, ?input_type) ;
500
+ return Err ( "failed to normalize argument type" ) ;
501
+ }
502
+ }
503
+ }
504
+
505
+ Ok ( ( ) )
506
+ }
507
+
495
508
fn inline_call (
496
509
& self ,
497
510
caller_body : & mut Body < ' tcx > ,
0 commit comments