diff options
| -rw-r--r-- | library/core/src/fmt/mod.rs | 2 | ||||
| -rw-r--r-- | library/core/src/fmt/rt.rs | 45 |
2 files changed, 24 insertions, 23 deletions
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 7ca390941bc..580f95eddce 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -7,7 +7,7 @@ use crate::char::{EscapeDebugExtArgs, MAX_LEN_UTF8}; use crate::marker::PhantomData; use crate::num::fmt as numfmt; use crate::ops::Deref; -use crate::{iter, mem, result, str}; +use crate::{iter, result, str}; mod builders; #[cfg(not(no_fp_fmt_parse))] diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs index 0459674303d..05e024b134d 100644 --- a/library/core/src/fmt/rt.rs +++ b/library/core/src/fmt/rt.rs @@ -65,61 +65,67 @@ pub struct Argument<'a> { ty: ArgumentType<'a>, } -#[rustc_diagnostic_item = "ArgumentMethods"] -impl Argument<'_> { - #[inline] - const fn new<'a, T>(x: &'a T, f: fn(&T, &mut Formatter<'_>) -> Result) -> Argument<'a> { +macro_rules! argument_new { + ($t:ty, $x:expr, $f:expr) => { Argument { // INVARIANT: this creates an `ArgumentType<'a>` from a `&'a T` and // a `fn(&T, ...)`, so the invariant is maintained. ty: ArgumentType::Placeholder { - value: NonNull::from_ref(x).cast(), + value: NonNull::<$t>::from_ref($x).cast(), // SAFETY: function pointers always have the same layout. - formatter: unsafe { mem::transmute(f) }, + formatter: |ptr: NonNull<()>, fmt: &mut Formatter<'_>| { + let func = $f; + // SAFETY: This is the same type as the `value` field. + let r = unsafe { ptr.cast::<$t>().as_ref() }; + (func)(r, fmt) + }, _lifetime: PhantomData, }, } - } + }; +} +#[rustc_diagnostic_item = "ArgumentMethods"] +impl Argument<'_> { #[inline] pub fn new_display<T: Display>(x: &T) -> Argument<'_> { - Self::new(x, Display::fmt) + argument_new!(T, x, <T as Display>::fmt) } #[inline] pub fn new_debug<T: Debug>(x: &T) -> Argument<'_> { - Self::new(x, Debug::fmt) + argument_new!(T, x, <T as Debug>::fmt) } #[inline] pub fn new_debug_noop<T: Debug>(x: &T) -> Argument<'_> { - Self::new(x, |_, _| Ok(())) + argument_new!(T, x, |_: &T, _| Ok(())) } #[inline] pub fn new_octal<T: Octal>(x: &T) -> Argument<'_> { - Self::new(x, Octal::fmt) + argument_new!(T, x, <T as Octal>::fmt) } #[inline] pub fn new_lower_hex<T: LowerHex>(x: &T) -> Argument<'_> { - Self::new(x, LowerHex::fmt) + argument_new!(T, x, <T as LowerHex>::fmt) } #[inline] pub fn new_upper_hex<T: UpperHex>(x: &T) -> Argument<'_> { - Self::new(x, UpperHex::fmt) + argument_new!(T, x, <T as UpperHex>::fmt) } #[inline] pub fn new_pointer<T: Pointer>(x: &T) -> Argument<'_> { - Self::new(x, Pointer::fmt) + argument_new!(T, x, <T as Pointer>::fmt) } #[inline] pub fn new_binary<T: Binary>(x: &T) -> Argument<'_> { - Self::new(x, Binary::fmt) + argument_new!(T, x, <T as Binary>::fmt) } #[inline] pub fn new_lower_exp<T: LowerExp>(x: &T) -> Argument<'_> { - Self::new(x, LowerExp::fmt) + argument_new!(T, x, <T as LowerExp>::fmt) } #[inline] pub fn new_upper_exp<T: UpperExp>(x: &T) -> Argument<'_> { - Self::new(x, UpperExp::fmt) + argument_new!(T, x, <T as UpperExp>::fmt) } #[inline] #[track_caller] @@ -135,11 +141,6 @@ impl Argument<'_> { /// # Safety /// /// This argument must actually be a placeholder argument. - /// - // FIXME: Transmuting formatter in new and indirectly branching to/calling - // it here is an explicit CFI violation. - #[allow(inline_no_sanitize)] - #[no_sanitize(cfi, kcfi)] #[inline] pub(super) unsafe fn fmt(&self, f: &mut Formatter<'_>) -> Result { match self.ty { |
