Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Remove (fn(...) -> ...) -> usize -> *const () -> usize cast
  • Loading branch information
WaffleLapkin committed May 29, 2022
commit ac5c15d6beec450db1d8116cf76c4c6b6e3b351f
54 changes: 30 additions & 24 deletions library/core/src/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2233,35 +2233,41 @@ impl Display for char {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Pointer for *const T {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
/// Since the formatting will be identical for all pointer types, use a non-monomorphized
/// implementation for the actual formatting to reduce the amount of codegen work needed
fn inner(ptr: *const (), f: &mut Formatter<'_>) -> Result {
let old_width = f.width;
let old_flags = f.flags;

// The alternate flag is already treated by LowerHex as being special-
// it denotes whether to prefix with 0x. We use it to work out whether
// or not to zero extend, and then unconditionally set it to get the
// prefix.
if f.alternate() {
f.flags |= 1 << (FlagV1::SignAwareZeroPad as u32);

if f.width.is_none() {
f.width = Some((usize::BITS / 4) as usize + 2);
}
}
f.flags |= 1 << (FlagV1::Alternate as u32);
// Cast is needed here because `.addr()` requires `T: Sized`.
pointer_fmt_inner((*self as *const ()).addr(), f)
}
}

let ret = LowerHex::fmt(&(ptr.addr()), f);
/// Since the formatting will be identical for all pointer types, use a non-monomorphized
/// implementation for the actual formatting to reduce the amount of codegen work needed.
///
/// This uses `ptr_addr: usize` and not `ptr: *const ()` to be able to use this for
/// `fn(...) -> ...` without using [problematic] "Oxford Casts".
///
/// [problematic]: https://github.com/rust-lang/rust/issues/95489
pub(crate) fn pointer_fmt_inner(ptr_addr: usize, f: &mut Formatter<'_>) -> Result {
let old_width = f.width;
let old_flags = f.flags;

f.width = old_width;
f.flags = old_flags;
// The alternate flag is already treated by LowerHex as being special-
// it denotes whether to prefix with 0x. We use it to work out whether
// or not to zero extend, and then unconditionally set it to get the
// prefix.
if f.alternate() {
f.flags |= 1 << (FlagV1::SignAwareZeroPad as u32);

ret
if f.width.is_none() {
f.width = Some((usize::BITS / 4) as usize + 2);
}

inner(*self as *const (), f)
}
f.flags |= 1 << (FlagV1::Alternate as u32);

let ret = LowerHex::fmt(&ptr_addr, f);

f.width = old_width;
f.flags = old_flags;

ret
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
14 changes: 2 additions & 12 deletions library/core/src/ptr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1831,24 +1831,14 @@ macro_rules! fnptr_impls_safety_abi {
#[stable(feature = "fnptr_impls", since = "1.4.0")]
impl<Ret, $($Arg),*> fmt::Pointer for $FnTy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// HACK: The intermediate cast as usize is required for AVR
// so that the address space of the source function pointer
// is preserved in the final function pointer.
//
// https://github.com/avr-rust/rust/issues/143
fmt::Pointer::fmt(&(*self as usize as *const ()), f)
fmt::pointer_fmt_inner(*self as usize, f)
}
}

#[stable(feature = "fnptr_impls", since = "1.4.0")]
impl<Ret, $($Arg),*> fmt::Debug for $FnTy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// HACK: The intermediate cast as usize is required for AVR
// so that the address space of the source function pointer
// is preserved in the final function pointer.
//
// https://github.com/avr-rust/rust/issues/143
fmt::Pointer::fmt(&(*self as usize as *const ()), f)
fmt::pointer_fmt_inner(*self as usize, f)
}
}
}
Expand Down