Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion library/core/src/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))]
Expand Down
45 changes: 23 additions & 22 deletions library/core/src/fmt/rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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 {
Expand Down
18 changes: 8 additions & 10 deletions tests/coverage/closure.cov-map
Original file line number Diff line number Diff line change
Expand Up @@ -140,19 +140,17 @@ Number of file 0 mappings: 6
- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
Highest counter ID seen: c1

Function name: closure::main::{closure#18}
Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 19, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 01, 0e]
Function name: closure::main::{closure#18} (unused)
Raw bytes (24): 0x[01, 01, 00, 04, 00, 19, 0d, 02, 1c, 00, 02, 1d, 02, 12, 00, 02, 11, 00, 12, 00, 01, 11, 01, 0e]
Number of files: 1
- file 0 => global file 1
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
Number of expressions: 0
Number of file 0 mappings: 4
- Code(Counter(0)) at (prev + 25, 13) to (start + 2, 28)
- Code(Counter(1)) at (prev + 2, 29) to (start + 2, 18)
- Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 18)
= (c0 - c1)
- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 14)
Highest counter ID seen: c1
- Code(Zero) at (prev + 25, 13) to (start + 2, 28)
- Code(Zero) at (prev + 2, 29) to (start + 2, 18)
- Code(Zero) at (prev + 2, 17) to (start + 0, 18)
- Code(Zero) at (prev + 1, 17) to (start + 1, 14)
Highest counter ID seen: (none)

Function name: closure::main::{closure#19}
Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 43, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 01, 0e]
Expand Down
Loading