|
1 | 1 | //! Inlining pass for MIR functions
|
2 | 2 | use crate::deref_separator::deref_finder;
|
3 | 3 | use rustc_attr::InlineAttr;
|
| 4 | +use rustc_const_eval::transform::validate::equal_up_to_regions; |
4 | 5 | use rustc_index::bit_set::BitSet;
|
5 | 6 | use rustc_index::vec::Idx;
|
6 | 7 | use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
|
@@ -166,6 +167,45 @@ impl<'tcx> Inliner<'tcx> {
|
166 | 167 | return Err("failed to normalize callee body");
|
167 | 168 | };
|
168 | 169 |
|
| 170 | + // Check call signature compatibility. |
| 171 | + // Normally, this shouldn't be required, but trait normalization failure can create a |
| 172 | + // validation ICE. |
| 173 | + let terminator = caller_body[callsite.block].terminator.as_ref().unwrap(); |
| 174 | + let TerminatorKind::Call { args, destination, .. } = &terminator.kind else { bug!() }; |
| 175 | + let destination_ty = destination.ty(&caller_body.local_decls, self.tcx).ty; |
| 176 | + let output_type = callee_body.return_ty(); |
| 177 | + if !equal_up_to_regions(self.tcx, self.param_env, output_type, destination_ty) { |
| 178 | + trace!(?output_type, ?destination_ty); |
| 179 | + return Err("failed to normalize return type"); |
| 180 | + } |
| 181 | + if callsite.fn_sig.abi() == Abi::RustCall { |
| 182 | + let mut args = args.into_iter(); |
| 183 | + let _ = args.next(); // Skip `self` argument. |
| 184 | + let arg_tuple_ty = args.next().unwrap().ty(&caller_body.local_decls, self.tcx); |
| 185 | + assert!(args.next().is_none()); |
| 186 | + |
| 187 | + let ty::Tuple(arg_tuple_tys) = arg_tuple_ty.kind() else { |
| 188 | + bug!("Closure arguments are not passed as a tuple"); |
| 189 | + }; |
| 190 | + |
| 191 | + for (arg_ty, input) in arg_tuple_tys.iter().zip(callee_body.args_iter().skip(1)) { |
| 192 | + let input_type = callee_body.local_decls[input].ty; |
| 193 | + if !equal_up_to_regions(self.tcx, self.param_env, arg_ty, input_type) { |
| 194 | + trace!(?arg_ty, ?input_type); |
| 195 | + return Err("failed to normalize tuple argument type"); |
| 196 | + } |
| 197 | + } |
| 198 | + } else { |
| 199 | + for (arg, input) in args.iter().zip(callee_body.args_iter()) { |
| 200 | + let input_type = callee_body.local_decls[input].ty; |
| 201 | + let arg_ty = arg.ty(&caller_body.local_decls, self.tcx); |
| 202 | + if !equal_up_to_regions(self.tcx, self.param_env, arg_ty, input_type) { |
| 203 | + trace!(?arg_ty, ?input_type); |
| 204 | + return Err("failed to normalize argument type"); |
| 205 | + } |
| 206 | + } |
| 207 | + } |
| 208 | + |
169 | 209 | let old_blocks = caller_body.basic_blocks().next_index();
|
170 | 210 | self.inline_call(caller_body, &callsite, callee_body);
|
171 | 211 | let new_blocks = old_blocks..caller_body.basic_blocks().next_index();
|
|
0 commit comments