diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index b1e3fd735399d..b865cafa38647 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -190,8 +190,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } UnaryOp(un_op, ref operand) => { - // The operand always has the same type as the result. - let val = self.read_immediate(&self.eval_operand(operand, Some(dest.layout))?)?; + let layout = util::unop_homogeneous(un_op).then_some(dest.layout); + let val = self.read_immediate(&self.eval_operand(operand, layout)?)?; let result = self.unary_op(un_op, &val)?; assert_eq!(result.layout, dest.layout, "layout mismatch for result of {un_op:?}"); self.write_immediate(*result, &dest)?; diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs index 39992123882a9..c63d7748087c9 100644 --- a/compiler/rustc_const_eval/src/util/mod.rs +++ b/compiler/rustc_const_eval/src/util/mod.rs @@ -38,3 +38,13 @@ pub fn binop_right_homogeneous(op: mir::BinOp) -> bool { Offset | Shl | ShlUnchecked | Shr | ShrUnchecked => false, } } + +/// Classify whether an operator is "homogeneous", i.e., the operand has the +/// same type as the result. +#[inline] +pub fn unop_homogeneous(op: mir::UnOp) -> bool { + match op { + mir::UnOp::Not | mir::UnOp::Neg => true, + mir::UnOp::PtrMetadata => false, + } +}