@@ -182,19 +182,24 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
182
182
}
183
183
184
184
fn check_argument_compat (
185
+ rust_abi : bool ,
185
186
caller : TyLayout < ' tcx > ,
186
187
callee : TyLayout < ' tcx > ,
187
188
) -> bool {
188
189
if caller. ty == callee. ty {
189
190
// No question
190
191
return true ;
191
192
}
193
+ if !rust_abi {
194
+ // Don't risk anything
195
+ return false ;
196
+ }
192
197
// Compare layout
193
198
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).
194
202
( 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).
198
203
caller. value == callee. value ,
199
204
( layout:: Abi :: ScalarPair ( ref caller1, ref caller2) ,
200
205
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>
207
212
/// Pass a single argument, checking the types for compatibility.
208
213
fn pass_argument (
209
214
& mut self ,
210
- skip_zst : bool ,
215
+ rust_abi : bool ,
211
216
caller_arg : & mut impl Iterator < Item =OpTy < ' tcx , M :: PointerTag > > ,
212
217
callee_arg : PlaceTy < ' tcx , M :: PointerTag > ,
213
218
) -> EvalResult < ' tcx > {
214
- if skip_zst && callee_arg. layout . is_zst ( ) {
219
+ if rust_abi && callee_arg. layout . is_zst ( ) {
215
220
// Nothing to do.
216
221
trace ! ( "Skipping callee ZST" ) ;
217
222
return Ok ( ( ) ) ;
218
223
}
219
224
let caller_arg = caller_arg. next ( )
220
225
. ok_or_else ( || EvalErrorKind :: FunctionArgCountMismatch ) ?;
221
- if skip_zst {
226
+ if rust_abi {
222
227
debug_assert ! ( !caller_arg. layout. is_zst( ) , "ZSTs must have been already filtered out" ) ;
223
228
}
224
229
// 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 ) {
226
231
return err ! ( FunctionArgMismatch ( caller_arg. layout. ty, callee_arg. layout. ty) ) ;
227
232
}
228
233
// We allow some transmutes here
@@ -322,7 +327,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
322
327
// Figure out how to pass which arguments.
323
328
// We have two iterators: Where the arguments come from,
324
329
// and where they go to.
325
- let skip_zst = match caller_abi {
330
+ let rust_abi = match caller_abi {
326
331
Abi :: Rust | Abi :: RustCall => true ,
327
332
_ => false
328
333
} ;
@@ -347,7 +352,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
347
352
} ;
348
353
// Skip ZSTs
349
354
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 ( ) )
351
356
. map ( |op| * op) ;
352
357
353
358
// 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>
362
367
// Must be a tuple
363
368
for i in 0 ..dest. layout . fields . count ( ) {
364
369
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) ?;
366
371
}
367
372
} else {
368
373
// Normal argument
369
- self . pass_argument ( skip_zst , & mut caller_iter, dest) ?;
374
+ self . pass_argument ( rust_abi , & mut caller_iter, dest) ?;
370
375
}
371
376
}
372
377
// 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>
377
382
// Don't forget to check the return type!
378
383
if let Some ( caller_ret) = dest {
379
384
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
+ ) {
381
390
return err ! ( FunctionRetMismatch (
382
391
caller_ret. layout. ty, callee_ret. layout. ty
383
392
) ) ;
0 commit comments