<commit_before>// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.


#![allow(clippy::float_cmp)]

use crate::rustc::hir::def::Def;
use crate::rustc::hir::*;
use crate::rustc::lint::LateContext;
use crate::rustc::ty::subst::{Subst, Substs};
use crate::rustc::ty::{self, Instance, Ty, TyCtxt};
use crate::rustc::{bug, span_bug};
use crate::syntax::ast::{FloatTy, LitKind};
use crate::syntax::ptr::P;
use crate::utils::{clip, sext, unsext};
use std::cmp::Ordering::{self, Equal};
use std::cmp::PartialOrd;
use std::convert::TryInto;
use std::hash::{Hash, Hasher};
use std::mem;
use std::rc::Rc;

/// A `LitKind`-like enum to fold constant `Expr`s into.
#[derive(Debug, Clone)]
pub enum Constant {
    /// a String "abc"
    Str(String),
    /// a Binary String b"abc"
    Binary(Rc<Vec<u8>>),
    /// a single char 'a'
    Char(char),
    /// an integer's bit representation
    Int(u128),
    /// an f32
    F32(f32),
    /// an f64
    F64(f64),
    /// true or false
    Bool(bool),
    /// an array of constants
    Vec(Vec<Constant>),
    /// also an array, but with only one constant, repeated N times
    Repeat(Box<Constant>, u64),
    /// a tuple of constants
    Tuple(Vec<Constant>),
}

impl PartialEq for Constant {
    fn eq(&self, other: &Self) -> bool {
        match (self, other) {
            (&Constant::Str(ref ls), &Constant::Str(ref rs)) => ls == rs,
            (&Constant::Binary(ref l), &Constant::Binary(ref r)) => l == r,
            (&Constant::Char(l), &Constant::Char(r)) => l == r,
            (&Constant::Int(l), &Constant::Int(r)) => l == r,
            (&Constant::F64(l), &Constant::F64(r)) => {
                // we want `Fw32 == FwAny` and `FwAny == Fw64`, by transitivity we must have
                // `Fw32 == Fw64` so don’t compare them
                // mem::transmute is required to catch non-matching 0.0, -0.0, and NaNs
                unsafe { mem::transmute::<f64, u64>(l) == mem::transmute::<f64, u64>(r) }
            },
            (&Constant::F32(l), &Constant::F32(r)) => {
                // we want `Fw32 == FwAny` and `FwAny == Fw64`, by transitivity we must have
                // `Fw32 == Fw64` so don’t compare them
                // mem::transmute is required to catch non-matching 0.0, -0.0, and NaNs
                unsafe { mem::transmute::<f64, u64>(f64::from(l)) == mem::transmute::<f64, u64>(f64::from(r)) }
            },
            (&Constant::Bool(l), &Constant::Bool(r)) => l == r,
            (&Constant::Vec(ref l), &Constant::Vec(ref r)) | (&Constant::Tuple(ref l), &Constant::Tuple(ref r)) => {
                l == r
            },
            (&Constant::Repeat(ref lv, ref ls), &Constant::Repeat(ref rv, ref rs)) => ls == rs && lv == rv,
            _ => false, // TODO: Are there inter-type equalities?
        }
    }
}

impl Hash for Constant {
    fn hash<H>(&self, state: &mut H)
    where
        H: Hasher,
    {
        match *self {
            Constant::Str(ref s) => {
                s.hash(state);
            },
            Constant::Binary(ref b) => {
                b.hash(state);
            },
            Constant::Char(c) => {
                c.hash(state);
            },
            Constant::Int(i) => {
                i.hash(state);
            },
            Constant::F32(f) => {
                unsafe { mem::transmute::<f64, u64>(f64::from(f)) }.hash(state);
            },
            Constant::F64(f) => {
                unsafe { mem::transmute::<f64, u64>(f) }.hash(state);
            },
            Constant::Bool(b) => {
                b.hash(state);
            },<commit_msg>Remove unsafe from consts clippy lints<commit_after>// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.


#![allow(clippy::float_cmp)]

use crate::rustc::hir::def::Def;
use crate::rustc::hir::*;
use crate::rustc::lint::LateContext;
use crate::rustc::ty::subst::{Subst, Substs};
use crate::rustc::ty::{self, Instance, Ty, TyCtxt};
use crate::rustc::{bug, span_bug};
use crate::syntax::ast::{FloatTy, LitKind};
use crate::syntax::ptr::P;
use crate::utils::{clip, sext, unsext};
use std::cmp::Ordering::{self, Equal};
use std::cmp::PartialOrd;
use std::convert::TryInto;
use std::hash::{Hash, Hasher};
use std::rc::Rc;

/// A `LitKind`-like enum to fold constant `Expr`s into.
#[derive(Debug, Clone)]
pub enum Constant {
    /// a String "abc"
    Str(String),
    /// a Binary String b"abc"
    Binary(Rc<Vec<u8>>),
    /// a single char 'a'
    Char(char),
    /// an integer's bit representation
    Int(u128),
    /// an f32
    F32(f32),
    /// an f64
    F64(f64),
    /// true or false
    Bool(bool),
    /// an array of constants
    Vec(Vec<Constant>),
    /// also an array, but with only one constant, repeated N times
    Repeat(Box<Constant>, u64),
    /// a tuple of constants
    Tuple(Vec<Constant>),
}

impl PartialEq for Constant {
    fn eq(&self, other: &Self) -> bool {
        match (self, other) {
            (&Constant::Str(ref ls), &Constant::Str(ref rs)) => ls == rs,
            (&Constant::Binary(ref l), &Constant::Binary(ref r)) => l == r,
            (&Constant::Char(l), &Constant::Char(r)) => l == r,
            (&Constant::Int(l), &Constant::Int(r)) => l == r,
            (&Constant::F64(l), &Constant::F64(r)) => {
                // we want `Fw32 == FwAny` and `FwAny == Fw64`, by transitivity we must have
                // `Fw32 == Fw64` so don’t compare them
                // to_bits is required to catch non-matching 0.0, -0.0, and NaNs
                l.to_bits() == r.to_bits()
            },
            (&Constant::F32(l), &Constant::F32(r)) => {
                // we want `Fw32 == FwAny` and `FwAny == Fw64`, by transitivity we must have
                // `Fw32 == Fw64` so don’t compare them
                // to_bits is required to catch non-matching 0.0, -0.0, and NaNs
                f64::from(l).to_bits() == f64::from(r).to_bits()
            },
            (&Constant::Bool(l), &Constant::Bool(r)) => l == r,
            (&Constant::Vec(ref l), &Constant::Vec(ref r)) | (&Constant::Tuple(ref l), &Constant::Tuple(ref r)) => {
                l == r
            },
            (&Constant::Repeat(ref lv, ref ls), &Constant::Repeat(ref rv, ref rs)) => ls == rs && lv == rv,
            _ => false, // TODO: Are there inter-type equalities?
        }
    }
}

impl Hash for Constant {
    fn hash<H>(&self, state: &mut H)
    where
        H: Hasher,
    {
        match *self {
            Constant::Str(ref s) => {
                s.hash(state);
            },
            Constant::Binary(ref b) => {
                b.hash(state);
            },
            Constant::Char(c) => {
                c.hash(state);
            },
            Constant::Int(i) => {
                i.hash(state);
            },
            Constant::F32(f) => {
                f64::from(f).to_bits().hash(state);
            },
            Constant::F64(f) => {
                f.to_bits().hash(state);
            },
            Constant::Bool(b) => {
                b.hash(state);
            },
{'fraction_non_alphanumeric': 0.17879604672057503, 'fraction_numerical': 0.0215633423180593, 'mean_word_length': 2.1318327974276525, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1750078', 'n_tokens_mistral': 2630, 'n_tokens_neox': 2502, 'n_words': 647}