]> git.proxmox.com Git - rustc.git/blob - compiler/rustc_middle/src/ty/consts/int.rs
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / compiler / rustc_middle / src / ty / consts / int.rs
1 use crate::mir::interpret::truncate;
2 use rustc_target::abi::Size;
3
4 #[derive(Copy, Clone)]
5 /// A type for representing any integer. Only used for printing.
6 // FIXME: Use this for the integer-tree representation needed for type level ints and
7 // const generics?
8 pub struct ConstInt {
9 /// Number of bytes of the integer. Only 1, 2, 4, 8, 16 are legal values.
10 size: u8,
11 /// Whether the value is of a signed integer type.
12 signed: bool,
13 /// Whether the value is a `usize` or `isize` type.
14 is_ptr_sized_integral: bool,
15 /// Raw memory of the integer. All bytes beyond the `size` are unused and must be zero.
16 raw: u128,
17 }
18
19 impl ConstInt {
20 pub fn new(raw: u128, size: Size, signed: bool, is_ptr_sized_integral: bool) -> Self {
21 assert!(raw <= truncate(u128::MAX, size));
22 Self { raw, size: size.bytes() as u8, signed, is_ptr_sized_integral }
23 }
24 }
25
26 impl std::fmt::Debug for ConstInt {
27 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28 let Self { size, signed, raw, is_ptr_sized_integral } = *self;
29 if signed {
30 let bit_size = size * 8;
31 let min = 1u128 << (bit_size - 1);
32 let max = min - 1;
33 if raw == min {
34 match (size, is_ptr_sized_integral) {
35 (_, true) => write!(fmt, "isize::MIN"),
36 (1, _) => write!(fmt, "i8::MIN"),
37 (2, _) => write!(fmt, "i16::MIN"),
38 (4, _) => write!(fmt, "i32::MIN"),
39 (8, _) => write!(fmt, "i64::MIN"),
40 (16, _) => write!(fmt, "i128::MIN"),
41 _ => bug!("ConstInt 0x{:x} with size = {} and signed = {}", raw, size, signed),
42 }
43 } else if raw == max {
44 match (size, is_ptr_sized_integral) {
45 (_, true) => write!(fmt, "isize::MAX"),
46 (1, _) => write!(fmt, "i8::MAX"),
47 (2, _) => write!(fmt, "i16::MAX"),
48 (4, _) => write!(fmt, "i32::MAX"),
49 (8, _) => write!(fmt, "i64::MAX"),
50 (16, _) => write!(fmt, "i128::MAX"),
51 _ => bug!("ConstInt 0x{:x} with size = {} and signed = {}", raw, size, signed),
52 }
53 } else {
54 match size {
55 1 => write!(fmt, "{}", raw as i8)?,
56 2 => write!(fmt, "{}", raw as i16)?,
57 4 => write!(fmt, "{}", raw as i32)?,
58 8 => write!(fmt, "{}", raw as i64)?,
59 16 => write!(fmt, "{}", raw as i128)?,
60 _ => bug!("ConstInt 0x{:x} with size = {} and signed = {}", raw, size, signed),
61 }
62 if fmt.alternate() {
63 match (size, is_ptr_sized_integral) {
64 (_, true) => write!(fmt, "_isize")?,
65 (1, _) => write!(fmt, "_i8")?,
66 (2, _) => write!(fmt, "_i16")?,
67 (4, _) => write!(fmt, "_i32")?,
68 (8, _) => write!(fmt, "_i64")?,
69 (16, _) => write!(fmt, "_i128")?,
70 _ => bug!(),
71 }
72 }
73 Ok(())
74 }
75 } else {
76 let max = truncate(u128::MAX, Size::from_bytes(size));
77 if raw == max {
78 match (size, is_ptr_sized_integral) {
79 (_, true) => write!(fmt, "usize::MAX"),
80 (1, _) => write!(fmt, "u8::MAX"),
81 (2, _) => write!(fmt, "u16::MAX"),
82 (4, _) => write!(fmt, "u32::MAX"),
83 (8, _) => write!(fmt, "u64::MAX"),
84 (16, _) => write!(fmt, "u128::MAX"),
85 _ => bug!("ConstInt 0x{:x} with size = {} and signed = {}", raw, size, signed),
86 }
87 } else {
88 match size {
89 1 => write!(fmt, "{}", raw as u8)?,
90 2 => write!(fmt, "{}", raw as u16)?,
91 4 => write!(fmt, "{}", raw as u32)?,
92 8 => write!(fmt, "{}", raw as u64)?,
93 16 => write!(fmt, "{}", raw as u128)?,
94 _ => bug!("ConstInt 0x{:x} with size = {} and signed = {}", raw, size, signed),
95 }
96 if fmt.alternate() {
97 match (size, is_ptr_sized_integral) {
98 (_, true) => write!(fmt, "_usize")?,
99 (1, _) => write!(fmt, "_u8")?,
100 (2, _) => write!(fmt, "_u16")?,
101 (4, _) => write!(fmt, "_u32")?,
102 (8, _) => write!(fmt, "_u64")?,
103 (16, _) => write!(fmt, "_u128")?,
104 _ => bug!(),
105 }
106 }
107 Ok(())
108 }
109 }
110 }
111 }