Rollup merge of #124715 - RalfJung:interpret-noreturn, r=compiler-errors
interpret, miri: uniform treatments of intrinsics/functions with and without return block A long time ago we didn't have a `dest: &MPlaceTy<'tcx, Self::Provenance>` for diverging functions, and since `dest` is used so often we special-cased these non-returning intrinsics and functions so that we'd have `dest` available everywhere else. But this has changed a while ago, now only the return block `ret` is optional, and there's a convenient `return_to_block` function for dealing with the `None` case. So there no longer is any reason to treat diverging intrinsics/functions any different from those that do return.
This commit is contained in:
commit
743be1e35e
24 changed files with 192 additions and 240 deletions
|
@ -467,19 +467,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
|||
let intrinsic_name = ecx.tcx.item_name(instance.def_id());
|
||||
|
||||
// CTFE-specific intrinsics.
|
||||
let Some(ret) = target else {
|
||||
// Handle diverging intrinsics. We can't handle any of them (that are not already
|
||||
// handled above), but check if there is a fallback body.
|
||||
if ecx.tcx.intrinsic(instance.def_id()).unwrap().must_be_overridden {
|
||||
throw_unsup_format!(
|
||||
"intrinsic `{intrinsic_name}` is not supported at compile-time"
|
||||
);
|
||||
}
|
||||
return Ok(Some(ty::Instance {
|
||||
def: ty::InstanceDef::Item(instance.def_id()),
|
||||
args: instance.args,
|
||||
}));
|
||||
};
|
||||
match intrinsic_name {
|
||||
sym::ptr_guaranteed_cmp => {
|
||||
let a = ecx.read_scalar(&args[0])?;
|
||||
|
@ -559,7 +546,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
|||
}
|
||||
}
|
||||
|
||||
ecx.go_to_block(ret);
|
||||
// Intrinsic is done, jump to next block.
|
||||
ecx.return_to_block(target)?;
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
|
|
|
@ -113,10 +113,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
) -> InterpResult<'tcx, bool> {
|
||||
let instance_args = instance.args;
|
||||
let intrinsic_name = self.tcx.item_name(instance.def_id());
|
||||
let Some(ret) = ret else {
|
||||
// We don't support any intrinsic without return place.
|
||||
return Ok(false);
|
||||
};
|
||||
|
||||
match intrinsic_name {
|
||||
sym::caller_location => {
|
||||
|
@ -376,7 +372,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
};
|
||||
|
||||
M::panic_nounwind(self, &msg)?;
|
||||
// Skip the `go_to_block` at the end.
|
||||
// Skip the `return_to_block` at the end (we panicked, we do not return).
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
|
@ -437,11 +433,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
self.write_scalar(Scalar::from_target_usize(align.bytes(), self), dest)?;
|
||||
}
|
||||
|
||||
// Unsupported intrinsic: skip the return_to_block below.
|
||||
_ => return Ok(false),
|
||||
}
|
||||
|
||||
trace!("{:?}", self.dump_place(&dest.clone().into()));
|
||||
self.go_to_block(ret);
|
||||
self.return_to_block(ret)?;
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue