diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 2097f9d28870..bfe5514b6d3e 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -585,10 +585,7 @@ fn codegen_stmt<'tcx>( .discriminant_for_variant(fx.tcx, *index) .unwrap(); let discr = if discr.ty.is_signed() { - rustc_middle::mir::interpret::sign_extend( - discr.val, - fx.layout_of(discr.ty).size, - ) + fx.layout_of(discr.ty).size.sign_extend(discr.val) } else { discr.val }; diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index ef1ae807453f..454d43fd4e7d 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -29,7 +29,6 @@ use rustc_hir::def::CtorKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::ich::NodeIdHashingMode; -use rustc_middle::mir::interpret::truncate; use rustc_middle::mir::{self, Field, GeneratorLayout}; use rustc_middle::ty::layout::{self, IntegerExt, PrimitiveExt, TyAndLayout}; use rustc_middle::ty::subst::GenericArgKind; @@ -1693,7 +1692,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { let value = (i.as_u32() as u128) .wrapping_sub(niche_variants.start().as_u32() as u128) .wrapping_add(niche_start); - let value = truncate(value, tag.value.size(cx)); + let value = tag.value.size(cx).truncate(value); // NOTE(eddyb) do *NOT* remove this assert, until // we pass the full 128-bit value to LLVM, otherwise // truncation will be silent and remain undetected. diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 428cd453dd5a..467a3a425906 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -6,7 +6,6 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::{is_range_literal, ExprKind, Node}; use rustc_index::vec::Idx; -use rustc_middle::mir::interpret::{sign_extend, truncate}; use rustc_middle::ty::layout::{IntegerExt, SizeSkeleton}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, AdtKind, Ty, TyCtxt, TypeFoldable}; @@ -218,11 +217,11 @@ fn report_bin_hex_error( cx.struct_span_lint(OVERFLOWING_LITERALS, expr.span, |lint| { let (t, actually) = match ty { attr::IntType::SignedInt(t) => { - let actually = sign_extend(val, size) as i128; + let actually = size.sign_extend(val) as i128; (t.name_str(), actually.to_string()) } attr::IntType::UnsignedInt(t) => { - let actually = truncate(val, size); + let actually = size.truncate(val); (t.name_str(), actually.to_string()) } }; diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index b5beb3babe23..bcf85797313f 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -110,7 +110,7 @@ use rustc_hir::def_id::DefId; use rustc_macros::HashStable; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_serialize::{Decodable, Encodable}; -use rustc_target::abi::{Endian, Size}; +use rustc_target::abi::Endian; use crate::mir; use crate::ty::codec::{TyDecoder, TyEncoder}; @@ -590,39 +590,6 @@ pub fn read_target_uint(endianness: Endian, mut source: &[u8]) -> Result u128 { - let size = size.bits(); - if size == 0 { - // Truncated until nothing is left. - return 0; - } - // Sign-extend it. - let shift = 128 - size; - // Shift the unsigned value to the left, then shift back to the right as signed - // (essentially fills with FF on the left). - (((value << shift) as i128) >> shift) as u128 -} - -/// Truncates `value` to `size` bits. -#[inline] -pub fn truncate(value: u128, size: Size) -> u128 { - let size = size.bits(); - if size == 0 { - // Truncated until nothing is left. - return 0; - } - let shift = 128 - size; - // Truncate (shift left to drop out leftover values, shift right to fill with zeroes). - (value << shift) >> shift -} - /// Computes the unsigned absolute value without wrapping or panicking. #[inline] pub fn uabs(value: i64) -> u64 { diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index a191dd1d705f..5e97862ecf2b 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -10,7 +10,7 @@ use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout}; use crate::ty::{ParamEnv, ScalarInt, Ty, TyCtxt}; -use super::{sign_extend, AllocId, Allocation, InterpResult, Pointer, PointerArithmetic}; +use super::{AllocId, Allocation, InterpResult, Pointer, PointerArithmetic}; /// Represents the result of const evaluation via the `eval_to_allocation` query. #[derive(Clone, HashStable, TyEncodable, TyDecodable)] @@ -448,7 +448,7 @@ impl<'tcx, Tag> Scalar { fn to_signed_with_bit_width(self, bits: u64) -> InterpResult<'static, i128> { let sz = Size::from_bits(bits); let b = self.to_bits(sz)?; - Ok(sign_extend(b, sz) as i128) + Ok(sz.sign_extend(b) as i128) } /// Converts the scalar to produce an `i8`. Fails if the scalar is a pointer. @@ -479,7 +479,7 @@ impl<'tcx, Tag> Scalar { pub fn to_machine_isize(self, cx: &impl HasDataLayout) -> InterpResult<'static, i64> { let sz = cx.data_layout().pointer_size; let b = self.to_bits(sz)?; - let b = sign_extend(b, sz) as i128; + let b = sz.sign_extend(b) as i128; Ok(i64::try_from(b).unwrap()) } diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 8308cfddb438..4ff88d1adaf8 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -1,4 +1,4 @@ -use crate::mir::interpret::{sign_extend, truncate, InterpResult}; +use crate::mir::interpret::InterpResult; use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::Float; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; @@ -75,7 +75,7 @@ impl std::fmt::Debug for ConstInt { Ok(()) } } else { - let max = truncate(u128::MAX, Size::from_bytes(size)); + let max = Size::from_bytes(size).truncate(u128::MAX); if raw == max { match (size, is_ptr_sized_integral) { (_, true) => write!(fmt, "usize::MAX"), @@ -174,7 +174,7 @@ impl ScalarInt { // is a packed struct, that would create a possibly unaligned reference, which // is UB. debug_assert_eq!( - truncate(self.data, self.size()), + self.size().truncate(self.data), { self.data }, "Scalar value {:#x} exceeds size of {} bytes", { self.data }, @@ -204,7 +204,7 @@ impl ScalarInt { #[inline] pub fn try_from_uint(i: impl Into, size: Size) -> Option { let data = i.into(); - if truncate(data, size) == data { + if size.truncate(data) == data { Some(Self { data, size: size.bytes() as u8 }) } else { None @@ -215,8 +215,8 @@ impl ScalarInt { pub fn try_from_int(i: impl Into, size: Size) -> Option { let i = i.into(); // `into` performed sign extension, we have to truncate - let truncated = truncate(i as u128, size); - if sign_extend(truncated, size) as i128 == i { + let truncated = size.truncate(i as u128); + if size.sign_extend(truncated) as i128 == i { Some(Self { data: truncated, size: size.bytes() as u8 }) } else { None diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 4a20e1c32f99..5f117e19eca2 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -2,7 +2,6 @@ use crate::ich::NodeIdHashingMode; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use crate::mir::interpret::{sign_extend, truncate}; use crate::ty::fold::TypeFolder; use crate::ty::layout::IntegerExt; use crate::ty::query::TyCtxtAt; @@ -38,7 +37,7 @@ impl<'tcx> fmt::Display for Discr<'tcx> { let size = ty::tls::with(|tcx| Integer::from_attr(&tcx, SignedInt(ity)).size()); let x = self.val; // sign extend the raw representation to be an i128 - let x = sign_extend(x, size) as i128; + let x = size.sign_extend(x) as i128; write!(fmt, "{}", x) } _ => write!(fmt, "{}", self.val), @@ -47,7 +46,7 @@ impl<'tcx> fmt::Display for Discr<'tcx> { } fn signed_min(size: Size) -> i128 { - sign_extend(1_u128 << (size.bits() - 1), size) as i128 + size.sign_extend(1_u128 << (size.bits() - 1)) as i128 } fn signed_max(size: Size) -> i128 { @@ -77,14 +76,14 @@ impl<'tcx> Discr<'tcx> { let (val, oflo) = if signed { let min = signed_min(size); let max = signed_max(size); - let val = sign_extend(self.val, size) as i128; + let val = size.sign_extend(self.val) as i128; assert!(n < (i128::MAX as u128)); let n = n as i128; let oflo = val > max - n; let val = if oflo { min + (n - (max - val) - 1) } else { val + n }; // zero the upper bits let val = val as u128; - let val = truncate(val, size); + let val = size.truncate(val); (val, oflo) } else { let max = unsigned_max(size); @@ -650,7 +649,7 @@ impl<'tcx> ty::TyS<'tcx> { let val = match self.kind() { ty::Int(_) | ty::Uint(_) => { let (size, signed) = int_size_and_signed(tcx, self); - let val = if signed { truncate(signed_min(size) as u128, size) } else { 0 }; + let val = if signed { size.truncate(signed_min(size) as u128) } else { 0 }; Some(val) } ty::Char => Some(0), diff --git a/compiler/rustc_mir/src/interpret/cast.rs b/compiler/rustc_mir/src/interpret/cast.rs index affeae546b2a..6d224bcc50b0 100644 --- a/compiler/rustc_mir/src/interpret/cast.rs +++ b/compiler/rustc_mir/src/interpret/cast.rs @@ -13,8 +13,7 @@ use rustc_span::symbol::sym; use rustc_target::abi::{Integer, LayoutOf, Variants}; use super::{ - truncate, util::ensure_monomorphic_enough, FnVal, ImmTy, Immediate, InterpCx, Machine, OpTy, - PlaceTy, + util::ensure_monomorphic_enough, FnVal, ImmTy, Immediate, InterpCx, Machine, OpTy, PlaceTy, }; impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { @@ -209,7 +208,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { RawPtr(_) => self.pointer_size(), _ => bug!(), }; - let v = truncate(v, size); + let v = size.truncate(v); Scalar::from_uint(v, size) } diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index ec1195d3703b..08d8904ae1a5 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -9,9 +9,7 @@ use rustc_index::vec::IndexVec; use rustc_macros::HashStable; use rustc_middle::ich::StableHashingContext; use rustc_middle::mir; -use rustc_middle::mir::interpret::{ - sign_extend, truncate, GlobalId, InterpResult, Pointer, Scalar, -}; +use rustc_middle::mir::interpret::{GlobalId, InterpResult, Pointer, Scalar}; use rustc_middle::ty::layout::{self, TyAndLayout}; use rustc_middle::ty::{ self, query::TyCtxtAt, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, @@ -443,12 +441,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[inline(always)] pub fn sign_extend(&self, value: u128, ty: TyAndLayout<'_>) -> u128 { assert!(ty.abi.is_signed()); - sign_extend(value, ty.size) + ty.size.sign_extend(value) } #[inline(always)] pub fn truncate(&self, value: u128, ty: TyAndLayout<'_>) -> u128 { - truncate(value, ty.size) + ty.size.truncate(value) } #[inline] diff --git a/compiler/rustc_mir/src/interpret/place.rs b/compiler/rustc_mir/src/interpret/place.rs index 3e10d0960a88..a003380dda7e 100644 --- a/compiler/rustc_mir/src/interpret/place.rs +++ b/compiler/rustc_mir/src/interpret/place.rs @@ -14,9 +14,9 @@ use rustc_target::abi::{Abi, Align, FieldsShape, TagEncoding}; use rustc_target::abi::{HasDataLayout, LayoutOf, Size, VariantIdx, Variants}; use super::{ - mir_assign_valid_types, truncate, AllocId, AllocMap, Allocation, AllocationExtra, ConstAlloc, - ImmTy, Immediate, InterpCx, InterpResult, LocalValue, Machine, MemoryKind, OpTy, Operand, - Pointer, PointerArithmetic, Scalar, ScalarMaybeUninit, + mir_assign_valid_types, AllocId, AllocMap, Allocation, AllocationExtra, ConstAlloc, ImmTy, + Immediate, InterpCx, InterpResult, LocalValue, Machine, MemoryKind, OpTy, Operand, Pointer, + PointerArithmetic, Scalar, ScalarMaybeUninit, }; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)] @@ -1073,7 +1073,7 @@ where // their computation, but the in-memory tag is the smallest possible // representation let size = tag_layout.value.size(self); - let tag_val = truncate(discr_val, size); + let tag_val = size.truncate(discr_val); let tag_dest = self.place_field(dest, tag_field)?; self.write_scalar(Scalar::from_uint(tag_val, size), tag_dest)?; diff --git a/compiler/rustc_mir/src/transform/const_prop.rs b/compiler/rustc_mir/src/transform/const_prop.rs index 620b9ac673a6..aeb9920c0e32 100644 --- a/compiler/rustc_mir/src/transform/const_prop.rs +++ b/compiler/rustc_mir/src/transform/const_prop.rs @@ -29,10 +29,9 @@ use rustc_trait_selection::traits; use crate::const_eval::ConstEvalErr; use crate::interpret::{ - self, compile_time_machine, truncate, AllocId, Allocation, ConstValue, CtfeValidationMode, - Frame, ImmTy, Immediate, InterpCx, InterpResult, LocalState, LocalValue, MemPlace, Memory, - MemoryKind, OpTy, Operand as InterpOperand, PlaceTy, Pointer, Scalar, ScalarMaybeUninit, - StackPopCleanup, + self, compile_time_machine, AllocId, Allocation, ConstValue, CtfeValidationMode, Frame, ImmTy, + Immediate, InterpCx, InterpResult, LocalState, LocalValue, MemPlace, Memory, MemoryKind, OpTy, + Operand as InterpOperand, PlaceTy, Pointer, Scalar, ScalarMaybeUninit, StackPopCleanup, }; use crate::transform::MirPass; @@ -746,7 +745,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } } BinOp::BitOr => { - if arg_value == truncate(u128::MAX, const_arg.layout.size) + if arg_value == const_arg.layout.size.truncate(u128::MAX) || (const_arg.layout.ty.is_bool() && arg_value == 1) { this.ecx.write_immediate(*const_arg, dest)?; diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs index e46274770be1..375f19f87559 100644 --- a/compiler/rustc_mir_build/src/build/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs @@ -17,7 +17,6 @@ use crate::build::Builder; use crate::thir::{self, *}; use rustc_attr::{SignedInt, UnsignedInt}; use rustc_hir::RangeEnd; -use rustc_middle::mir::interpret::truncate; use rustc_middle::mir::Place; use rustc_middle::ty; use rustc_middle::ty::layout::IntegerExt; @@ -161,13 +160,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ty::Int(ity) => { let size = Integer::from_attr(&tcx, SignedInt(ity)).size(); - let max = truncate(u128::MAX, size); + let max = size.truncate(u128::MAX); let bias = 1u128 << (size.bits() - 1); (Some((0, max, size)), bias) } ty::Uint(uty) => { let size = Integer::from_attr(&tcx, UnsignedInt(uty)).size(); - let max = truncate(u128::MAX, size); + let max = size.truncate(u128::MAX); (Some((0, max, size)), 0) } _ => (None, 0), diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index b71ff6e75574..dfe82317f48c 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -1,6 +1,6 @@ use rustc_ast as ast; use rustc_middle::mir::interpret::{ - truncate, Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar, + Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar, }; use rustc_middle::ty::{self, ParamEnv, TyCtxt}; use rustc_span::symbol::Symbol; @@ -16,7 +16,7 @@ crate fn lit_to_const<'tcx>( let param_ty = ParamEnv::reveal_all().and(ty); let width = tcx.layout_of(param_ty).map_err(|_| LitToConstError::Reported)?.size; trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits()); - let result = truncate(n, width); + let result = width.truncate(n); trace!("trunc result: {}", result); Ok(ConstValue::Scalar(Scalar::from_uint(result, width))) }; diff --git a/compiler/rustc_mir_build/src/thir/pattern/_match.rs b/compiler/rustc_mir_build/src/thir/pattern/_match.rs index e0de1351ac33..9e096f9ad684 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/_match.rs @@ -304,7 +304,7 @@ use rustc_arena::TypedArena; use rustc_attr::{SignedInt, UnsignedInt}; use rustc_hir::def_id::DefId; use rustc_hir::{HirId, RangeEnd}; -use rustc_middle::mir::interpret::{truncate, ConstValue}; +use rustc_middle::mir::interpret::ConstValue; use rustc_middle::mir::Field; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{self, Const, Ty, TyCtxt}; @@ -1608,7 +1608,7 @@ fn all_constructors<'p, 'tcx>(pcx: PatCtxt<'_, 'p, 'tcx>) -> Vec { let size = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size(); - let max = truncate(u128::MAX, size); + let max = size.truncate(u128::MAX); vec![make_range(0, max)] } _ if cx.is_uninhabited(pcx.ty) => vec![], diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 3c746ac51539..db0ecd701bca 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -15,7 +15,7 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::RangeEnd; use rustc_index::vec::Idx; -use rustc_middle::mir::interpret::{get_slice_bytes, sign_extend, ConstValue}; +use rustc_middle::mir::interpret::{get_slice_bytes, ConstValue}; use rustc_middle::mir::interpret::{ErrorHandled, LitToConstError, LitToConstInput}; use rustc_middle::mir::UserTypeProjection; use rustc_middle::mir::{BorrowKind, Field, Mutability}; @@ -1082,8 +1082,8 @@ crate fn compare_const_vals<'tcx>( use rustc_attr::SignedInt; use rustc_middle::ty::layout::IntegerExt; let size = rustc_target::abi::Integer::from_attr(&tcx, SignedInt(ity)).size(); - let a = sign_extend(a, size); - let b = sign_extend(b, size); + let a = size.sign_extend(a); + let b = size.sign_extend(b); Some((a as i128).cmp(&(b as i128))) } _ => Some(a.cmp(&b)), diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 1ff043ae91ff..c28c2fecfbb4 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -4,7 +4,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; -use rustc_middle::mir::interpret::sign_extend; use rustc_middle::ty::print::{Print, Printer}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable}; @@ -527,7 +526,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { let param_env = ty::ParamEnv::reveal_all(); ct.try_eval_bits(self.tcx, param_env, ct.ty).and_then(|b| { let sz = self.tcx.layout_of(param_env.and(ct.ty)).ok()?.size; - let val = sign_extend(b, sz) as i128; + let val = sz.sign_extend(b) as i128; if val < 0 { neg = true; } diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 5c87a8f6b3d2..12cdd5c169ac 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -306,6 +306,35 @@ impl Size { let bytes = self.bytes().checked_mul(count)?; if bytes < dl.obj_size_bound() { Some(Size::from_bytes(bytes)) } else { None } } + + /// Truncates `value` to `self` bits and then sign-extend it to 128 bits + /// (i.e., if it is negative, fill with 1's on the left). + #[inline] + pub fn sign_extend(self, value: u128) -> u128 { + let size = self.bits(); + if size == 0 { + // Truncated until nothing is left. + return 0; + } + // Sign-extend it. + let shift = 128 - size; + // Shift the unsigned value to the left, then shift back to the right as signed + // (essentially fills with FF on the left). + (((value << shift) as i128) >> shift) as u128 + } + + /// Truncates `value` to `self` bits. + #[inline] + pub fn truncate(self, value: u128) -> u128 { + let size = self.bits(); + if size == 0 { + // Truncated until nothing is left. + return 0; + } + let shift = 128 - size; + // Truncate (shift left to drop out leftover values, shift right to fill with zeroes). + (value << shift) >> shift + } } // Panicking addition, subtraction and multiplication for convenience. diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 167b06428e50..f6258221e322 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -14,7 +14,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; -use rustc_middle::mir::interpret::{sign_extend, ConstValue}; +use rustc_middle::mir::interpret::ConstValue; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::{self, DefIdTree, Ty}; use rustc_span::symbol::{kw, sym, Symbol}; @@ -506,7 +506,7 @@ fn print_const_with_custom_print_scalar(cx: &DocContext<'_>, ct: &'tcx ty::Const let ty = cx.tcx.lift(ct.ty).unwrap(); let size = cx.tcx.layout_of(ty::ParamEnv::empty().and(ty)).unwrap().size; let data = int.assert_bits(size); - let sign_extended_data = sign_extend(data, size) as i128; + let sign_extended_data = size.sign_extend(data) as i128; format!( "{}{}",