diff --git a/compiler/rustc_mir/src/interpret/intrinsics.rs b/compiler/rustc_mir/src/interpret/intrinsics.rs index 5dd679b8912..ad9cf3e7d2f 100644 --- a/compiler/rustc_mir/src/interpret/intrinsics.rs +++ b/compiler/rustc_mir/src/interpret/intrinsics.rs @@ -570,11 +570,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { rhs: &OpTy<'tcx, >::PointerTag>, ) -> InterpResult<'tcx, Scalar> { 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 rhs = self.read_scalar(rhs)?.check_init()?; let lhs_bytes = self.memory.read_bytes(lhs, 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)) } } diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs index 18ccaf79d32..6661df21ed9 100644 --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs @@ -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::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 param_ty = 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 => { diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 7d2c278aa05..238f00e41b3 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1924,8 +1924,12 @@ extern "rust-intrinsic" { /// /// # Safety /// - /// This doesn't take into account padding, so if `T` has padding - /// the result will be `undef`, which cannot be exposed to safe code. + /// It's UB to call this if any of the *bytes* in `*a` or `*b` are uninitialized. + /// 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))] #[rustc_const_unstable(feature = "const_intrinsic_raw_eq", issue = "none")] pub fn raw_eq(a: &T, b: &T) -> bool;