Skip to content

Commit e7288d2

Browse files
authored
Rollup merge of rust-lang#97420 - WaffleLapkin:no_oxford_casts_qqq, r=Mark-Simulacrum
Be a little nicer with casts when formatting `fn` pointers This removes a `fn(...) -> ...` -> `usize` -> `*const ()` -> `usize` cast. cc rust-lang#95489.
2 parents 59b802d + ac5c15d commit e7288d2

File tree

2 files changed

+32
-36
lines changed

2 files changed

+32
-36
lines changed

library/core/src/fmt/mod.rs

+30-24
Original file line numberDiff line numberDiff line change
@@ -2233,35 +2233,41 @@ impl Display for char {
22332233
#[stable(feature = "rust1", since = "1.0.0")]
22342234
impl<T: ?Sized> Pointer for *const T {
22352235
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
2236-
/// Since the formatting will be identical for all pointer types, use a non-monomorphized
2237-
/// implementation for the actual formatting to reduce the amount of codegen work needed
2238-
fn inner(ptr: *const (), f: &mut Formatter<'_>) -> Result {
2239-
let old_width = f.width;
2240-
let old_flags = f.flags;
2241-
2242-
// The alternate flag is already treated by LowerHex as being special-
2243-
// it denotes whether to prefix with 0x. We use it to work out whether
2244-
// or not to zero extend, and then unconditionally set it to get the
2245-
// prefix.
2246-
if f.alternate() {
2247-
f.flags |= 1 << (FlagV1::SignAwareZeroPad as u32);
2248-
2249-
if f.width.is_none() {
2250-
f.width = Some((usize::BITS / 4) as usize + 2);
2251-
}
2252-
}
2253-
f.flags |= 1 << (FlagV1::Alternate as u32);
2236+
// Cast is needed here because `.addr()` requires `T: Sized`.
2237+
pointer_fmt_inner((*self as *const ()).addr(), f)
2238+
}
2239+
}
22542240

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

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

2260-
ret
2259+
if f.width.is_none() {
2260+
f.width = Some((usize::BITS / 4) as usize + 2);
22612261
}
2262-
2263-
inner(*self as *const (), f)
22642262
}
2263+
f.flags |= 1 << (FlagV1::Alternate as u32);
2264+
2265+
let ret = LowerHex::fmt(&ptr_addr, f);
2266+
2267+
f.width = old_width;
2268+
f.flags = old_flags;
2269+
2270+
ret
22652271
}
22662272

22672273
#[stable(feature = "rust1", since = "1.0.0")]

library/core/src/ptr/mod.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -1878,24 +1878,14 @@ macro_rules! fnptr_impls_safety_abi {
18781878
#[stable(feature = "fnptr_impls", since = "1.4.0")]
18791879
impl<Ret, $($Arg),*> fmt::Pointer for $FnTy {
18801880
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1881-
// HACK: The intermediate cast as usize is required for AVR
1882-
// so that the address space of the source function pointer
1883-
// is preserved in the final function pointer.
1884-
//
1885-
// https://github.com/avr-rust/rust/issues/143
1886-
fmt::Pointer::fmt(&(*self as usize as *const ()), f)
1881+
fmt::pointer_fmt_inner(*self as usize, f)
18871882
}
18881883
}
18891884

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

0 commit comments

Comments
 (0)