@@ -182,19 +182,24 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
182182 }
183183
184184 fn check_argument_compat (
185+ rust_abi : bool ,
185186 caller : TyLayout < ' tcx > ,
186187 callee : TyLayout < ' tcx > ,
187188 ) -> bool {
188189 if caller. ty == callee. ty {
189190 // No question
190191 return true ;
191192 }
193+ if !rust_abi {
194+ // Don't risk anything
195+ return false ;
196+ }
192197 // Compare layout
193198 match ( & caller. abi , & callee. abi ) {
199+ // Different valid ranges are okay (once we enforce validity,
200+ // that will take care to make it UB to leave the range, just
201+ // like for transmute).
194202 ( layout:: Abi :: Scalar ( ref caller) , layout:: Abi :: Scalar ( ref callee) ) =>
195- // Different valid ranges are okay (once we enforce validity,
196- // that will take care to make it UB to leave the range, just
197- // like for transmute).
198203 caller. value == callee. value ,
199204 ( layout:: Abi :: ScalarPair ( ref caller1, ref caller2) ,
200205 layout:: Abi :: ScalarPair ( ref callee1, ref callee2) ) =>
@@ -207,22 +212,22 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
207212 /// Pass a single argument, checking the types for compatibility.
208213 fn pass_argument (
209214 & mut self ,
210- skip_zst : bool ,
215+ rust_abi : bool ,
211216 caller_arg : & mut impl Iterator < Item =OpTy < ' tcx , M :: PointerTag > > ,
212217 callee_arg : PlaceTy < ' tcx , M :: PointerTag > ,
213218 ) -> EvalResult < ' tcx > {
214- if skip_zst && callee_arg. layout . is_zst ( ) {
219+ if rust_abi && callee_arg. layout . is_zst ( ) {
215220 // Nothing to do.
216221 trace ! ( "Skipping callee ZST" ) ;
217222 return Ok ( ( ) ) ;
218223 }
219224 let caller_arg = caller_arg. next ( )
220225 . ok_or_else ( || EvalErrorKind :: FunctionArgCountMismatch ) ?;
221- if skip_zst {
226+ if rust_abi {
222227 debug_assert ! ( !caller_arg. layout. is_zst( ) , "ZSTs must have been already filtered out" ) ;
223228 }
224229 // Now, check
225- if !Self :: check_argument_compat ( caller_arg. layout , callee_arg. layout ) {
230+ if !Self :: check_argument_compat ( rust_abi , caller_arg. layout , callee_arg. layout ) {
226231 return err ! ( FunctionArgMismatch ( caller_arg. layout. ty, callee_arg. layout. ty) ) ;
227232 }
228233 // We allow some transmutes here
@@ -322,7 +327,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
322327 // Figure out how to pass which arguments.
323328 // We have two iterators: Where the arguments come from,
324329 // and where they go to.
325- let skip_zst = match caller_abi {
330+ let rust_abi = match caller_abi {
326331 Abi :: Rust | Abi :: RustCall => true ,
327332 _ => false
328333 } ;
@@ -347,7 +352,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
347352 } ;
348353 // Skip ZSTs
349354 let mut caller_iter = caller_args. iter ( )
350- . filter ( |op| !skip_zst || !op. layout . is_zst ( ) )
355+ . filter ( |op| !rust_abi || !op. layout . is_zst ( ) )
351356 . map ( |op| * op) ;
352357
353358 // Now we have to spread them out across the callee's locals,
@@ -362,11 +367,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
362367 // Must be a tuple
363368 for i in 0 ..dest. layout . fields . count ( ) {
364369 let dest = self . place_field ( dest, i as u64 ) ?;
365- self . pass_argument ( skip_zst , & mut caller_iter, dest) ?;
370+ self . pass_argument ( rust_abi , & mut caller_iter, dest) ?;
366371 }
367372 } else {
368373 // Normal argument
369- self . pass_argument ( skip_zst , & mut caller_iter, dest) ?;
374+ self . pass_argument ( rust_abi , & mut caller_iter, dest) ?;
370375 }
371376 }
372377 // Now we should have no more caller args
@@ -377,7 +382,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
377382 // Don't forget to check the return type!
378383 if let Some ( caller_ret) = dest {
379384 let callee_ret = self . eval_place ( & mir:: Place :: Local ( mir:: RETURN_PLACE ) ) ?;
380- if !Self :: check_argument_compat ( caller_ret. layout , callee_ret. layout ) {
385+ if !Self :: check_argument_compat (
386+ rust_abi,
387+ caller_ret. layout ,
388+ callee_ret. layout ,
389+ ) {
381390 return err ! ( FunctionRetMismatch (
382391 caller_ret. layout. ty, callee_ret. layout. ty
383392 ) ) ;
0 commit comments