@@ -172,8 +172,7 @@ impl<'tcx> Inliner<'tcx> {
172172 self . check_codegen_attributes ( callsite, callee_attrs) ?;
173173
174174 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 ! ( ) } ;
177176 for arg in args {
178177 if !arg. ty ( & caller_body. local_decls , self . tcx ) . is_sized ( self . tcx , self . param_env ) {
179178 // We do not allow inlining functions with unsized params. Inlining these functions
@@ -200,45 +199,7 @@ impl<'tcx> Inliner<'tcx> {
200199 return Err ( "failed to normalize callee body" ) ;
201200 } ;
202201
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) ?;
242203
243204 let old_blocks = caller_body. basic_blocks . next_index ( ) ;
244205 self . inline_call ( caller_body, & callsite, callee_body) ;
@@ -492,6 +453,58 @@ impl<'tcx> Inliner<'tcx> {
492453 }
493454 }
494455
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+
495508 fn inline_call (
496509 & self ,
497510 caller_body : & mut Body < ' tcx > ,
0 commit comments