1use std::fmt;
2use std::num::NonZero;
3
4use rustc_abi::Size;
5use rustc_apfloat::Float;
6use rustc_apfloat::ieee::{Double, Half, Quad, Single};
7use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt};
8use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
9use rustc_span::bug;
10
11use crate::mir::interpret::Scalar;
12use crate::ty::TyCtxt;
13
14#[derive(#[automatically_derived]impl ::core::marker::Copy for ConstInt { }Copy, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for ConstInt {
}
#[automatically_derived]impl ::core::clone::Clone for ConstInt {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<ScalarInt>;
let _: ::core::clone::AssertParamIsClone<bool>;
*self
}
}Clone)]
15pub struct ConstInt {
17 int: ScalarInt,
19 signed: bool,
21 is_ptr_sized_integral: bool,
23}
24
25impl ConstInt {
26 pub fn new(int: ScalarInt, signed: bool, is_ptr_sized_integral: bool) -> Self {
27 Self { int, signed, is_ptr_sized_integral }
28 }
29}
30
31#[derive(#[automatically_derived]impl ::core::fmt::Debug for AtomicOrdering {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_c_like_enum_write_str(f,
"Relaxed Release Acquire AcqRel SeqCst",
match self {
AtomicOrdering::Relaxed => 0usize,
AtomicOrdering::Release => 8usize,
AtomicOrdering::Acquire => 16usize,
AtomicOrdering::AcqRel => 24usize,
AtomicOrdering::SeqCst => 31usize,
})
}
}Debug, #[automatically_derived]impl ::core::marker::Copy for AtomicOrdering { }Copy, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for AtomicOrdering {
}
#[automatically_derived]impl ::core::clone::Clone for AtomicOrdering {
#[inline]
fn clone(&self) -> Self { *self }
}Clone)]
35pub enum AtomicOrdering {
36 Relaxed = 0,
38 Release = 1,
39 Acquire = 2,
40 AcqRel = 3,
41 SeqCst = 4,
42}
43
44#[derive(#[automatically_derived]impl ::core::fmt::Debug for SimdAlign {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
SimdAlign::Unaligned => "Unaligned",
SimdAlign::Element => "Element",
SimdAlign::Vector => "Vector",
})
}
}Debug, #[automatically_derived]impl ::core::marker::Copy for SimdAlign { }Copy, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for SimdAlign {
}
#[automatically_derived]impl ::core::clone::Clone for SimdAlign {
#[inline]
fn clone(&self) -> Self { *self }
}Clone)]
46pub enum SimdAlign {
47 Unaligned = 0,
49 Element = 1,
50 Vector = 2,
51}
52
53impl std::fmt::Debug for ConstInt {
54 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55 let Self { int, signed, is_ptr_sized_integral } = *self;
56 let size = int.size().bytes();
57 let raw = int.data;
58 if signed {
59 let bit_size = size * 8;
60 let min = 1u128 << (bit_size - 1);
61 let max = min - 1;
62 if raw == min {
63 match (size, is_ptr_sized_integral) {
64 (_, true) => fmt.write_fmt(format_args!("isize::MIN"))write!(fmt, "isize::MIN"),
65 (1, _) => fmt.write_fmt(format_args!("i8::MIN"))write!(fmt, "i8::MIN"),
66 (2, _) => fmt.write_fmt(format_args!("i16::MIN"))write!(fmt, "i16::MIN"),
67 (4, _) => fmt.write_fmt(format_args!("i32::MIN"))write!(fmt, "i32::MIN"),
68 (8, _) => fmt.write_fmt(format_args!("i64::MIN"))write!(fmt, "i64::MIN"),
69 (16, _) => fmt.write_fmt(format_args!("i128::MIN"))write!(fmt, "i128::MIN"),
70 _ => ::rustc_span::macros::bug_impl(None,
format_args!("ConstInt 0x{0:x} with size = {1} and signed = {2}", raw,
size, signed), Location::caller())bug!("ConstInt 0x{:x} with size = {} and signed = {}", raw, size, signed),
71 }
72 } else if raw == max {
73 match (size, is_ptr_sized_integral) {
74 (_, true) => fmt.write_fmt(format_args!("isize::MAX"))write!(fmt, "isize::MAX"),
75 (1, _) => fmt.write_fmt(format_args!("i8::MAX"))write!(fmt, "i8::MAX"),
76 (2, _) => fmt.write_fmt(format_args!("i16::MAX"))write!(fmt, "i16::MAX"),
77 (4, _) => fmt.write_fmt(format_args!("i32::MAX"))write!(fmt, "i32::MAX"),
78 (8, _) => fmt.write_fmt(format_args!("i64::MAX"))write!(fmt, "i64::MAX"),
79 (16, _) => fmt.write_fmt(format_args!("i128::MAX"))write!(fmt, "i128::MAX"),
80 _ => ::rustc_span::macros::bug_impl(None,
format_args!("ConstInt 0x{0:x} with size = {1} and signed = {2}", raw,
size, signed), Location::caller())bug!("ConstInt 0x{:x} with size = {} and signed = {}", raw, size, signed),
81 }
82 } else {
83 match size {
84 1 => fmt.write_fmt(format_args!("{0}", raw as i8))write!(fmt, "{}", raw as i8)?,
85 2 => fmt.write_fmt(format_args!("{0}", raw as i16))write!(fmt, "{}", raw as i16)?,
86 4 => fmt.write_fmt(format_args!("{0}", raw as i32))write!(fmt, "{}", raw as i32)?,
87 8 => fmt.write_fmt(format_args!("{0}", raw as i64))write!(fmt, "{}", raw as i64)?,
88 16 => fmt.write_fmt(format_args!("{0}", raw as i128))write!(fmt, "{}", raw as i128)?,
89 _ => ::rustc_span::macros::bug_impl(None,
format_args!("ConstInt 0x{0:x} with size = {1} and signed = {2}", raw,
size, signed), Location::caller())bug!("ConstInt 0x{:x} with size = {} and signed = {}", raw, size, signed),
90 }
91 if fmt.alternate() {
92 match (size, is_ptr_sized_integral) {
93 (_, true) => fmt.write_fmt(format_args!("_isize"))write!(fmt, "_isize")?,
94 (1, _) => fmt.write_fmt(format_args!("_i8"))write!(fmt, "_i8")?,
95 (2, _) => fmt.write_fmt(format_args!("_i16"))write!(fmt, "_i16")?,
96 (4, _) => fmt.write_fmt(format_args!("_i32"))write!(fmt, "_i32")?,
97 (8, _) => fmt.write_fmt(format_args!("_i64"))write!(fmt, "_i64")?,
98 (16, _) => fmt.write_fmt(format_args!("_i128"))write!(fmt, "_i128")?,
99 (sz, _) => ::rustc_span::macros::bug_impl(None,
format_args!("unexpected int size i{0}", sz), Location::caller())bug!("unexpected int size i{sz}"),
100 }
101 }
102 Ok(())
103 }
104 } else {
105 let max = Size::from_bytes(size).truncate(u128::MAX);
106 if raw == max {
107 match (size, is_ptr_sized_integral) {
108 (_, true) => fmt.write_fmt(format_args!("usize::MAX"))write!(fmt, "usize::MAX"),
109 (1, _) => fmt.write_fmt(format_args!("u8::MAX"))write!(fmt, "u8::MAX"),
110 (2, _) => fmt.write_fmt(format_args!("u16::MAX"))write!(fmt, "u16::MAX"),
111 (4, _) => fmt.write_fmt(format_args!("u32::MAX"))write!(fmt, "u32::MAX"),
112 (8, _) => fmt.write_fmt(format_args!("u64::MAX"))write!(fmt, "u64::MAX"),
113 (16, _) => fmt.write_fmt(format_args!("u128::MAX"))write!(fmt, "u128::MAX"),
114 _ => ::rustc_span::macros::bug_impl(None,
format_args!("ConstInt 0x{0:x} with size = {1} and signed = {2}", raw,
size, signed), Location::caller())bug!("ConstInt 0x{:x} with size = {} and signed = {}", raw, size, signed),
115 }
116 } else {
117 match size {
118 1 => fmt.write_fmt(format_args!("{0}", raw as u8))write!(fmt, "{}", raw as u8)?,
119 2 => fmt.write_fmt(format_args!("{0}", raw as u16))write!(fmt, "{}", raw as u16)?,
120 4 => fmt.write_fmt(format_args!("{0}", raw as u32))write!(fmt, "{}", raw as u32)?,
121 8 => fmt.write_fmt(format_args!("{0}", raw as u64))write!(fmt, "{}", raw as u64)?,
122 16 => fmt.write_fmt(format_args!("{0}", raw as u128))write!(fmt, "{}", raw as u128)?,
123 _ => ::rustc_span::macros::bug_impl(None,
format_args!("ConstInt 0x{0:x} with size = {1} and signed = {2}", raw,
size, signed), Location::caller())bug!("ConstInt 0x{:x} with size = {} and signed = {}", raw, size, signed),
124 }
125 if fmt.alternate() {
126 match (size, is_ptr_sized_integral) {
127 (_, true) => fmt.write_fmt(format_args!("_usize"))write!(fmt, "_usize")?,
128 (1, _) => fmt.write_fmt(format_args!("_u8"))write!(fmt, "_u8")?,
129 (2, _) => fmt.write_fmt(format_args!("_u16"))write!(fmt, "_u16")?,
130 (4, _) => fmt.write_fmt(format_args!("_u32"))write!(fmt, "_u32")?,
131 (8, _) => fmt.write_fmt(format_args!("_u64"))write!(fmt, "_u64")?,
132 (16, _) => fmt.write_fmt(format_args!("_u128"))write!(fmt, "_u128")?,
133 (sz, _) => ::rustc_span::macros::bug_impl(None,
format_args!("unexpected unsigned int size u{0}", sz), Location::caller())bug!("unexpected unsigned int size u{sz}"),
134 }
135 }
136 Ok(())
137 }
138 }
139 }
140}
141
142#[derive(#[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for ScalarInt {
}
#[automatically_derived]impl ::core::clone::Clone for ScalarInt {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<u128>;
let _: ::core::clone::AssertParamIsClone<NonZero<u8>>;
*self
}
}Clone, #[automatically_derived]impl ::core::marker::Copy for ScalarInt { }Copy, #[automatically_derived]impl ::core::cmp::Eq for ScalarInt {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<u128>;
let _: ::core::cmp::AssertParamIsEq<NonZero<u8>>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for ScalarInt
{
}
#[automatically_derived]impl ::core::cmp::PartialEq for ScalarInt {
#[inline]
fn eq(&self, other: &Self) -> bool {
({ self.data }) == ({ other.data }) &&
({ self.size }) == ({ other.size })
}
}PartialEq, #[automatically_derived]impl ::core::hash::Hash for ScalarInt {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&{ self.data }, state);
::core::hash::Hash::hash(&{ self.size }, state)
}
}Hash)]
147#[repr(packed)]
148pub struct ScalarInt {
149 data: u128,
152 size: NonZero<u8>,
153}
154
155impl StableHash for ScalarInt {
158 fn stable_hash<Hcx: StableHashCtxt>(
159 &self,
160 hcx: &mut Hcx,
161 hasher: &mut crate::ty::StableHasher,
162 ) {
163 { self.data }.stable_hash(hcx, hasher);
168 self.size.get().stable_hash(hcx, hasher);
169 }
170}
171
172impl<S: Encoder> Encodable<S> for ScalarInt {
173 fn encode(&self, s: &mut S) {
174 let size = self.size.get();
175 s.emit_u8(size);
176 s.emit_raw_bytes(&self.data.to_le_bytes()[..size as usize]);
177 }
178}
179
180impl<D: Decoder> Decodable<D> for ScalarInt {
181 fn decode(d: &mut D) -> ScalarInt {
182 let mut data = [0u8; 16];
183 let size = d.read_u8();
184 data[..size as usize].copy_from_slice(d.read_raw_bytes(size as usize));
185 ScalarInt { data: u128::from_le_bytes(data), size: NonZero::new(size).unwrap() }
186 }
187}
188
189impl<'tcx> rustc_type_ir::inherent::ScalarInt<TyCtxt<'tcx>> for ScalarInt {
190 fn try_from_uint(i: impl Into<u128>, size: Size) -> Option<Self> {
191 Self::try_from_uint(i, size)
192 }
193
194 fn to_scalar(self) -> Scalar {
195 Scalar::Int(self)
196 }
197}
198
199impl ScalarInt {
200 pub const TRUE: ScalarInt = ScalarInt { data: 1_u128, size: NonZero::new(1).unwrap() };
201 pub const FALSE: ScalarInt = ScalarInt { data: 0_u128, size: NonZero::new(1).unwrap() };
202
203 fn raw(data: u128, size: Size) -> Self {
204 Self { data, size: NonZero::new(size.bytes() as u8).unwrap() }
205 }
206
207 #[inline]
208 pub fn size(self) -> Size {
209 Size::from_bytes(self.size.get())
210 }
211
212 #[inline(always)]
216 fn check_data(self) {
217 if true {
{
match (&self.size().truncate(self.data), &{ self.data }) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val,
::core::option::Option::Some(format_args!("Scalar value {0:#x} exceeds size of {1} bytes",
{ self.data }, self.size)));
}
}
}
};
};debug_assert_eq!(
223 self.size().truncate(self.data),
224 { self.data },
225 "Scalar value {:#x} exceeds size of {} bytes",
226 { self.data },
227 self.size
228 );
229 }
230
231 #[inline]
232 pub fn null(size: Size) -> Self {
233 Self::raw(0, size)
234 }
235
236 #[inline]
237 pub fn is_null(self) -> bool {
238 self.data == 0
239 }
240
241 #[inline]
242 pub fn try_from_uint(i: impl Into<u128>, size: Size) -> Option<Self> {
243 let (r, overflow) = Self::truncate_from_uint(i, size);
244 if overflow { None } else { Some(r) }
245 }
246
247 #[inline]
249 pub fn truncate_from_uint(i: impl Into<u128>, size: Size) -> (Self, bool) {
250 let data = i.into();
251 let r = Self::raw(size.truncate(data), size);
252 (r, r.data != data)
253 }
254
255 #[inline]
256 pub fn try_from_int(i: impl Into<i128>, size: Size) -> Option<Self> {
257 let (r, overflow) = Self::truncate_from_int(i, size);
258 if overflow { None } else { Some(r) }
259 }
260
261 #[inline]
263 pub fn truncate_from_int(i: impl Into<i128>, size: Size) -> (Self, bool) {
264 let data = i.into();
265 let r = Self::raw(size.truncate(data as u128), size);
267 (r, size.sign_extend(r.data) != data)
268 }
269
270 #[inline]
271 pub fn try_from_target_usize(i: impl Into<u128>, tcx: TyCtxt<'_>) -> Option<Self> {
272 Self::try_from_uint(i, tcx.data_layout.pointer_size())
273 }
274
275 #[inline]
277 pub fn to_bits(self, expected_size: Size) -> u128 {
278 let self_size = u64::from(self.size.get());
279 if expected_size.bytes() != self_size {
280 #[cold]
281 fn invalid(expected_size: u64, self_size: u64) -> ! {
282 {
::core::panicking::panic_fmt(format_args!("ScalarInt has size {0} but expected {1}",
self_size, expected_size));
}panic!("ScalarInt has size {self_size} but expected {expected_size}")
283 }
284
285 invalid(expected_size.bytes(), self_size);
286 }
287
288 self.check_data();
289 self.data
290 }
291
292 #[inline]
294 pub fn to_bits_unchecked(self) -> u128 {
295 self.check_data();
296 self.data
297 }
298
299 #[inline]
302 pub fn to_uint(self, size: Size) -> u128 {
303 self.to_bits(size)
304 }
305
306 #[inline]
309 pub fn to_u8(self) -> u8 {
310 self.to_uint(Size::from_bits(8)).try_into().unwrap()
311 }
312
313 #[inline]
316 pub fn to_u16(self) -> u16 {
317 self.to_uint(Size::from_bits(16)).try_into().unwrap()
318 }
319
320 #[inline]
323 pub fn to_u32(self) -> u32 {
324 self.to_uint(Size::from_bits(32)).try_into().unwrap()
325 }
326
327 #[inline]
330 pub fn to_u64(self) -> u64 {
331 self.to_uint(Size::from_bits(64)).try_into().unwrap()
332 }
333
334 #[inline]
337 pub fn to_u128(self) -> u128 {
338 self.to_uint(Size::from_bits(128))
339 }
340
341 #[inline]
342 pub fn to_target_usize(&self, tcx: TyCtxt<'_>) -> u64 {
343 self.to_uint(tcx.data_layout.pointer_size()).try_into().unwrap()
344 }
345
346 #[inline]
347 pub fn to_atomic_ordering(self) -> AtomicOrdering {
348 use AtomicOrdering::*;
349 let val = self.to_u32();
350 if val == Relaxed as u32 {
351 Relaxed
352 } else if val == Release as u32 {
353 Release
354 } else if val == Acquire as u32 {
355 Acquire
356 } else if val == AcqRel as u32 {
357 AcqRel
358 } else if val == SeqCst as u32 {
359 SeqCst
360 } else {
361 { ::core::panicking::panic_fmt(format_args!("not a valid atomic ordering")); }panic!("not a valid atomic ordering")
362 }
363 }
364
365 #[inline]
366 pub fn to_simd_alignment(self) -> SimdAlign {
367 use SimdAlign::*;
368 let val = self.to_u32();
369 if val == Unaligned as u32 {
370 Unaligned
371 } else if val == Element as u32 {
372 Element
373 } else if val == Vector as u32 {
374 Vector
375 } else {
376 { ::core::panicking::panic_fmt(format_args!("not a valid simd alignment")); }panic!("not a valid simd alignment")
377 }
378 }
379
380 #[inline]
384 pub fn try_to_bool(self) -> Result<bool, ()> {
385 match self.to_u8() {
386 0 => Ok(false),
387 1 => Ok(true),
388 _ => Err(()),
389 }
390 }
391
392 #[inline]
395 pub fn to_int(self, size: Size) -> i128 {
396 let b = self.to_bits(size);
397 size.sign_extend(b)
398 }
399
400 pub fn to_i8(self) -> i8 {
403 self.to_int(Size::from_bits(8)).try_into().unwrap()
404 }
405
406 pub fn to_i16(self) -> i16 {
409 self.to_int(Size::from_bits(16)).try_into().unwrap()
410 }
411
412 pub fn to_i32(self) -> i32 {
415 self.to_int(Size::from_bits(32)).try_into().unwrap()
416 }
417
418 pub fn to_i64(self) -> i64 {
421 self.to_int(Size::from_bits(64)).try_into().unwrap()
422 }
423
424 pub fn to_i128(self) -> i128 {
427 self.to_int(Size::from_bits(128))
428 }
429
430 #[inline]
431 pub fn to_target_isize(&self, tcx: TyCtxt<'_>) -> i64 {
432 self.to_int(tcx.data_layout.pointer_size()).try_into().unwrap()
433 }
434
435 #[inline]
436 pub fn to_float<F: Float>(self) -> F {
437 F::from_bits(self.to_bits(Size::from_bits(F::BITS)))
439 }
440
441 #[inline]
442 pub fn to_f16(self) -> Half {
443 self.to_float()
444 }
445
446 #[inline]
447 pub fn to_f32(self) -> Single {
448 self.to_float()
449 }
450
451 #[inline]
452 pub fn to_f64(self) -> Double {
453 self.to_float()
454 }
455
456 #[inline]
457 pub fn to_f128(self) -> Quad {
458 self.to_float()
459 }
460}
461
462macro_rules! from_x_for_scalar_int {
463 ($($ty:ty),*) => {
464 $(
465 impl From<$ty> for ScalarInt {
466 #[inline]
467 fn from(u: $ty) -> Self {
468 Self {
469 data: u128::from(u),
470 size: NonZero::new(size_of::<$ty>() as u8).unwrap(),
471 }
472 }
473 }
474 )*
475 }
476}
477
478macro_rules! from_scalar_int_for_x {
479 ($($ty:ty),*) => {
480 $(
481 impl From<ScalarInt> for $ty {
482 #[inline]
483 fn from(int: ScalarInt) -> Self {
484 int.to_uint(Size::from_bytes(size_of::<$ty>()))
487 .try_into().unwrap()
488 }
489 }
490 )*
491 }
492}
493
494impl From<u8> for ScalarInt {
#[inline]
fn from(u: u8) -> Self {
Self {
data: u128::from(u),
size: NonZero::new(size_of::<u8>() as u8).unwrap(),
}
}
}
impl From<u16> for ScalarInt {
#[inline]
fn from(u: u16) -> Self {
Self {
data: u128::from(u),
size: NonZero::new(size_of::<u16>() as u8).unwrap(),
}
}
}
impl From<u32> for ScalarInt {
#[inline]
fn from(u: u32) -> Self {
Self {
data: u128::from(u),
size: NonZero::new(size_of::<u32>() as u8).unwrap(),
}
}
}
impl From<u64> for ScalarInt {
#[inline]
fn from(u: u64) -> Self {
Self {
data: u128::from(u),
size: NonZero::new(size_of::<u64>() as u8).unwrap(),
}
}
}
impl From<u128> for ScalarInt {
#[inline]
fn from(u: u128) -> Self {
Self {
data: u128::from(u),
size: NonZero::new(size_of::<u128>() as u8).unwrap(),
}
}
}
impl From<bool> for ScalarInt {
#[inline]
fn from(u: bool) -> Self {
Self {
data: u128::from(u),
size: NonZero::new(size_of::<bool>() as u8).unwrap(),
}
}
}from_x_for_scalar_int!(u8, u16, u32, u64, u128, bool);
495impl From<ScalarInt> for u8 {
#[inline]
fn from(int: ScalarInt) -> Self {
int.to_uint(Size::from_bytes(size_of::<u8>())).try_into().unwrap()
}
}
impl From<ScalarInt> for u16 {
#[inline]
fn from(int: ScalarInt) -> Self {
int.to_uint(Size::from_bytes(size_of::<u16>())).try_into().unwrap()
}
}
impl From<ScalarInt> for u32 {
#[inline]
fn from(int: ScalarInt) -> Self {
int.to_uint(Size::from_bytes(size_of::<u32>())).try_into().unwrap()
}
}
impl From<ScalarInt> for u64 {
#[inline]
fn from(int: ScalarInt) -> Self {
int.to_uint(Size::from_bytes(size_of::<u64>())).try_into().unwrap()
}
}
impl From<ScalarInt> for u128 {
#[inline]
fn from(int: ScalarInt) -> Self {
int.to_uint(Size::from_bytes(size_of::<u128>())).try_into().unwrap()
}
}from_scalar_int_for_x!(u8, u16, u32, u64, u128);
496
497impl TryFrom<ScalarInt> for bool {
498 type Error = ();
499 #[inline]
500 fn try_from(int: ScalarInt) -> Result<Self, ()> {
501 int.try_to_bool()
502 }
503}
504
505impl From<char> for ScalarInt {
506 #[inline]
507 fn from(c: char) -> Self {
508 (c as u32).into()
509 }
510}
511
512macro_rules! from_x_for_scalar_int_signed {
513 ($($ty:ty),*) => {
514 $(
515 impl From<$ty> for ScalarInt {
516 #[inline]
517 fn from(u: $ty) -> Self {
518 Self {
519 data: u128::from(u.cast_unsigned()), size: NonZero::new(size_of::<$ty>() as u8).unwrap(),
521 }
522 }
523 }
524 )*
525 }
526}
527
528macro_rules! from_scalar_int_for_x_signed {
529 ($($ty:ty),*) => {
530 $(
531 impl From<ScalarInt> for $ty {
532 #[inline]
533 fn from(int: ScalarInt) -> Self {
534 int.to_int(Size::from_bytes(size_of::<$ty>()))
537 .try_into().unwrap()
538 }
539 }
540 )*
541 }
542}
543
544impl From<i8> for ScalarInt {
#[inline]
fn from(u: i8) -> Self {
Self {
data: u128::from(u.cast_unsigned()),
size: NonZero::new(size_of::<i8>() as u8).unwrap(),
}
}
}
impl From<i16> for ScalarInt {
#[inline]
fn from(u: i16) -> Self {
Self {
data: u128::from(u.cast_unsigned()),
size: NonZero::new(size_of::<i16>() as u8).unwrap(),
}
}
}
impl From<i32> for ScalarInt {
#[inline]
fn from(u: i32) -> Self {
Self {
data: u128::from(u.cast_unsigned()),
size: NonZero::new(size_of::<i32>() as u8).unwrap(),
}
}
}
impl From<i64> for ScalarInt {
#[inline]
fn from(u: i64) -> Self {
Self {
data: u128::from(u.cast_unsigned()),
size: NonZero::new(size_of::<i64>() as u8).unwrap(),
}
}
}
impl From<i128> for ScalarInt {
#[inline]
fn from(u: i128) -> Self {
Self {
data: u128::from(u.cast_unsigned()),
size: NonZero::new(size_of::<i128>() as u8).unwrap(),
}
}
}from_x_for_scalar_int_signed!(i8, i16, i32, i64, i128);
545impl From<ScalarInt> for i8 {
#[inline]
fn from(int: ScalarInt) -> Self {
int.to_int(Size::from_bytes(size_of::<i8>())).try_into().unwrap()
}
}
impl From<ScalarInt> for i16 {
#[inline]
fn from(int: ScalarInt) -> Self {
int.to_int(Size::from_bytes(size_of::<i16>())).try_into().unwrap()
}
}
impl From<ScalarInt> for i32 {
#[inline]
fn from(int: ScalarInt) -> Self {
int.to_int(Size::from_bytes(size_of::<i32>())).try_into().unwrap()
}
}
impl From<ScalarInt> for i64 {
#[inline]
fn from(int: ScalarInt) -> Self {
int.to_int(Size::from_bytes(size_of::<i64>())).try_into().unwrap()
}
}
impl From<ScalarInt> for i128 {
#[inline]
fn from(int: ScalarInt) -> Self {
int.to_int(Size::from_bytes(size_of::<i128>())).try_into().unwrap()
}
}from_scalar_int_for_x_signed!(i8, i16, i32, i64, i128);
546
547impl From<std::cmp::Ordering> for ScalarInt {
548 #[inline]
549 fn from(c: std::cmp::Ordering) -> Self {
550 ScalarInt::from(c as i8)
552 }
553}
554
555#[derive(#[automatically_derived]impl ::core::fmt::Debug for CharTryFromScalarInt {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "CharTryFromScalarInt")
}
}Debug)]
557pub struct CharTryFromScalarInt;
558
559impl TryFrom<ScalarInt> for char {
560 type Error = CharTryFromScalarInt;
561
562 #[inline]
563 fn try_from(int: ScalarInt) -> Result<Self, Self::Error> {
564 match char::from_u32(int.to_u32()) {
565 Some(c) => Ok(c),
566 None => Err(CharTryFromScalarInt),
567 }
568 }
569}
570
571impl From<Half> for ScalarInt {
572 #[inline]
573 fn from(f: Half) -> Self {
574 Self { data: f.to_bits(), size: NonZero::new((Half::BITS / 8) as u8).unwrap() }
576 }
577}
578
579impl From<ScalarInt> for Half {
580 #[inline]
581 fn from(int: ScalarInt) -> Self {
582 Self::from_bits(int.to_bits(Size::from_bytes(2)))
583 }
584}
585
586impl From<Single> for ScalarInt {
587 #[inline]
588 fn from(f: Single) -> Self {
589 Self { data: f.to_bits(), size: NonZero::new((Single::BITS / 8) as u8).unwrap() }
591 }
592}
593
594impl From<ScalarInt> for Single {
595 #[inline]
596 fn from(int: ScalarInt) -> Self {
597 Self::from_bits(int.to_bits(Size::from_bytes(4)))
598 }
599}
600
601impl From<Double> for ScalarInt {
602 #[inline]
603 fn from(f: Double) -> Self {
604 Self { data: f.to_bits(), size: NonZero::new((Double::BITS / 8) as u8).unwrap() }
606 }
607}
608
609impl From<ScalarInt> for Double {
610 #[inline]
611 fn from(int: ScalarInt) -> Self {
612 Self::from_bits(int.to_bits(Size::from_bytes(8)))
613 }
614}
615
616impl From<Quad> for ScalarInt {
617 #[inline]
618 fn from(f: Quad) -> Self {
619 Self { data: f.to_bits(), size: NonZero::new((Quad::BITS / 8) as u8).unwrap() }
621 }
622}
623
624impl From<ScalarInt> for Quad {
625 #[inline]
626 fn from(int: ScalarInt) -> Self {
627 Self::from_bits(int.to_bits(Size::from_bytes(16)))
628 }
629}
630
631impl fmt::Debug for ScalarInt {
632 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
633 f.write_fmt(format_args!("0x{0:x}", self))write!(f, "0x{self:x}")
635 }
636}
637
638impl fmt::LowerHex for ScalarInt {
639 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
640 self.check_data();
641 if f.alternate() {
642 f.write_fmt(format_args!("0x"))write!(f, "0x")?;
644 }
645 f.write_fmt(format_args!("{0:01$x}", { self.data },
self.size.get() as usize * 2))write!(f, "{:01$x}", { self.data }, self.size.get() as usize * 2)
653 }
654}
655
656impl fmt::UpperHex for ScalarInt {
657 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
658 self.check_data();
659 f.write_fmt(format_args!("{0:01$X}", { self.data },
self.size.get() as usize * 2))write!(f, "{:01$X}", { self.data }, self.size.get() as usize * 2)
667 }
668}
669
670impl fmt::Display for ScalarInt {
671 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
672 self.check_data();
673 f.write_fmt(format_args!("{0}", { self.data }))write!(f, "{}", { self.data })
674 }
675}