@@ -427,52 +427,41 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
427427
428428 fn find_mir_or_eval_fn (
429429 ecx : & mut InterpCx < ' mir , ' tcx , Self > ,
430- instance : ty:: Instance < ' tcx > ,
430+ orig_instance : ty:: Instance < ' tcx > ,
431431 _abi : CallAbi ,
432432 args : & [ FnArg < ' tcx > ] ,
433433 dest : & PlaceTy < ' tcx > ,
434434 ret : Option < mir:: BasicBlock > ,
435435 _unwind : mir:: UnwindAction , // unwinding is not supported in consts
436436 ) -> 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+ } ;
438444
439445 // Only check non-glue functions
440446 if let ty:: InstanceDef :: Item ( def) = instance. def {
441447 // 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)
471458 }
472459 }
473460
474461 // 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) ) )
476465 }
477466
478467 fn call_intrinsic (
0 commit comments