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
23impl Placeholder {
24 #[cfg(bootstrap)]
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 #[cfg(not(bootstrap))]
38 #[inline]
39 pub const fn new(position: usize, flags: u32, precision: Count, width: Count) -> Self {
40 Self { position, flags, precision, width }
41 }
42}
43
44#[cfg(bootstrap)]
45#[lang = "format_alignment"]
46#[derive(Copy, Clone, PartialEq, Eq)]
47pub enum Alignment {
48 Left,
49 Right,
50 Center,
51 Unknown,
52}
53
54#[lang = "format_count"]
57#[derive(Copy, Clone)]
58pub enum Count {
59 #[cfg(bootstrap)]
61 Is(usize),
62 #[cfg(not(bootstrap))]
64 Is(u16),
65 Param(usize),
67 Implied,
69}
70
71#[derive(Copy, Clone)]
72enum ArgumentType<'a> {
73 Placeholder {
74 value: NonNull<()>,
77 formatter: unsafe fn(NonNull<()>, &mut Formatter<'_>) -> Result,
78 _lifetime: PhantomData<&'a ()>,
79 },
80 Count(u16),
81}
82
83#[lang = "format_argument"]
94#[derive(Copy, Clone)]
95pub struct Argument<'a> {
96 ty: ArgumentType<'a>,
97}
98
99#[rustc_diagnostic_item = "ArgumentMethods"]
100impl Argument<'_> {
101 #[inline]
102 const fn new<'a, T>(x: &'a T, f: fn(&T, &mut Formatter<'_>) -> Result) -> Argument<'a> {
103 Argument {
104 ty: ArgumentType::Placeholder {
107 value: NonNull::from_ref(x).cast(),
108 formatter: unsafe { mem::transmute(f) },
110 _lifetime: PhantomData,
111 },
112 }
113 }
114
115 #[inline]
116 pub fn new_display<T: Display>(x: &T) -> Argument<'_> {
117 Self::new(x, Display::fmt)
118 }
119 #[inline]
120 pub fn new_debug<T: Debug>(x: &T) -> Argument<'_> {
121 Self::new(x, Debug::fmt)
122 }
123 #[inline]
124 pub fn new_debug_noop<T: Debug>(x: &T) -> Argument<'_> {
125 Self::new(x, |_, _| Ok(()))
126 }
127 #[inline]
128 pub fn new_octal<T: Octal>(x: &T) -> Argument<'_> {
129 Self::new(x, Octal::fmt)
130 }
131 #[inline]
132 pub fn new_lower_hex<T: LowerHex>(x: &T) -> Argument<'_> {
133 Self::new(x, LowerHex::fmt)
134 }
135 #[inline]
136 pub fn new_upper_hex<T: UpperHex>(x: &T) -> Argument<'_> {
137 Self::new(x, UpperHex::fmt)
138 }
139 #[inline]
140 pub fn new_pointer<T: Pointer>(x: &T) -> Argument<'_> {
141 Self::new(x, Pointer::fmt)
142 }
143 #[inline]
144 pub fn new_binary<T: Binary>(x: &T) -> Argument<'_> {
145 Self::new(x, Binary::fmt)
146 }
147 #[inline]
148 pub fn new_lower_exp<T: LowerExp>(x: &T) -> Argument<'_> {
149 Self::new(x, LowerExp::fmt)
150 }
151 #[inline]
152 pub fn new_upper_exp<T: UpperExp>(x: &T) -> Argument<'_> {
153 Self::new(x, UpperExp::fmt)
154 }
155 #[inline]
156 #[track_caller]
157 pub const fn from_usize(x: &usize) -> Argument<'_> {
158 if *x > u16::MAX as usize {
159 panic!("Formatting argument out of range");
160 }
161 Argument { ty: ArgumentType::Count(*x as u16) }
162 }
163
164 #[allow(inline_no_sanitize)]
173 #[no_sanitize(cfi, kcfi)]
174 #[inline]
175 pub(super) unsafe fn fmt(&self, f: &mut Formatter<'_>) -> Result {
176 match self.ty {
177 ArgumentType::Placeholder { formatter, value, .. } => unsafe { formatter(value, f) },
185 ArgumentType::Count(_) => unsafe { unreachable_unchecked() },
187 }
188 }
189
190 #[inline]
191 pub(super) const fn as_u16(&self) -> Option<u16> {
192 match self.ty {
193 ArgumentType::Count(count) => Some(count),
194 ArgumentType::Placeholder { .. } => None,
195 }
196 }
197
198 #[inline]
216 pub fn none() -> [Self; 0] {
217 []
218 }
219}
220
221#[lang = "format_unsafe_arg"]
225pub struct UnsafeArg {
226 _private: (),
227}
228
229impl UnsafeArg {
230 #[inline]
233 pub const unsafe fn new() -> Self {
234 Self { _private: () }
235 }
236}