1#![allow(missing_debug_implementations)]
2#![unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
3
4use super::*;
7use crate::hint::unreachable_unchecked;
8use crate::ptr::NonNull;
9
10#[lang = "format_placeholder"]
11#[derive(Copy, Clone)]
12pub struct Placeholder {
13 pub position: usize,
14 pub flags: u32,
15 pub precision: Count,
16 pub width: Count,
17}
18
19#[cfg(bootstrap)]
20impl Placeholder {
21 #[inline]
22 pub const fn new(position: usize, flags: u32, precision: Count, width: Count) -> Self {
23 Self { position, flags, precision, width }
24 }
25}
26
27#[lang = "format_count"]
30#[derive(Copy, Clone)]
31pub enum Count {
32 Is(u16),
34 Param(usize),
36 Implied,
38}
39
40#[derive(Copy, Clone)]
41enum ArgumentType<'a> {
42 Placeholder {
43 value: NonNull<()>,
46 formatter: unsafe fn(NonNull<()>, &mut Formatter<'_>) -> Result,
47 _lifetime: PhantomData<&'a ()>,
48 },
49 Count(u16),
50}
51
52#[lang = "format_argument"]
63#[derive(Copy, Clone)]
64pub struct Argument<'a> {
65 ty: ArgumentType<'a>,
66}
67
68#[rustc_diagnostic_item = "ArgumentMethods"]
69impl Argument<'_> {
70 #[inline]
71 const fn new<'a, T>(x: &'a T, f: fn(&T, &mut Formatter<'_>) -> Result) -> Argument<'a> {
72 Argument {
73 ty: ArgumentType::Placeholder {
76 value: NonNull::from_ref(x).cast(),
77 formatter: unsafe { mem::transmute(f) },
79 _lifetime: PhantomData,
80 },
81 }
82 }
83
84 #[inline]
85 pub fn new_display<T: Display>(x: &T) -> Argument<'_> {
86 Self::new(x, Display::fmt)
87 }
88 #[inline]
89 pub fn new_debug<T: Debug>(x: &T) -> Argument<'_> {
90 Self::new(x, Debug::fmt)
91 }
92 #[inline]
93 pub fn new_debug_noop<T: Debug>(x: &T) -> Argument<'_> {
94 Self::new(x, |_, _| Ok(()))
95 }
96 #[inline]
97 pub fn new_octal<T: Octal>(x: &T) -> Argument<'_> {
98 Self::new(x, Octal::fmt)
99 }
100 #[inline]
101 pub fn new_lower_hex<T: LowerHex>(x: &T) -> Argument<'_> {
102 Self::new(x, LowerHex::fmt)
103 }
104 #[inline]
105 pub fn new_upper_hex<T: UpperHex>(x: &T) -> Argument<'_> {
106 Self::new(x, UpperHex::fmt)
107 }
108 #[inline]
109 pub fn new_pointer<T: Pointer>(x: &T) -> Argument<'_> {
110 Self::new(x, Pointer::fmt)
111 }
112 #[inline]
113 pub fn new_binary<T: Binary>(x: &T) -> Argument<'_> {
114 Self::new(x, Binary::fmt)
115 }
116 #[inline]
117 pub fn new_lower_exp<T: LowerExp>(x: &T) -> Argument<'_> {
118 Self::new(x, LowerExp::fmt)
119 }
120 #[inline]
121 pub fn new_upper_exp<T: UpperExp>(x: &T) -> Argument<'_> {
122 Self::new(x, UpperExp::fmt)
123 }
124 #[inline]
125 #[track_caller]
126 pub const fn from_usize(x: &usize) -> Argument<'_> {
127 if *x > u16::MAX as usize {
128 panic!("Formatting argument out of range");
129 }
130 Argument { ty: ArgumentType::Count(*x as u16) }
131 }
132
133 #[allow(inline_no_sanitize)]
142 #[no_sanitize(cfi, kcfi)]
143 #[inline]
144 pub(super) unsafe fn fmt(&self, f: &mut Formatter<'_>) -> Result {
145 match self.ty {
146 ArgumentType::Placeholder { formatter, value, .. } => unsafe { formatter(value, f) },
154 ArgumentType::Count(_) => unsafe { unreachable_unchecked() },
156 }
157 }
158
159 #[inline]
160 pub(super) const fn as_u16(&self) -> Option<u16> {
161 match self.ty {
162 ArgumentType::Count(count) => Some(count),
163 ArgumentType::Placeholder { .. } => None,
164 }
165 }
166
167 #[inline]
178 pub const fn none() -> [Self; 0] {
179 []
180 }
181}
182
183#[lang = "format_unsafe_arg"]
187pub struct UnsafeArg {
188 _private: (),
189}
190
191impl UnsafeArg {
192 #[inline]
195 pub const unsafe fn new() -> Self {
196 Self { _private: () }
197 }
198}