Skip to content

HRTB variants are missing a std::fmt::Pointer impl #50280

Description

@jimy-byerley

It seems that there is a missing implementation of std::fmt::Pointer on some function pointers:

function pointers like fn test() -> f32 can be passed as argument to println!("{:p}", ...)
but function pointers like fn test(Vec<T> a) -> f32 can't because it's a HRTB variant.

see https://users.rust-lang.org/t/display-function-pointer/17073 for more details.

Activity

  1. ExpHP commented on Apr 27, 2018

    @ExpHP
    Contributor

    Your link is broken. Can you please post a code snippet?

    Printing an HRTB fn pointer should be impossible, because the address depends on the type arguments. Printing test::<i8> might be possible; I'm not sure, because playing around with it in the playpen, it seems to me that even a simple fn foo() does not impl Pointer.

  2. ExpHP commented on Apr 27, 2018

    @ExpHP
    Contributor

    Found it by copying the link text.

    Your arg type was fn (&Vec<i8>)->f32, which adds an important detail (the reference in the argument, which adds an invisible HRTB lifetime parameter that should not affect the function address. This makes the issue more legitimate

  3. jimy-byerley commented on Apr 27, 2018

    @jimy-byerley
    Author

    But the address's interpretation doesn't depends on the function type, isn't it ? HRTB type makes it difficult to reach the correct implementation of methods and traits but that doesn't affect the fact that it's a pointer ?

  4. vitalyd commented on Apr 27, 2018

    @vitalyd

    There's a macro in std that is used to generate the various std::fmt::Pointer impls for fn's of different arity. Probably what's missing are the HRTB variants, e.g. impl<Ret, A> Pointer for for<'a> fn(&'a A) -> Ret and so on for the other combinations.

  5. ExpHP commented on Apr 27, 2018

    @ExpHP
    Contributor

    @vitalyd that solution has exponentially scaling complexity just to support & and &mut arguments, and that's without even support for:

    • other types besides & that have lifetime parameters
    • 'b: 'a constraints
  6. vitalyd commented on Apr 27, 2018

    @vitalyd

    @ExpHP, I agree that it’s not exhaustive. The existing impls are handcoded as well with someone making the choice of which arities and types to support.

    Perhaps the real solution would be compiler support (eg a lang item) or some auto trait or something else. It’s a bad look when these fn pointers should just work but don’t and it all depends for which impls Pointer was implemented.

    But barring a more principled solution, adding more combinations could bandaid this for now.

  7. added
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    T-langRelevant to the language team
    on Oct 2, 2018
  8. steveklabnik commented on May 8, 2020

    @steveklabnik
    Contributor

    Triage: no change. This program: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=844d632aee1147f2dc9e7d05d3ef9462

    fn show(a: fn () -> f32, b: fn (&Vec<i8>)->f32) {
        println!("the two pointers: {:p} {:p}", a, b);
    }
    

    gives this error:

    error[E0277]: the trait bound `for<'r> fn(&'r std::vec::Vec<i8>) -> f32: std::fmt::Pointer` is not satisfied
     --> src/lib.rs:2:48
      |
    2 |     println!("the two pointers: {:p} {:p}", a, b);
      |                                                ^ the trait `std::fmt::Pointer` is not implemented for `for<'r> fn(&'r std::vec::Vec<i8>) -> f32`
      |
      = help: the following implementations were found:
                <extern "C" fn(A) -> Ret as std::fmt::Pointer>
                <extern "C" fn(A, ...) -> Ret as std::fmt::Pointer>
                <fn(A) -> Ret as std::fmt::Pointer>
                <unsafe extern "C" fn(A) -> Ret as std::fmt::Pointer>
              and 2 others
      = note: required by `std::fmt::Pointer::fmt`
      = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
    
  9. fmease commented on Sep 24, 2024

    @fmease
    Member

    Triage: The code provided in the comment above now compiles just fine.

    Marking as E-needs-test, however we might already have a test for this.

  10. added
    E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.
    T-libs-api[DEPRECATED; DO NOT USE]
    T-typesRelevant to the types team, which will review and decide on the PR/issue.
    A-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)
    and removed
    T-langRelevant to the language team
    on Sep 24, 2024
  11. Enselic commented on Dec 17, 2025

    @Enselic
    Member

    This was fixed in nightly-2023-03-29

    git log ^2036fdd24f77d607dcfaa24c48fbe85d3f785823 478cbb4 --no-merges --oneline
    054009d17ee fix long line
    b17e6680d66 Move const trait bounds checks to MIR constck
    b38732f25c3 Add "Platform-specific behavior" heading and link to changes disclaimer
    e3b0a728b4a Erase impl regions when checking for impossible to eagerly monomorphize items
    1354a38afd7 Document the heuristics IsTerminal uses on Windows
    7bbc8ef0223 Make doc comment a little bit more accurate
    901f10899c3 Add `#[inline]` to CStr trait implementations
    f738b44c6d0 no shadow plz
    904dd2c3987 Bless tidy
    8af42f695d4 Remove useless Clone bounds
    436afdf1fea Don't skip all directories when tidy-checking
    3c4fabc341c Improve documentation for E0223
    7cba12c5a9f Update books
    9fc7eca935a Always set `RUSTC_BOOTSTRAP` with `x doc`
    ed5c0f66ac1 socket ancillary data implementation for FreeBSD (from 13 and above).
    73c34cbaf71 Add notes to non-structural const in pattern error message
    41807938d2f fix advance_by impl for vec_deque and add tests
    9cd9da2cd1c update documentation
    e29b27b4a4c replace advance_by returning usize with Result<(), NonZeroUsize>
    5ae6caa0f04 Use the FnPtr trait to avoid implementing common traits via macros
    9e27c6c133b Some tracing/instrument cleanups
    0c13565ca66 Add a builtin `FnPtr` trait
    69db91b8b25 Change advance(_back)_by to return `usize` instead of `Result<(), usize>`
    64927b973b6 Fix LVI test post LLVM 16 update
    2a3177a8bcc tolerate region vars in implied bounds
    b20aa97d480 exhaustive match on implied bounds regions
    9cfb5f73ba3 add test
    d1743c98170 resolve regions before implied bounds
    b197f1ac2e4 remove obsolete `givens` from regionck
    27c44d2e28d Update indexmap and rayon crates
    4d5501037a3 Allow long link names in tar files
    a1f48047bf9 Use Rayon's TLV directly
    8b1be44758f Update ar_archive_writer to 0.1.3
    d13b423859b use llvm 16.0.0 instead of 16.0.0-rc4
    5456eecab0e Clean up substs building
    08284449a24 Subst gat normalize pred correctly
    73c79cd8063 stop special-casing `'static` in evaluate
    

    Most likely #108080, which didn't add a test for this case, and I couldn't find any other test either.

    So I added a test in #150082.

    @rustbot claim

  12. added a commit that references this issue on Dec 21, 2025
  13. added a commit that references this issue on Dec 21, 2025
  14. added a commit that references this issue on Dec 21, 2025
  15. added a commit that references this issue on Dec 21, 2025
  16. added a commit that references this issue on Dec 21, 2025
  17. added a commit that references this issue on Dec 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)A-trait-systemArea: Trait systemC-enhancementCategory: An issue proposing an enhancement or a PR with one.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.T-libs-api[DEPRECATED; DO NOT USE]T-typesRelevant to the types team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions