<commit_before>//! Miscellaneous type-system utilities that are too small to deserve their own modules.

use crate::hir::def::Def;
use crate::hir::def_id::DefId;
use crate::hir::map::DefPathData;
use crate::hir::{self, Node};
use crate::ich::NodeIdHashingMode;
use crate::traits::{self, ObligationCause};
use crate::ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable};
use crate::ty::subst::{Subst, Substs, UnpackedKind};
use crate::ty::query::TyCtxtAt;
use crate::ty::TyKind::*;
use crate::ty::layout::{Integer, IntegerExt};
use crate::util::common::ErrorReported;
use crate::middle::lang_items;

use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use std::{cmp, fmt};
use syntax::ast;
use syntax::attr::{self, SignedInt, UnsignedInt};
use syntax_pos::{Span, DUMMY_SP};

#[derive(Copy, Clone, Debug)]
pub struct Discr<'tcx> {
    /// Bit representation of the discriminant (e.g., `-128i8` is `0xFF_u128`).
    pub val: u128,
    pub ty: Ty<'tcx>
}

impl<'tcx> fmt::Display for Discr<'tcx> {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self.ty.sty {
            ty::Int(ity) => {
                let bits = ty::tls::with(|tcx| {
                    Integer::from_attr(&tcx, SignedInt(ity)).size().bits()
                });
                let x = self.val as i128;
                // sign extend the raw representation to be an i128
                let x = (x << (128 - bits)) >> (128 - bits);
                write!(fmt, "{}", x)
            },
            _ => write!(fmt, "{}", self.val),
        }
    }
}

impl<'tcx> Discr<'tcx> {
    /// Adds `1` to the value and wraps around if the maximum for the type is reached.
    pub fn wrap_incr<'a, 'gcx>(self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self {
        self.checked_add(tcx, 1).0
    }
    pub fn checked_add<'a, 'gcx>(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, n: u128) -> (Self, bool) {
        let (int, signed) = match self.ty.sty {
            Int(ity) => (Integer::from_attr(&tcx, SignedInt(ity)), true),
            Uint(uty) => (Integer::from_attr(&tcx, UnsignedInt(uty)), false),
            _ => bug!("non integer discriminant"),
        };

        let bit_size = int.size().bits();
        let shift = 128 - bit_size;
        if signed {
            let sext = |u| {
                let i = u as i128;
                (i << shift) >> shift
            };
            let min = sext(1_u128 << (bit_size - 1));
            let max = i128::max_value() >> shift;
            let val = sext(self.val);
            assert!(n < (i128::max_value() 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 = (val << shift) >> shift;
            (Self {
                val: val as u128,
                ty: self.ty,
            }, oflo)
        } else {
            let max = u128::max_value() >> shift;
            let val = self.val;
            let oflo = val > max - n;
            let val = if oflo {
                n - (max - val) - 1
            } else {<commit_msg>reduce repetitions of (n << amt) >> amt<commit_after>//! Miscellaneous type-system utilities that are too small to deserve their own modules.

use crate::hir::def::Def;
use crate::hir::def_id::DefId;
use crate::hir::map::DefPathData;
use crate::hir::{self, Node};
use crate::mir::interpret::{sign_extend, truncate};
use crate::ich::NodeIdHashingMode;
use crate::traits::{self, ObligationCause};
use crate::ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable};
use crate::ty::subst::{Subst, Substs, UnpackedKind};
use crate::ty::query::TyCtxtAt;
use crate::ty::TyKind::*;
use crate::ty::layout::{Integer, IntegerExt};
use crate::util::common::ErrorReported;
use crate::middle::lang_items;

use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use std::{cmp, fmt};
use syntax::ast;
use syntax::attr::{self, SignedInt, UnsignedInt};
use syntax_pos::{Span, DUMMY_SP};

#[derive(Copy, Clone, Debug)]
pub struct Discr<'tcx> {
    /// Bit representation of the discriminant (e.g., `-128i8` is `0xFF_u128`).
    pub val: u128,
    pub ty: Ty<'tcx>
}

impl<'tcx> fmt::Display for Discr<'tcx> {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self.ty.sty {
            ty::Int(ity) => {
                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;
                write!(fmt, "{}", x)
            },
            _ => write!(fmt, "{}", self.val),
        }
    }
}

impl<'tcx> Discr<'tcx> {
    /// Adds `1` to the value and wraps around if the maximum for the type is reached.
    pub fn wrap_incr<'a, 'gcx>(self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self {
        self.checked_add(tcx, 1).0
    }
    pub fn checked_add<'a, 'gcx>(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, n: u128) -> (Self, bool) {
        let (int, signed) = match self.ty.sty {
            Int(ity) => (Integer::from_attr(&tcx, SignedInt(ity)), true),
            Uint(uty) => (Integer::from_attr(&tcx, UnsignedInt(uty)), false),
            _ => bug!("non integer discriminant"),
        };

        let size = int.size();
        let bit_size = int.size().bits();
        let shift = 128 - bit_size;
        if signed {
            let sext = |u| {
                sign_extend(u, size) as i128
            };
            let min = sext(1_u128 << (bit_size - 1));
            let max = i128::max_value() >> shift;
            let val = sext(self.val);
            assert!(n < (i128::max_value() 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);
            (Self {
                val: val as u128,
                ty: self.ty,
            }, oflo)
        } else {
            let max = u128::max_value() >> shift;
            let val = self.val;
            let oflo = val > max - n;
            let val = if oflo {
                n - (max - val) - 1
            } else {
{'fraction_non_alphanumeric': 0.1591011913738501, 'fraction_numerical': 0.018096817976172522, 'mean_word_length': 2.0394133822181484, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3359769', 'n_tokens_mistral': 2246, 'n_tokens_neox': 2194, 'n_words': 581}