@@ -427,52 +427,41 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
427
427
428
428
fn find_mir_or_eval_fn (
429
429
ecx : & mut InterpCx < ' mir , ' tcx , Self > ,
430
- instance : ty:: Instance < ' tcx > ,
430
+ orig_instance : ty:: Instance < ' tcx > ,
431
431
_abi : CallAbi ,
432
432
args : & [ FnArg < ' tcx > ] ,
433
433
dest : & PlaceTy < ' tcx > ,
434
434
ret : Option < mir:: BasicBlock > ,
435
435
_unwind : mir:: UnwindAction , // unwinding is not supported in consts
436
436
) -> InterpResult < ' tcx , Option < ( & ' mir mir:: Body < ' tcx > , ty:: Instance < ' tcx > ) > > {
437
- debug ! ( "find_mir_or_eval_fn: {:?}" , instance) ;
437
+ debug ! ( "find_mir_or_eval_fn: {:?}" , orig_instance) ;
438
+
439
+ // Replace some functions.
440
+ let Some ( instance) = ecx. hook_special_const_fn ( orig_instance, args, dest, ret) ? else {
441
+ // Call has already been handled.
442
+ return Ok ( None ) ;
443
+ } ;
438
444
439
445
// Only check non-glue functions
440
446
if let ty:: InstanceDef :: Item ( def) = instance. def {
441
447
// Execution might have wandered off into other crates, so we cannot do a stability-
442
- // sensitive check here. But we can at least rule out functions that are not const
443
- // at all.
444
- if !ecx. tcx . is_const_fn_raw ( def) {
445
- // allow calling functions inside a trait marked with #[const_trait].
446
- if !ecx. tcx . is_const_default_method ( def) {
447
- // We certainly do *not* want to actually call the fn
448
- // though, so be sure we return here.
449
- throw_unsup_format ! ( "calling non-const function `{}`" , instance)
450
- }
451
- }
452
-
453
- let Some ( new_instance) = ecx. hook_special_const_fn ( instance, args, dest, ret) ? else {
454
- return Ok ( None ) ;
455
- } ;
456
-
457
- if new_instance != instance {
458
- // We call another const fn instead.
459
- // However, we return the *original* instance to make backtraces work out
460
- // (and we hope this does not confuse the FnAbi checks too much).
461
- return Ok ( Self :: find_mir_or_eval_fn (
462
- ecx,
463
- new_instance,
464
- _abi,
465
- args,
466
- dest,
467
- ret,
468
- _unwind,
469
- ) ?
470
- . map ( |( body, _instance) | ( body, instance) ) ) ;
448
+ // sensitive check here. But we can at least rule out functions that are not const at
449
+ // all. That said, we have to allow calling functions inside a trait marked with
450
+ // #[const_trait]. These *are* const-checked!
451
+ // FIXME: why does `is_const_fn_raw` not classify them as const?
452
+ if ( !ecx. tcx . is_const_fn_raw ( def) && !ecx. tcx . is_const_default_method ( def) )
453
+ || ecx. tcx . has_attr ( def, sym:: rustc_do_not_const_check)
454
+ {
455
+ // We certainly do *not* want to actually call the fn
456
+ // though, so be sure we return here.
457
+ throw_unsup_format ! ( "calling non-const function `{}`" , instance)
471
458
}
472
459
}
473
460
474
461
// This is a const fn. Call it.
475
- Ok ( Some ( ( ecx. load_mir ( instance. def , None ) ?, instance) ) )
462
+ // In case of replacement, we return the *original* instance to make backtraces work out
463
+ // (and we hope this does not confuse the FnAbi checks too much).
464
+ Ok ( Some ( ( ecx. load_mir ( instance. def , None ) ?, orig_instance) ) )
476
465
}
477
466
478
467
fn call_intrinsic (
0 commit comments