@@ -65,61 +65,67 @@ pub struct Argument<'a> {
6565 ty : ArgumentType < ' a > ,
6666}
6767
68- #[ rustc_diagnostic_item = "ArgumentMethods" ]
69- impl Argument < ' _ > {
70- #[ inline]
71- const fn new < ' a , T > ( x : & ' a T , f : fn ( & T , & mut Formatter < ' _ > ) -> Result ) -> Argument < ' a > {
68+ macro_rules! argument_new {
69+ ( $t: ty, $x: expr, $f: expr) => {
7270 Argument {
7371 // INVARIANT: this creates an `ArgumentType<'a>` from a `&'a T` and
7472 // a `fn(&T, ...)`, so the invariant is maintained.
7573 ty: ArgumentType :: Placeholder {
76- value : NonNull :: from_ref ( x) . cast ( ) ,
74+ value: NonNull :: <$t> :: from_ref( $ x) . cast( ) ,
7775 // SAFETY: function pointers always have the same layout.
78- formatter : unsafe { mem:: transmute ( f) } ,
76+ formatter: |ptr: NonNull <( ) >, fmt: & mut Formatter <' _>| {
77+ let func = $f;
78+ // SAFETY: This is the same type as the `value` field.
79+ let r = unsafe { ptr. cast:: <$t>( ) . as_ref( ) } ;
80+ ( func) ( r, fmt)
81+ } ,
7982 _lifetime: PhantomData ,
8083 } ,
8184 }
82- }
85+ } ;
86+ }
8387
88+ #[ rustc_diagnostic_item = "ArgumentMethods" ]
89+ impl Argument < ' _ > {
8490 #[ inline]
8591 pub fn new_display < T : Display > ( x : & T ) -> Argument < ' _ > {
86- Self :: new ( x, Display :: fmt)
92+ argument_new ! ( T , x, < T as Display > :: fmt)
8793 }
8894 #[ inline]
8995 pub fn new_debug < T : Debug > ( x : & T ) -> Argument < ' _ > {
90- Self :: new ( x, Debug :: fmt)
96+ argument_new ! ( T , x, < T as Debug > :: fmt)
9197 }
9298 #[ inline]
9399 pub fn new_debug_noop < T : Debug > ( x : & T ) -> Argument < ' _ > {
94- Self :: new ( x, |_, _| Ok ( ( ) ) )
100+ argument_new ! ( T , x, |_: & T , _| Ok ( ( ) ) )
95101 }
96102 #[ inline]
97103 pub fn new_octal < T : Octal > ( x : & T ) -> Argument < ' _ > {
98- Self :: new ( x, Octal :: fmt)
104+ argument_new ! ( T , x, < T as Octal > :: fmt)
99105 }
100106 #[ inline]
101107 pub fn new_lower_hex < T : LowerHex > ( x : & T ) -> Argument < ' _ > {
102- Self :: new ( x, LowerHex :: fmt)
108+ argument_new ! ( T , x, < T as LowerHex > :: fmt)
103109 }
104110 #[ inline]
105111 pub fn new_upper_hex < T : UpperHex > ( x : & T ) -> Argument < ' _ > {
106- Self :: new ( x, UpperHex :: fmt)
112+ argument_new ! ( T , x, < T as UpperHex > :: fmt)
107113 }
108114 #[ inline]
109115 pub fn new_pointer < T : Pointer > ( x : & T ) -> Argument < ' _ > {
110- Self :: new ( x, Pointer :: fmt)
116+ argument_new ! ( T , x, < T as Pointer > :: fmt)
111117 }
112118 #[ inline]
113119 pub fn new_binary < T : Binary > ( x : & T ) -> Argument < ' _ > {
114- Self :: new ( x, Binary :: fmt)
120+ argument_new ! ( T , x, < T as Binary > :: fmt)
115121 }
116122 #[ inline]
117123 pub fn new_lower_exp < T : LowerExp > ( x : & T ) -> Argument < ' _ > {
118- Self :: new ( x, LowerExp :: fmt)
124+ argument_new ! ( T , x, < T as LowerExp > :: fmt)
119125 }
120126 #[ inline]
121127 pub fn new_upper_exp < T : UpperExp > ( x : & T ) -> Argument < ' _ > {
122- Self :: new ( x, UpperExp :: fmt)
128+ argument_new ! ( T , x, < T as UpperExp > :: fmt)
123129 }
124130 #[ inline]
125131 #[ track_caller]
@@ -135,11 +141,6 @@ impl Argument<'_> {
135141 /// # Safety
136142 ///
137143 /// This argument must actually be a placeholder argument.
138- ///
139- // FIXME: Transmuting formatter in new and indirectly branching to/calling
140- // it here is an explicit CFI violation.
141- #[ allow( inline_no_sanitize) ]
142- #[ no_sanitize( cfi, kcfi) ]
143144 #[ inline]
144145 pub ( super ) unsafe fn fmt ( & self , f : & mut Formatter < ' _ > ) -> Result {
145146 match self . ty {
0 commit comments