diff options
| author | Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> | 2022-06-02 15:26:57 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-06-02 15:26:57 +0200 |
| commit | 0b2d48e5af11ca20878ccb463fceba2c180a6a4a (patch) | |
| tree | 2e9d036e397cf106d5dd888b09044a0f50304ae1 | |
| parent | 9598b4b594c97dff66feb93522e22db500deea07 (diff) | |
| parent | ac5c15d6beec450db1d8116cf76c4c6b6e3b351f (diff) | |
| download | rust-0b2d48e5af11ca20878ccb463fceba2c180a6a4a.tar.gz rust-0b2d48e5af11ca20878ccb463fceba2c180a6a4a.zip | |
Rollup merge of #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 #95489.
| -rw-r--r-- | library/core/src/fmt/mod.rs | 54 | ||||
| -rw-r--r-- | library/core/src/ptr/mod.rs | 14 |
2 files changed, 32 insertions, 36 deletions
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index dde9bc383d2..63655ae8a24 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -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")] diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 6b1e63e0cfa..5b04ae7b07e 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1878,24 +1878,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) } } } |
