Clean up special function const checks
Mark them as const and `#[rustc_do_not_const_check]` instead of hard-coding them in const-eval checks.
This commit is contained in:
@@ -30,34 +30,25 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
|
||||
&mut self,
|
||||
instance: ty::Instance<'tcx>,
|
||||
args: &[OpTy<'tcx>],
|
||||
is_const_fn: bool,
|
||||
) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
|
||||
// The list of functions we handle here must be in sync with
|
||||
// `is_lang_special_const_fn` in `transform/check_consts/mod.rs`.
|
||||
// All `#[rustc_do_not_const_check]` functions should be hooked here.
|
||||
let def_id = instance.def_id();
|
||||
|
||||
if is_const_fn {
|
||||
if Some(def_id) == self.tcx.lang_items().const_eval_select() {
|
||||
// redirect to const_eval_select_ct
|
||||
if let Some(const_eval_select) = self.tcx.lang_items().const_eval_select_ct() {
|
||||
return Ok(Some(
|
||||
ty::Instance::resolve(
|
||||
*self.tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
const_eval_select,
|
||||
instance.substs,
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
));
|
||||
}
|
||||
if Some(def_id) == self.tcx.lang_items().const_eval_select() {
|
||||
// redirect to const_eval_select_ct
|
||||
if let Some(const_eval_select) = self.tcx.lang_items().const_eval_select_ct() {
|
||||
return Ok(Some(
|
||||
ty::Instance::resolve(
|
||||
*self.tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
const_eval_select,
|
||||
instance.substs,
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
));
|
||||
}
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
if Some(def_id) == self.tcx.lang_items().panic_fn()
|
||||
|| Some(def_id) == self.tcx.lang_items().panic_str()
|
||||
|| Some(def_id) == self.tcx.lang_items().panic_display()
|
||||
} else if Some(def_id) == self.tcx.lang_items().panic_display()
|
||||
|| Some(def_id) == self.tcx.lang_items().begin_panic_fn()
|
||||
{
|
||||
// &str or &&str
|
||||
@@ -286,19 +277,16 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||
}
|
||||
}
|
||||
|
||||
// Some functions we support even if they are non-const -- but avoid testing
|
||||
// that for const fn!
|
||||
// `const_eval_select` is a const fn because it must use const trait bounds.
|
||||
if let Some(new_instance) = ecx.hook_special_const_fn(instance, args, is_const_fn)? {
|
||||
// We call another const fn instead.
|
||||
return Self::find_mir_or_eval_fn(ecx, new_instance, _abi, args, _ret, _unwind);
|
||||
}
|
||||
|
||||
if !is_const_fn {
|
||||
// We certainly do *not* want to actually call the fn
|
||||
// though, so be sure we return here.
|
||||
throw_unsup_format!("calling non-const function `{}`", instance)
|
||||
}
|
||||
|
||||
if let Some(new_instance) = ecx.hook_special_const_fn(instance, args)? {
|
||||
// We call another const fn instead.
|
||||
return Self::find_mir_or_eval_fn(ecx, new_instance, _abi, args, _ret, _unwind);
|
||||
}
|
||||
}
|
||||
// This is a const fn. Call it.
|
||||
Ok(Some(ecx.load_mir(instance.def, None)?))
|
||||
|
||||
Reference in New Issue
Block a user