PR feedback

- Add `:Sized` assertion in interpreter impl
- Use `Scalar::from_bool` instead of `ScalarInt: From<bool>`
- Remove unneeded comparison in intrinsic typeck
- Make this UB to call with undef, not just return undef in that case
This commit is contained in:
Scott McMurray 2021-05-30 11:31:56 -07:00
parent 2456495a26
commit b63b2f1e42
3 changed files with 9 additions and 5 deletions

View file

@ -570,11 +570,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
rhs: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>, rhs: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,
) -> InterpResult<'tcx, Scalar<M::PointerTag>> { ) -> InterpResult<'tcx, Scalar<M::PointerTag>> {
let layout = self.layout_of(lhs.layout.ty.builtin_deref(true).unwrap().ty)?; let layout = self.layout_of(lhs.layout.ty.builtin_deref(true).unwrap().ty)?;
assert!(!layout.is_unsized());
let lhs = self.read_scalar(lhs)?.check_init()?; let lhs = self.read_scalar(lhs)?.check_init()?;
let rhs = self.read_scalar(rhs)?.check_init()?; let rhs = self.read_scalar(rhs)?.check_init()?;
let lhs_bytes = self.memory.read_bytes(lhs, layout.size)?; let lhs_bytes = self.memory.read_bytes(lhs, layout.size)?;
let rhs_bytes = self.memory.read_bytes(rhs, layout.size)?; let rhs_bytes = self.memory.read_bytes(rhs, layout.size)?;
Ok(Scalar::Int((lhs_bytes == rhs_bytes).into())) Ok(Scalar::from_bool(lhs_bytes == rhs_bytes))
} }
} }

View file

@ -381,11 +381,10 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
sym::nontemporal_store => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()), sym::nontemporal_store => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()),
sym::raw_eq => { sym::raw_eq => {
let param_count = if intrinsic_name == sym::raw_eq { 2 } else { 1 };
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0) }; let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0) };
let param_ty = let param_ty =
tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)), param(0)); tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)), param(0));
(1, vec![param_ty; param_count], tcx.types.bool) (1, vec![param_ty; 2], tcx.types.bool)
} }
other => { other => {

View file

@ -1924,8 +1924,12 @@ extern "rust-intrinsic" {
/// ///
/// # Safety /// # Safety
/// ///
/// This doesn't take into account padding, so if `T` has padding /// It's UB to call this if any of the *bytes* in `*a` or `*b` are uninitialized.
/// the result will be `undef`, which cannot be exposed to safe code. /// Note that this is a stricter criterion than just the *values* being
/// fully-initialized: if `T` has padding, it's UB to call this intrinsic.
///
/// (The implementation is allowed to branch on the results of comparisons,
/// which is UB if any of their inputs are `undef`.)
#[cfg(not(bootstrap))] #[cfg(not(bootstrap))]
#[rustc_const_unstable(feature = "const_intrinsic_raw_eq", issue = "none")] #[rustc_const_unstable(feature = "const_intrinsic_raw_eq", issue = "none")]
pub fn raw_eq<T>(a: &T, b: &T) -> bool; pub fn raw_eq<T>(a: &T, b: &T) -> bool;