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 #[cfg(bootstrap)]
15 pub fill: char,
16 #[cfg(bootstrap)]
17 pub align: Alignment,
18 pub flags: u32,
19 pub precision: Count,
20 pub width: Count,
21}
22
23#[cfg(bootstrap)]
24impl Placeholder {
25 #[inline]
26 pub const fn new(
27 position: usize,
28 fill: char,
29 align: Alignment,
30 flags: u32,
31 precision: Count,
32 width: Count,
33 ) -> Self {
34 Self { position, fill, align, flags, precision, width }
35 }
36}
37
38#[cfg(bootstrap)]
39#[lang = "format_alignment"]
40#[derive(Copy, Clone, PartialEq, Eq)]
41pub enum Alignment {
42 Left,
43 Right,
44 Center,
45 Unknown,
46}
47
48#[lang = "format_count"]
51#[derive(Copy, Clone)]
52pub enum Count {
53 #[cfg(bootstrap)]
55 Is(usize),
56 #[cfg(not(bootstrap))]
58 Is(u16),
59 Param(usize),
61 Implied,
63}
64
65#[derive(Copy, Clone)]
66enum ArgumentType<'a> {
67 Placeholder {
68 value: NonNull<()>,
71 formatter: unsafe fn(NonNull<()>, &mut Formatter<'_>) -> Result,
72 _lifetime: PhantomData<&'a ()>,
73 },
74 Count(u16),
75}
76
77#[lang = "format_argument"]
88#[derive(Copy, Clone)]
89pub struct Argument<'a> {
90 ty: ArgumentType<'a>,
91}
92
93#[rustc_diagnostic_item = "ArgumentMethods"]
94impl Argument<'_> {
95 #[inline]
96 const fn new<'a, T>(x: &'a T, f: fn(&T, &mut Formatter<'_>) -> Result) -> Argument<'a> {
97 Argument {
98 ty: ArgumentType::Placeholder {
101 value: NonNull::from_ref(x).cast(),
102 formatter: unsafe { mem::transmute(f) },
104 _lifetime: PhantomData,
105 },
106 }
107 }
108
109 #[inline]
110 pub fn new_display<T: Display>(x: &T) -> Argument<'_> {
111 Self::new(x, Display::fmt)
112 }
113 #[inline]
114 pub fn new_debug<T: Debug>(x: &T) -> Argument<'_> {
115 Self::new(x, Debug::fmt)
116 }
117 #[inline]
118 pub fn new_debug_noop<T: Debug>(x: &T) -> Argument<'_> {
119 Self::new(x, |_, _| Ok(()))
120 }
121 #[inline]
122 pub fn new_octal<T: Octal>(x: &T) -> Argument<'_> {
123 Self::new(x, Octal::fmt)
124 }
125 #[inline]
126 pub fn new_lower_hex<T: LowerHex>(x: &T) -> Argument<'_> {
127 Self::new(x, LowerHex::fmt)
128 }
129 #[inline]
130 pub fn new_upper_hex<T: UpperHex>(x: &T) -> Argument<'_> {
131 Self::new(x, UpperHex::fmt)
132 }
133 #[inline]
134 pub fn new_pointer<T: Pointer>(x: &T) -> Argument<'_> {
135 Self::new(x, Pointer::fmt)
136 }
137 #[inline]
138 pub fn new_binary<T: Binary>(x: &T) -> Argument<'_> {
139 Self::new(x, Binary::fmt)
140 }
141 #[inline]
142 pub fn new_lower_exp<T: LowerExp>(x: &T) -> Argument<'_> {
143 Self::new(x, LowerExp::fmt)
144 }
145 #[inline]
146 pub fn new_upper_exp<T: UpperExp>(x: &T) -> Argument<'_> {
147 Self::new(x, UpperExp::fmt)
148 }
149 #[inline]
150 #[track_caller]
151 pub const fn from_usize(x: &usize) -> Argument<'_> {
152 if *x > u16::MAX as usize {
153 panic!("Formatting argument out of range");
154 }
155 Argument { ty: ArgumentType::Count(*x as u16) }
156 }
157
158 #[allow(inline_no_sanitize)]
167 #[no_sanitize(cfi, kcfi)]
168 #[inline]
169 pub(super) unsafe fn fmt(&self, f: &mut Formatter<'_>) -> Result {
170 match self.ty {
171 ArgumentType::Placeholder { formatter, value, .. } => unsafe { formatter(value, f) },
179 ArgumentType::Count(_) => unsafe { unreachable_unchecked() },
181 }
182 }
183
184 #[inline]
185 pub(super) const fn as_u16(&self) -> Option<u16> {
186 match self.ty {
187 ArgumentType::Count(count) => Some(count),
188 ArgumentType::Placeholder { .. } => None,
189 }
190 }
191
192 #[inline]
203 pub const fn none() -> [Self; 0] {
204 []
205 }
206}
207
208#[lang = "format_unsafe_arg"]
212pub struct UnsafeArg {
213 _private: (),
214}
215
216impl UnsafeArg {
217 #[inline]
220 pub const unsafe fn new() -> Self {
221 Self { _private: () }
222 }
223}